diff --git a/pkg/yqlib/doc/operators/anchor-and-alias-operators.md b/pkg/yqlib/doc/operators/anchor-and-alias-operators.md index 0a745236..8c9a7381 100644 --- a/pkg/yqlib/doc/operators/anchor-and-alias-operators.md +++ b/pkg/yqlib/doc/operators/anchor-and-alias-operators.md @@ -8,9 +8,13 @@ Use the `alias` and `anchor` operators to read and write yaml aliases and anchor ## NOTE --yaml-fix-merge-anchor-to-spec flag `yq` doesn't merge anchors `<<:` to spec, in some circumstances it incorrectly overrides existing keys when the spec documents not to do that. -To minimise disruption while still fixing the issue, a flag has been added to toggle this behaviour. This will first default to false; and log warnings to users. Then it will default to true (and still allow users to specify false if needed) +To minimise disruption while still fixing the issue, a flag has been added to toggle this behaviour. This will first default to false; and log warnings to users. Then it will default to true (and still allow users to specify false if needed). -See examples of the flag difference below. +This flag also enables advanced merging, like inline maps, as well as fixes to ensure when exploding a particular path, neighbours are not affect ed. + +Long story short, you should be setting this flag to true. + +See examples of the flag differences below. ## Merge one map @@ -279,8 +283,8 @@ foobar: thing: foobar_thing ``` -## Merge multiple maps -see https://yaml.org/type/merge.html +## LEGACY: Merge multiple maps +see https://yaml.org/type/merge.html. This has the correct data, but the wrong key order; set --yaml-fix-merge-anchor-to-spec=true to fix the key order. Given a sample.yml file of: ```yaml @@ -309,8 +313,8 @@ x: 1 y: 2 ``` -## Override -see https://yaml.org/type/merge.html +## LEGACY: Override +see https://yaml.org/type/merge.html. This has the correct data, but the wrong key order; set --yaml-fix-merge-anchor-to-spec=true to fix the key order. Given a sample.yml file of: ```yaml @@ -342,7 +346,8 @@ y: 2 ``` ## FIXED: Explode with merge anchors -See the foobarList.b property is still foobarList_b. Set `--yaml-fix-merge-anchor-to-spec=true` to get this correct merge behaviour. Flag will default to true in late 2025 +Set `--yaml-fix-merge-anchor-to-spec=true` to get this correct merge behaviour (flag will default to true in late 2025). +Observe that foobarList.b property is still foobarList_b. Given a sample.yml file of: ```yaml @@ -390,8 +395,9 @@ foobar: thing: foobar_thing ``` -## Merge multiple maps -see https://yaml.org/type/merge.html +## FIXED: Merge multiple maps +Set `--yaml-fix-merge-anchor-to-spec=true` to get this correct merge behaviour (flag will default to true in late 2025). +Taken from https://yaml.org/type/merge.html. Same values as legacy, but with the correct key order. Given a sample.yml file of: ```yaml @@ -420,8 +426,9 @@ y: 2 r: 10 ``` -## Override -see https://yaml.org/type/merge.html +## FIXED: Override +Set `--yaml-fix-merge-anchor-to-spec=true` to get this correct merge behaviour (flag will default to true in late 2025). +Taken from https://yaml.org/type/merge.html. Same values as legacy, but with the correct key order. Given a sample.yml file of: ```yaml @@ -452,114 +459,25 @@ y: 2 x: 1 ``` -## FIXED: Explode with merge anchors -See the foobarList.b property is still foobarList_b. Set `--yaml-fix-merge-anchor-to-spec=true` to get this correct merge behaviour. Flag will default to true in late 2025 +## Exploding inline merge anchor +Set `--yaml-fix-merge-anchor-to-spec=true` to get this correct merge behaviour (flag will default to true in late 2025). + Given a sample.yml file of: ```yaml -foo: &foo - a: foo_a - thing: foo_thing - c: foo_c -bar: &bar - b: bar_b - thing: bar_thing - c: bar_c -foobarList: - b: foobarList_b - !!merge <<: - - *foo - - *bar - c: foobarList_c -foobar: - c: foobar_c - !!merge <<: *foo - thing: foobar_thing +a: + b: &b 42 +!!merge <<: + c: *b ``` then ```bash -yq 'explode(.)' sample.yml +yq 'explode(.) | sort_keys(.)' sample.yml ``` will output ```yaml -foo: - a: foo_a - thing: foo_thing - c: foo_c -bar: - b: bar_b - thing: bar_thing - c: bar_c -foobarList: - b: foobarList_b - a: foo_a - thing: foo_thing - c: foobarList_c -foobar: - c: foobar_c - a: foo_a - thing: foobar_thing -``` - -## Merge multiple maps -see https://yaml.org/type/merge.html - -Given a sample.yml file of: -```yaml -- &CENTER - x: 1 - y: 2 -- &LEFT - x: 0 - y: 2 -- &BIG - r: 10 -- &SMALL - r: 1 -- !!merge <<: - - *CENTER - - *BIG -``` -then -```bash -yq '.[4] | explode(.)' sample.yml -``` -will output -```yaml -x: 1 -y: 2 -r: 10 -``` - -## Override -see https://yaml.org/type/merge.html - -Given a sample.yml file of: -```yaml -- &CENTER - x: 1 - y: 2 -- &LEFT - x: 0 - y: 2 -- &BIG - r: 10 -- &SMALL - r: 1 -- !!merge <<: - - *BIG - - *LEFT - - *SMALL - x: 1 -``` -then -```bash -yq '.[4] | explode(.)' sample.yml -``` -will output -```yaml -r: 10 -y: 2 -x: 1 +a: + b: 42 +c: 42 ``` diff --git a/pkg/yqlib/operator_anchors_aliases_test.go b/pkg/yqlib/operator_anchors_aliases_test.go index 59c8fb8a..0fa62905 100644 --- a/pkg/yqlib/operator_anchors_aliases_test.go +++ b/pkg/yqlib/operator_anchors_aliases_test.go @@ -111,7 +111,7 @@ var fixedAnchorOperatorScenarios = []expressionScenario{ }, { description: "FIXED: Explode with merge anchors", - subdescription: "See the foobarList.b property is still foobarList_b. Set `--yaml-fix-merge-anchor-to-spec=true` to get this correct merge behaviour. Flag will default to true in late 2025 ", + subdescription: "Observe that foobarList.b property is still foobarList_b.", document: mergeDocSample, expression: `explode(.)`, expected: []string{explodeMergeAnchorsFixedExpected}, @@ -137,25 +137,24 @@ var fixedAnchorOperatorScenarios = []expressionScenario{ }, }, { - description: "Merge multiple maps", - subdescription: "see https://yaml.org/type/merge.html", + description: "FIXED: Merge multiple maps", + subdescription: "Taken from https://yaml.org/type/merge.html. Same values as legacy, but with the correct key order.", document: specDocument + "- << : [ *CENTER, *BIG ]\n", expression: ".[4] | explode(.)", expected: []string{"D0, P[4], (!!map)::x: 1\ny: 2\nr: 10\n"}, }, { - description: "Override", - subdescription: "see https://yaml.org/type/merge.html", + description: "FIXED: Override", + subdescription: "Taken from https://yaml.org/type/merge.html. Same values as legacy, but with the correct key order.", document: specDocument + "- << : [ *BIG, *LEFT, *SMALL ]\n x: 1\n", expression: ".[4] | explode(.)", expected: []string{"D0, P[4], (!!map)::r: 10\ny: 2\nx: 1\n"}, }, { - skipDoc: true, - description: "Exploding inline merge anchor", - subdescription: "`<<` map must be exploded, otherwise `c: *b` will become invalid", - document: `{a: {b: &b 42}, <<: {c: *b}}`, - expression: `explode(.) | sort_keys(.)`, + description: "Exploding inline merge anchor", + // subdescription: "`<<` map must be exploded, otherwise `c: *b` will become invalid", + document: `{a: {b: &b 42}, <<: {c: *b}}`, + expression: `explode(.) | sort_keys(.)`, expected: []string{ "D0, P[], (!!map)::{a: {b: 42}, c: 42}\n", }, @@ -255,18 +254,19 @@ var badAnchorOperatorScenarios = []expressionScenario{ }, }, { - description: "Merge multiple maps", - subdescription: "see https://yaml.org/type/merge.html", + description: "LEGACY: Merge multiple maps", + subdescription: "see https://yaml.org/type/merge.html. This has the correct data, but the wrong key order; set --yaml-fix-merge-anchor-to-spec=true to fix the key order.", document: specDocument + "- << : [ *CENTER, *BIG ]\n", expression: ".[4] | explode(.)", - expected: []string{"D0, P[4], (!!map)::r: 10\nx: 1\ny: 2\n"}, // correct data, but wrong key order + expected: []string{"D0, P[4], (!!map)::r: 10\nx: 1\ny: 2\n"}, }, { - description: "Override", - subdescription: "see https://yaml.org/type/merge.html", - document: specDocument + "- << : [ *BIG, *LEFT, *SMALL ]\n x: 1\n", - expression: ".[4] | explode(.)", - expected: []string{"D0, P[4], (!!map)::r: 10\nx: 1\ny: 2\n"}, + description: "LEGACY: Override", + subdescription: "see https://yaml.org/type/merge.html. This has the correct data, but the wrong key order; set --yaml-fix-merge-anchor-to-spec=true to fix the key order.", + + document: specDocument + "- << : [ *BIG, *LEFT, *SMALL ]\n x: 1\n", + expression: ".[4] | explode(.)", + expected: []string{"D0, P[4], (!!map)::r: 10\nx: 1\ny: 2\n"}, }, } @@ -501,7 +501,10 @@ func TestAnchorAliasOperatorAlignedToSpecScenarios(t *testing.T) { ConfiguredYamlPreferences.FixMergeAnchorToSpec = true for _, tt := range append(fixedAnchorOperatorScenarios, anchorOperatorScenarios...) { testScenario(t, &tt) + } + for i, tt := range fixedAnchorOperatorScenarios { + fixedAnchorOperatorScenarios[i].subdescription = "Set `--yaml-fix-merge-anchor-to-spec=true` to get this correct merge behaviour (flag will default to true in late 2025).\n" + tt.subdescription } appendOperatorDocumentScenario(t, "anchor-and-alias-operators", fixedAnchorOperatorScenarios) ConfiguredYamlPreferences.FixMergeAnchorToSpec = false diff --git a/pkg/yqlib/operators_test.go b/pkg/yqlib/operators_test.go index 4c9d3d01..23c83c4e 100644 --- a/pkg/yqlib/operators_test.go +++ b/pkg/yqlib/operators_test.go @@ -255,7 +255,7 @@ func documentScenarios(t *testing.T, folder string, title string, scenarios []in func appendOperatorDocumentScenario(t *testing.T, title string, scenarios []expressionScenario) { filename := fmt.Sprintf("doc/%v/%v.md", "operators", title) - f, err := os.OpenFile(filename, os.O_WRONLY|os.O_APPEND, fs.ModeAppend) + f, err := os.OpenFile(filename, os.O_CREATE|os.O_RDWR|os.O_APPEND, fs.ModeAppend) if err != nil { t.Error(err) return