From cbd03f8a9319ea5b26b00136d13bfab6eba065a3 Mon Sep 17 00:00:00 2001 From: Mike Farah Date: Wed, 13 Dec 2023 10:41:56 +1100 Subject: [PATCH] Added new recipe --- pkg/yqlib/doc/usage/recipes.md | 34 +++++++++++++++++++++++++++++++++- pkg/yqlib/recipes_test.go | 24 +++++++++++++++++++++++- 2 files changed, 56 insertions(+), 2 deletions(-) diff --git a/pkg/yqlib/doc/usage/recipes.md b/pkg/yqlib/doc/usage/recipes.md index 2a0cc17e..de26c1e1 100644 --- a/pkg/yqlib/doc/usage/recipes.md +++ b/pkg/yqlib/doc/usage/recipes.md @@ -117,7 +117,7 @@ myArray: - So, we use `|=` to update `.myArray`. This is the same as doing `.myArray = (.myArray | sort_by(.numBuckets))` ## Filter, flatten, sort and unique -Lets +Lets find the unique set of names from the document. Given a sample.yml file of: ```yaml @@ -153,3 +153,35 @@ will output - Next we pipe `|` that through `sort` and then `unique` to get a sorted, unique list of the names! - See the [flatten](https://mikefarah.gitbook.io/yq/operators/flatten), [sort](https://mikefarah.gitbook.io/yq/operators/sort) and [unique](https://mikefarah.gitbook.io/yq/operators/unique) for more information and examples. +## Export as environment variables (script), or any custom format +Given a yaml document, lets output a script that will configure environment variables with that data. This same approach can be used for exporting into custom formats. + +Given a sample.yml file of: +```yaml +var0: string0 +var1: string1 +ary0: + - aryval0 + - aryval1 + - aryval2 +``` +then +```bash +yq '.[] |( + ( select(kind == "scalar") | key + "='" + . + "'"), + ( select(kind == "seq") | key + "=(" + (map("'" + . + "'") | join(",")) + ")") +)' sample.yml +``` +will output +```yaml +var0='string0' +var1='string1' +ary0=('aryval0','aryval1','aryval2') +``` + +### Explanation: +- `.[]` matches all top level elements +- We need a string expression for each of the different types that will product the bash syntax, we'll use the union operator , to join them together +- Scalars, we just need the key and quoted value: `( select(kind == "scalar") | key + "='" + . + "'")` +- Sequences (or arrays) are trickier, we need to quote each value and `join` them with `,`: `map("'" + . + "'") | join(",")` + diff --git a/pkg/yqlib/recipes_test.go b/pkg/yqlib/recipes_test.go index 2040eecf..6b460832 100644 --- a/pkg/yqlib/recipes_test.go +++ b/pkg/yqlib/recipes_test.go @@ -4,6 +4,11 @@ import ( "testing" ) +var bashEnvScript = `.[] |( + ( select(kind == "scalar") | key + "='" + . + "'"), + ( select(kind == "seq") | key + "=(" + (map("'" + . + "'") | join(",")) + ")") +)` + var recipes = []expressionScenario{ { description: "Find items in an array", @@ -66,7 +71,7 @@ var recipes = []expressionScenario{ }, { description: "Filter, flatten, sort and unique", - subdescription: "Lets", + subdescription: "Lets find the unique set of names from the document.", document: `[{type: foo, names: [Fred, Catherine]}, {type: bar, names: [Zelda]}, {type: foo, names: Fred}, {type: foo, names: Ava}]`, expression: `[.[] | select(.type == "foo") | .names] | flatten | sort | unique`, explanation: []string{ @@ -82,6 +87,23 @@ var recipes = []expressionScenario{ "D0, P[], (!!seq)::- Ava\n- Catherine\n- Fred\n", }, }, + { + description: "Export as environment variables (script), or any custom format", + subdescription: "Given a yaml document, lets output a script that will configure environment variables with that data. This same approach can be used for exporting into custom formats.", + document: "var0: string0\nvar1: string1\nary0: [aryval0, aryval1, aryval2]\n", + expression: bashEnvScript, + expected: []string{ + "D0, P[var0='string0'], (!!str)::var0='string0'\n", + "D0, P[var1='string1'], (!!str)::var1='string1'\n", + "D0, P[ary0=('aryval0','aryval1','aryval2')], (!!str)::ary0=('aryval0','aryval1','aryval2')\n", + }, + explanation: []string{ + "`.[]` matches all top level elements", + "We need a string expression for each of the different types that will product the bash syntax, we'll use the union operator , to join them together", + "Scalars, we just need the key and quoted value: `( select(kind == \"scalar\") | key + \"='\" + . + \"'\")`", + "Sequences (or arrays) are trickier, we need to quote each value and `join` them with `,`: `map(\"'\" + . + \"'\") | join(\",\")`", + }, + }, } func TestRecipes(t *testing.T) {