From b24b484efc5ea8d6d5e5422eb5ce2af39e7b071e Mon Sep 17 00:00:00 2001 From: Mike Farah Date: Tue, 20 Feb 2024 11:39:56 +1100 Subject: [PATCH] Added --properties-array-brackets flag for properties encoder #1933 --- cmd/root.go | 1 + examples/data1.yaml | 13 ++++- pkg/yqlib/doc/usage/properties.md | 80 +++++++++++++++++++------------ pkg/yqlib/encoder_properties.go | 7 +++ pkg/yqlib/properties.go | 2 + pkg/yqlib/properties_test.go | 44 +++++++++++++++-- release_notes.txt | 5 +- 7 files changed, 115 insertions(+), 37 deletions(-) diff --git a/cmd/root.go b/cmd/root.go index 3a6d0b03..46a00e4a 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -121,6 +121,7 @@ yq -P -oy sample.json rootCmd.PersistentFlags().BoolVar(&yqlib.ConfiguredLuaPreferences.Globals, "lua-globals", yqlib.ConfiguredLuaPreferences.Globals, "output keys as top-level global variables") rootCmd.PersistentFlags().StringVar(&yqlib.ConfiguredPropertiesPreferences.KeyValueSeparator, "properties-separator", yqlib.ConfiguredPropertiesPreferences.KeyValueSeparator, "separator to use between keys and values") + rootCmd.PersistentFlags().BoolVar(&yqlib.ConfiguredPropertiesPreferences.UseArrayBrackets, "properties-array-brackets", yqlib.ConfiguredPropertiesPreferences.UseArrayBrackets, "use [x] in array paths (e.g. for SpringBoot)") rootCmd.PersistentFlags().BoolVarP(&nullInput, "null-input", "n", false, "Don't read input, simply evaluate the expression given. Useful for creating docs from scratch.") rootCmd.PersistentFlags().BoolVarP(&noDocSeparators, "no-doc", "N", false, "Don't print document separators (---)") diff --git a/examples/data1.yaml b/examples/data1.yaml index a15395fa..5be86e05 100644 --- a/examples/data1.yaml +++ b/examples/data1.yaml @@ -1,2 +1,11 @@ -a: #things - meow \ No newline at end of file +# block comments come through +person: # neither do comments on maps + name: Mike Wazowski # comments on values appear + pets: + - cat # comments on array values appear + - dog # comments on array values appear + - things: + - frog + food: [pizza] # comments on arrays do not +emptyArray: [] +emptyMap: [] \ No newline at end of file diff --git a/pkg/yqlib/doc/usage/properties.md b/pkg/yqlib/doc/usage/properties.md index 70758dad..6f3835dd 100644 --- a/pkg/yqlib/doc/usage/properties.md +++ b/pkg/yqlib/doc/usage/properties.md @@ -14,6 +14,8 @@ person: # neither do comments on maps name: Mike Wazowski # comments on values appear pets: - cat # comments on array values appear + - nested: + - list entry food: [pizza] # comments on arrays do not emptyArray: [] emptyMap: [] @@ -31,9 +33,43 @@ person.name = Mike Wazowski # comments on array values appear person.pets.0 = cat +person.pets.1.nested.0 = list entry person.food.0 = pizza ``` +## Encode properties with array brackets +Note that empty arrays and maps are not encoded by default. + +Given a sample.yml file of: +```yaml +# block comments come through +person: # neither do comments on maps + name: Mike Wazowski # comments on values appear + pets: + - cat # comments on array values appear + - nested: + - list entry + food: [pizza] # comments on arrays do not +emptyArray: [] +emptyMap: [] + +``` +then +```bash +yq -o=props --properties-array-brackets sample.yml +``` +will output +```properties +# block comments come through +# comments on values appear +person.name = Mike Wazowski + +# comments on array values appear +person.pets[0] = cat +person.pets[1].nested[0] = list entry +person.food[0] = pizza +``` + ## Encode properties: scalar encapsulation Note that string values with blank characters in them are encapsulated with double quotes @@ -44,6 +80,8 @@ person: # neither do comments on maps name: Mike Wazowski # comments on values appear pets: - cat # comments on array values appear + - nested: + - list entry food: [pizza] # comments on arrays do not emptyArray: [] emptyMap: [] @@ -61,6 +99,7 @@ person.name = "Mike Wazowski" # comments on array values appear person.pets.0 = cat +person.pets.1.nested.0 = "list entry" person.food.0 = pizza ``` @@ -72,6 +111,8 @@ person: # neither do comments on maps name: Mike Wazowski # comments on values appear pets: - cat # comments on array values appear + - nested: + - list entry food: [pizza] # comments on arrays do not emptyArray: [] emptyMap: [] @@ -85,6 +126,7 @@ will output ```properties person.name = Mike Wazowski person.pets.0 = cat +person.pets.1.nested.0 = list entry person.food.0 = pizza ``` @@ -98,6 +140,8 @@ person: # neither do comments on maps name: Mike Wazowski # comments on values appear pets: - cat # comments on array values appear + - nested: + - list entry food: [pizza] # comments on arrays do not emptyArray: [] emptyMap: [] @@ -115,41 +159,12 @@ person.name = Mike Wazowski # comments on array values appear person.pets.0 = cat +person.pets.1.nested.0 = list entry person.food.0 = pizza emptyArray = emptyMap = ``` -## Encode properties: use custom separator -Provide a custom key-value separator using the `--properties-separator` flag. - -Given a sample.yml file of: -```yaml -# block comments come through -person: # neither do comments on maps - name: Mike Wazowski # comments on values appear - pets: - - cat # comments on array values appear - food: [pizza] # comments on arrays do not -emptyArray: [] -emptyMap: [] - -``` -then -```bash -yq -o props --properties-separator=";" sample.yml -``` -will output -```properties -# block comments come through -# comments on values appear -person.name;Mike Wazowski - -# comments on array values appear -person.pets.0;cat -person.food.0;pizza -``` - ## Decode properties Given a sample.properties file of: ```properties @@ -159,6 +174,7 @@ person.name = Mike Wazowski # comments on array values appear person.pets.0 = cat +person.pets.1.nested.0 = list entry person.food.0 = pizza ``` @@ -175,6 +191,8 @@ person: pets: # comments on array values appear - cat + - nested: + - list entry food: - pizza ``` @@ -205,6 +223,7 @@ person.name = Mike Wazowski # comments on array values appear person.pets.0 = cat +person.pets.1.nested.0 = list entry person.food.0 = pizza ``` @@ -220,6 +239,7 @@ person.name = Mike Wazowski # comments on array values appear person.pets.0 = dog +person.pets.1.nested.0 = list entry person.food.0 = pizza ``` diff --git a/pkg/yqlib/encoder_properties.go b/pkg/yqlib/encoder_properties.go index 49d0e007..57a73307 100644 --- a/pkg/yqlib/encoder_properties.go +++ b/pkg/yqlib/encoder_properties.go @@ -117,6 +117,13 @@ func (pe *propertiesEncoder) appendPath(path string, key interface{}) string { if path == "" { return fmt.Sprintf("%v", key) } + switch key.(type) { + case int: + if pe.prefs.UseArrayBrackets { + return fmt.Sprintf("%v[%v]", path, key) + } + + } return fmt.Sprintf("%v.%v", path, key) } diff --git a/pkg/yqlib/properties.go b/pkg/yqlib/properties.go index b1920b12..45b7c3d8 100644 --- a/pkg/yqlib/properties.go +++ b/pkg/yqlib/properties.go @@ -2,11 +2,13 @@ package yqlib type PropertiesPreferences struct { KeyValueSeparator string + UseArrayBrackets bool } func NewDefaultPropertiesPreferences() PropertiesPreferences { return PropertiesPreferences{ KeyValueSeparator: " = ", + UseArrayBrackets: false, } } diff --git a/pkg/yqlib/properties_test.go b/pkg/yqlib/properties_test.go index 15d69dfe..892b93be 100644 --- a/pkg/yqlib/properties_test.go +++ b/pkg/yqlib/properties_test.go @@ -55,6 +55,8 @@ person: # neither do comments on maps name: Mike Wazowski # comments on values appear pets: - cat # comments on array values appear + - nested: + - list entry food: [pizza] # comments on arrays do not emptyArray: [] emptyMap: [] @@ -66,15 +68,27 @@ person.name = Mike Wazowski # comments on array values appear person.pets.0 = cat +person.pets.1.nested.0 = list entry person.food.0 = pizza ` +const expectedPropertiesUnwrappedArrayBrackets = `# block comments come through +# comments on values appear +person.name = Mike Wazowski + +# comments on array values appear +person.pets[0] = cat +person.pets[1].nested[0] = list entry +person.food[0] = pizza +` + const expectedPropertiesWrapped = `# block comments come through # comments on values appear person.name = "Mike Wazowski" # comments on array values appear person.pets.0 = cat +person.pets.1.nested.0 = "list entry" person.food.0 = pizza ` @@ -84,6 +98,7 @@ person.name = Mike Wazowski # comments on array values appear person.pets.0 = dog +person.pets.1.nested.0 = list entry person.food.0 = pizza ` @@ -94,6 +109,8 @@ const expectedDecodedYaml = `person: pets: # comments on array values appear - cat + - nested: + - list entry food: - pizza ` @@ -104,12 +121,15 @@ name: Mike Wazowski pets: # comments on array values appear - cat + - nested: + - list entry food: - pizza ` const expectedPropertiesNoComments = `person.name = Mike Wazowski person.pets.0 = cat +person.pets.1.nested.0 = list entry person.food.0 = pizza ` @@ -119,6 +139,7 @@ person.name = Mike Wazowski # comments on array values appear person.pets.0 = cat +person.pets.1.nested.0 = list entry person.food.0 = pizza emptyArray = emptyMap = @@ -131,6 +152,13 @@ var propertyScenarios = []formatScenario{ input: samplePropertiesYaml, expected: expectedPropertiesUnwrapped, }, + { + description: "Encode properties with array brackets", + subdescription: "Note that empty arrays and maps are not encoded by default.", + input: samplePropertiesYaml, + expected: expectedPropertiesUnwrappedArrayBrackets, + scenarioType: "encode-array-brackets", + }, { description: "Encode properties: scalar encapsulation", subdescription: "Note that string values with blank characters in them are encapsulated with double quotes", @@ -264,15 +292,21 @@ func documentUnwrappedEncodePropertyScenario(w *bufio.Writer, s formatScenario) writeOrPanic(w, "then\n") expression := s.expression + prefs := NewDefaultPropertiesPreferences() + useArrayBracketsFlag := "" + if s.scenarioType == "encode-array-brackets" { + useArrayBracketsFlag = " --properties-array-brackets" + prefs.UseArrayBrackets = true + } if expression != "" { - writeOrPanic(w, fmt.Sprintf("```bash\nyq -o=props '%v' sample.yml\n```\n", expression)) + writeOrPanic(w, fmt.Sprintf("```bash\nyq -o=props%v '%v' sample.yml\n```\n", useArrayBracketsFlag, expression)) } else { - writeOrPanic(w, "```bash\nyq -o=props sample.yml\n```\n") + writeOrPanic(w, fmt.Sprintf("```bash\nyq -o=props%v sample.yml\n```\n", useArrayBracketsFlag)) } writeOrPanic(w, "will output\n") - writeOrPanic(w, fmt.Sprintf("```properties\n%v```\n\n", mustProcessFormatScenario(s, NewYamlDecoder(ConfiguredYamlPreferences), NewPropertiesEncoder(true, ConfiguredPropertiesPreferences)))) + writeOrPanic(w, fmt.Sprintf("```properties\n%v```\n\n", mustProcessFormatScenario(s, NewYamlDecoder(ConfiguredYamlPreferences), NewPropertiesEncoder(true, prefs)))) } func documentWrappedEncodePropertyScenario(w *bufio.Writer, s formatScenario) { @@ -356,7 +390,7 @@ func documentPropertyScenario(_ *testing.T, w *bufio.Writer, i interface{}) { return } switch s.scenarioType { - case "": + case "", "encode-array-brackets": documentUnwrappedEncodePropertyScenario(w, s) case "decode": documentDecodePropertyScenario(w, s) @@ -379,6 +413,8 @@ func TestPropertyScenarios(t *testing.T) { test.AssertResultWithContext(t, s.expected, mustProcessFormatScenario(s, NewPropertiesDecoder(), NewYamlEncoder(2, false, ConfiguredYamlPreferences)), s.description) case "encode-wrapped": test.AssertResultWithContext(t, s.expected, mustProcessFormatScenario(s, NewYamlDecoder(ConfiguredYamlPreferences), NewPropertiesEncoder(false, ConfiguredPropertiesPreferences)), s.description) + case "encode-array-brackets": + test.AssertResultWithContext(t, s.expected, mustProcessFormatScenario(s, NewYamlDecoder(ConfiguredYamlPreferences), NewPropertiesEncoder(true, PropertiesPreferences{KeyValueSeparator: " = ", UseArrayBrackets: true})), s.description) case "roundtrip": test.AssertResultWithContext(t, s.expected, mustProcessFormatScenario(s, NewPropertiesDecoder(), NewPropertiesEncoder(true, ConfiguredPropertiesPreferences)), s.description) diff --git a/release_notes.txt b/release_notes.txt index 0982e35a..4c5e0843 100644 --- a/release_notes.txt +++ b/release_notes.txt @@ -1,5 +1,8 @@ 4.42.1 (not released): - - Can execute yq expression files directly with shebang (#1851) + - Can execute yq expression files directly with shebang #1851 + - Added --csv-separator flag #1950 + - Added --properties-separator option - thanks @learnitall #1864 + 4.41.1: - Can now comment in yq expressions! #1919