From 9a8151d316885a08faef32dd6bc52000edd2a136 Mon Sep 17 00:00:00 2001 From: Mike Farah Date: Sat, 17 Feb 2024 19:10:13 +1100 Subject: [PATCH] Added csv separator flag #1950 --- acceptance_tests/inputs-format.sh | 21 ++++++++++++++++++ acceptance_tests/output-format.sh | 21 ++++++++++++++++++ cmd/root.go | 31 +++++++++++++++++++++++++++ cmd/utils.go | 4 ++-- pkg/yqlib/csv_test.go | 16 ++++++++------ pkg/yqlib/encoder_csv.go | 4 ++-- pkg/yqlib/operator_encoder_decoder.go | 4 ++-- 7 files changed, 89 insertions(+), 12 deletions(-) diff --git a/acceptance_tests/inputs-format.sh b/acceptance_tests/inputs-format.sh index e7a7563e..60d0bd11 100755 --- a/acceptance_tests/inputs-format.sh +++ b/acceptance_tests/inputs-format.sh @@ -63,6 +63,27 @@ EOM assertEquals "$expected" "$X" } +testInputCSVCustomSeparator() { + cat >test.csv <test.csv <test.yml <test.yml <)") rootCmd.PersistentFlags().BoolVar(&yqlib.ConfiguredCsvPreferences.AutoParse, "csv-auto-parse", yqlib.ConfiguredCsvPreferences.AutoParse, "parse CSV YAML/JSON values") + rootCmd.PersistentFlags().Var(newRuneVar(&yqlib.ConfiguredCsvPreferences.Separator), "csv-separator", "CSV Separator character") + rootCmd.PersistentFlags().BoolVar(&yqlib.ConfiguredTsvPreferences.AutoParse, "tsv-auto-parse", yqlib.ConfiguredTsvPreferences.AutoParse, "parse TSV YAML/JSON values") rootCmd.PersistentFlags().StringVar(&yqlib.ConfiguredLuaPreferences.DocPrefix, "lua-prefix", yqlib.ConfiguredLuaPreferences.DocPrefix, "prefix") diff --git a/cmd/utils.go b/cmd/utils.go index b266016d..91f95f81 100644 --- a/cmd/utils.go +++ b/cmd/utils.go @@ -189,9 +189,9 @@ func createEncoder(format yqlib.PrinterOutputFormat) (yqlib.Encoder, error) { case yqlib.PropsOutputFormat: return yqlib.NewPropertiesEncoder(unwrapScalar), nil case yqlib.CSVOutputFormat: - return yqlib.NewCsvEncoder(','), nil + return yqlib.NewCsvEncoder(yqlib.ConfiguredCsvPreferences), nil case yqlib.TSVOutputFormat: - return yqlib.NewCsvEncoder('\t'), nil + return yqlib.NewCsvEncoder(yqlib.ConfiguredTsvPreferences), nil case yqlib.YamlOutputFormat: return yqlib.NewYamlEncoder(indent, colorsEnabled, yqlib.ConfiguredYamlPreferences), nil case yqlib.XMLOutputFormat: diff --git a/pkg/yqlib/csv_test.go b/pkg/yqlib/csv_test.go index b5872763..c88cc35d 100644 --- a/pkg/yqlib/csv_test.go +++ b/pkg/yqlib/csv_test.go @@ -206,9 +206,9 @@ var csvScenarios = []formatScenario{ func testCSVScenario(t *testing.T, s formatScenario) { switch s.scenarioType { case "encode-csv": - test.AssertResultWithContext(t, s.expected, mustProcessFormatScenario(s, NewYamlDecoder(ConfiguredYamlPreferences), NewCsvEncoder(',')), s.description) + test.AssertResultWithContext(t, s.expected, mustProcessFormatScenario(s, NewYamlDecoder(ConfiguredYamlPreferences), NewCsvEncoder(ConfiguredCsvPreferences)), s.description) case "encode-tsv": - test.AssertResultWithContext(t, s.expected, mustProcessFormatScenario(s, NewYamlDecoder(ConfiguredYamlPreferences), NewCsvEncoder('\t')), s.description) + test.AssertResultWithContext(t, s.expected, mustProcessFormatScenario(s, NewYamlDecoder(ConfiguredYamlPreferences), NewCsvEncoder(ConfiguredTsvPreferences)), s.description) case "decode-csv": test.AssertResultWithContext(t, s.expected, mustProcessFormatScenario(s, NewCSVObjectDecoder(ConfiguredCsvPreferences), NewYamlEncoder(2, false, ConfiguredYamlPreferences)), s.description) case "decode-csv-no-auto": @@ -216,7 +216,7 @@ func testCSVScenario(t *testing.T, s formatScenario) { case "decode-tsv-object": test.AssertResultWithContext(t, s.expected, mustProcessFormatScenario(s, NewCSVObjectDecoder(ConfiguredTsvPreferences), NewYamlEncoder(2, false, ConfiguredYamlPreferences)), s.description) case "roundtrip-csv": - test.AssertResultWithContext(t, s.expected, mustProcessFormatScenario(s, NewCSVObjectDecoder(ConfiguredCsvPreferences), NewCsvEncoder(',')), s.description) + test.AssertResultWithContext(t, s.expected, mustProcessFormatScenario(s, NewCSVObjectDecoder(ConfiguredCsvPreferences), NewCsvEncoder(ConfiguredCsvPreferences)), s.description) default: panic(fmt.Sprintf("unhandled scenario type %q", s.scenarioType)) } @@ -298,9 +298,10 @@ func documentCSVEncodeScenario(w *bufio.Writer, s formatScenario, formatType str if formatType == "tsv" { separator = '\t' } - + csvPrefs := NewDefaultCsvPreferences() + csvPrefs.Separator = separator writeOrPanic(w, fmt.Sprintf("```%v\n%v```\n\n", formatType, - mustProcessFormatScenario(s, NewYamlDecoder(ConfiguredYamlPreferences), NewCsvEncoder(separator))), + mustProcessFormatScenario(s, NewYamlDecoder(ConfiguredYamlPreferences), NewCsvEncoder(csvPrefs))), ) } @@ -331,8 +332,11 @@ func documentCSVRoundTripScenario(w *bufio.Writer, s formatScenario, formatType separator = '\t' } + csvPrefs := NewDefaultCsvPreferences() + csvPrefs.Separator = separator + writeOrPanic(w, fmt.Sprintf("```%v\n%v```\n\n", formatType, - mustProcessFormatScenario(s, NewCSVObjectDecoder(CsvPreferences{Separator: separator, AutoParse: true}), NewCsvEncoder(separator))), + mustProcessFormatScenario(s, NewCSVObjectDecoder(CsvPreferences{Separator: separator, AutoParse: true}), NewCsvEncoder(csvPrefs))), ) } diff --git a/pkg/yqlib/encoder_csv.go b/pkg/yqlib/encoder_csv.go index aaea60c6..1fa4354c 100644 --- a/pkg/yqlib/encoder_csv.go +++ b/pkg/yqlib/encoder_csv.go @@ -10,8 +10,8 @@ type csvEncoder struct { separator rune } -func NewCsvEncoder(separator rune) Encoder { - return &csvEncoder{separator: separator} +func NewCsvEncoder(prefs CsvPreferences) Encoder { + return &csvEncoder{separator: prefs.Separator} } func (e *csvEncoder) CanHandleAliases() bool { diff --git a/pkg/yqlib/operator_encoder_decoder.go b/pkg/yqlib/operator_encoder_decoder.go index 84037146..f59c8702 100644 --- a/pkg/yqlib/operator_encoder_decoder.go +++ b/pkg/yqlib/operator_encoder_decoder.go @@ -16,9 +16,9 @@ func configureEncoder(format PrinterOutputFormat, indent int) Encoder { case PropsOutputFormat: return NewPropertiesEncoder(true) case CSVOutputFormat: - return NewCsvEncoder(',') + return NewCsvEncoder(ConfiguredCsvPreferences) case TSVOutputFormat: - return NewCsvEncoder('\t') + return NewCsvEncoder(ConfiguredTsvPreferences) case YamlOutputFormat: return NewYamlEncoder(indent, false, ConfiguredYamlPreferences) case XMLOutputFormat: