diff --git a/pkg/yqlib/doc/usage/formatting-expressions.md b/pkg/yqlib/doc/usage/formatting-expressions.md new file mode 100644 index 00000000000..59503dd19c4 --- /dev/null +++ b/pkg/yqlib/doc/usage/formatting-expressions.md @@ -0,0 +1,33 @@ +# Formatting Expressions + +`From version v4.41+` + +You can put expressions into `.yq` files, use whitespace and comments to break up complex expressions and explain what's going on. + +## Using expression files and comments +Given a sample.yaml file of: +```yaml +a: + b: old +``` +And an 'update.yq' expression file of: +```bash +# This is a yq expression that updates the map +# for several great reasons outlined here. + +.a.b = "new" # line comment here +| .a.c = "frog" + +# Now good things will happen. +``` +then +```bash +yq --from-file update.yq sample.yml +``` +will output +```yaml +a: + b: new + c: frog +``` + diff --git a/pkg/yqlib/doc/usage/headers/formatting-expressions.md b/pkg/yqlib/doc/usage/headers/formatting-expressions.md new file mode 100644 index 00000000000..60a018ef07e --- /dev/null +++ b/pkg/yqlib/doc/usage/headers/formatting-expressions.md @@ -0,0 +1,5 @@ +# Formatting Expressions + +`From version v4.41+` + +You can put expressions into `.yq` files, use whitespace and comments to break up complex expressions and explain what's going on. diff --git a/pkg/yqlib/doc/usage/xml.md b/pkg/yqlib/doc/usage/xml.md index 503f9a7475e..4238e971411 100644 --- a/pkg/yqlib/doc/usage/xml.md +++ b/pkg/yqlib/doc/usage/xml.md @@ -370,7 +370,7 @@ cat: purrs ``` then ```bash -yq -o=xml '.' sample.yml +yq -o=xml sample.yml ``` will output ```xml @@ -387,7 +387,7 @@ pets: ``` then ```bash -yq -o=xml '.' sample.yml +yq -o=xml sample.yml ``` will output ```xml @@ -409,7 +409,7 @@ cat: ``` then ```bash -yq -o=xml '.' sample.yml +yq -o=xml sample.yml ``` will output ```xml @@ -430,7 +430,7 @@ cat: ``` then ```bash -yq -o=xml '.' sample.yml +yq -o=xml sample.yml ``` will output ```xml @@ -457,7 +457,7 @@ cat: # inline_cat ``` then ```bash -yq -o=xml '.' sample.yml +yq -o=xml sample.yml ``` will output ```xml @@ -487,7 +487,7 @@ apple: ``` then ```bash -yq -o=xml '.' sample.yml +yq -o=xml sample.yml ``` will output ```xml diff --git a/pkg/yqlib/formatting_expressions_test.go b/pkg/yqlib/formatting_expressions_test.go new file mode 100644 index 00000000000..65ed3e10ad0 --- /dev/null +++ b/pkg/yqlib/formatting_expressions_test.go @@ -0,0 +1,57 @@ +package yqlib + +import ( + "bufio" + "fmt" + "testing" + + "github.com/mikefarah/yq/v4/test" +) + +var formattingExpressionScenarios = []formatScenario{ + { + description: "Using expression files and comments", + input: "a:\n b: old", + expression: "\n# This is a yq expression that updates the map\n# for several great reasons outlined here.\n\n.a.b = \"new\" # line comment here\n| .a.c = \"frog\"\n\n# Now good things will happen.\n", + expected: "a:\n b: new\n c: frog\n", + }, +} + +func documentExpressionScenario(_ *testing.T, w *bufio.Writer, i interface{}) { + s := i.(formatScenario) + + if s.skipDoc { + return + } + writeOrPanic(w, fmt.Sprintf("## %v\n", s.description)) + + if s.subdescription != "" { + writeOrPanic(w, s.subdescription) + writeOrPanic(w, "\n\n") + } + + writeOrPanic(w, "Given a sample.yaml file of:\n") + writeOrPanic(w, fmt.Sprintf("```yaml\n%v\n```\n", s.input)) + + writeOrPanic(w, "And an 'update.yq' expression file of:\n") + writeOrPanic(w, fmt.Sprintf("```bash%v```\n", s.expression)) + + writeOrPanic(w, "then\n") + writeOrPanic(w, "```bash\nyq --from-file update.yq sample.yml\n```\n") + writeOrPanic(w, "will output\n") + + writeOrPanic(w, fmt.Sprintf("```yaml\n%v```\n\n", mustProcessFormatScenario(s, NewYamlDecoder(ConfiguredYamlPreferences), NewYamlEncoder(2, false, ConfiguredYamlPreferences)))) +} + +func TestExpressionCommentScenarios(t *testing.T) { + for _, tt := range formattingExpressionScenarios { + test.AssertResultComplexWithContext(t, tt.expected, + mustProcessFormatScenario(tt, NewYamlDecoder(ConfiguredYamlPreferences), NewYamlEncoder(2, false, ConfiguredYamlPreferences)), + tt.description) + } + genericScenarios := make([]interface{}, len(formattingExpressionScenarios)) + for i, s := range formattingExpressionScenarios { + genericScenarios[i] = s + } + documentScenarios(t, "usage", "formatting-expressions", genericScenarios, documentExpressionScenario) +} diff --git a/pkg/yqlib/lexer_participle.go b/pkg/yqlib/lexer_participle.go index 391c8f04d11..1b365d88d3b 100644 --- a/pkg/yqlib/lexer_participle.go +++ b/pkg/yqlib/lexer_participle.go @@ -221,6 +221,7 @@ var participleYqRules = []*participleYqRule{ {"SubtractAssign", `\-=`, opToken(subtractAssignOpType), 0}, {"Subtract", `\-`, opToken(subtractOpType), 0}, + {"Comment", `#.*`, nil, 0}, } type yqAction func(lexer.Token) (*token, error) diff --git a/pkg/yqlib/xml_test.go b/pkg/yqlib/xml_test.go index 20a7551401c..c3eca8d199f 100644 --- a/pkg/yqlib/xml_test.go +++ b/pkg/yqlib/xml_test.go @@ -768,7 +768,7 @@ func documentXMLEncodeScenario(w *bufio.Writer, s formatScenario) { writeOrPanic(w, fmt.Sprintf("```yaml\n%v\n```\n", s.input)) writeOrPanic(w, "then\n") - writeOrPanic(w, "```bash\nyq -o=xml '.' sample.yml\n```\n") + writeOrPanic(w, "```bash\nyq -o=xml sample.yml\n```\n") writeOrPanic(w, "will output\n") writeOrPanic(w, fmt.Sprintf("```xml\n%v```\n\n", mustProcessFormatScenario(s, NewYamlDecoder(ConfiguredYamlPreferences), NewXMLEncoder(2, ConfiguredXMLPreferences))))