mirror of
https://github.com/mikefarah/yq.git
synced 2024-11-13 22:38:04 +00:00
Fixed merge anchor bug #800
This commit is contained in:
parent
37f3e21970
commit
ae4b606707
@ -3,6 +3,97 @@ Use the `alias` and `anchor` operators to read and write yaml aliases and anchor
|
|||||||
`yq` supports merge aliases (like `<<: *blah`) however this is no longer in the standard yaml spec (1.2) and so `yq` will automatically add the `!!merge` tag to these nodes as it is effectively a custom tag.
|
`yq` supports merge aliases (like `<<: *blah`) however this is no longer in the standard yaml spec (1.2) and so `yq` will automatically add the `!!merge` tag to these nodes as it is effectively a custom tag.
|
||||||
|
|
||||||
|
|
||||||
|
## Merge one map
|
||||||
|
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
|
||||||
|
r: 10
|
||||||
|
```
|
||||||
|
then
|
||||||
|
```bash
|
||||||
|
yq eval '.[4] | explode(.)' sample.yml
|
||||||
|
```
|
||||||
|
will output
|
||||||
|
```yaml
|
||||||
|
x: 1
|
||||||
|
y: 2
|
||||||
|
r: 10
|
||||||
|
```
|
||||||
|
|
||||||
|
## 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 eval '.[4] | explode(.)' sample.yml
|
||||||
|
```
|
||||||
|
will output
|
||||||
|
```yaml
|
||||||
|
r: 10
|
||||||
|
x: 1
|
||||||
|
y: 2
|
||||||
|
```
|
||||||
|
|
||||||
|
## 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 eval '.[4] | explode(.)' sample.yml
|
||||||
|
```
|
||||||
|
will output
|
||||||
|
```yaml
|
||||||
|
r: 10
|
||||||
|
x: 1
|
||||||
|
y: 2
|
||||||
|
```
|
||||||
|
|
||||||
## Get anchor
|
## Get anchor
|
||||||
Given a sample.yml file of:
|
Given a sample.yml file of:
|
||||||
```yaml
|
```yaml
|
||||||
@ -183,9 +274,9 @@ bar:
|
|||||||
c: bar_c
|
c: bar_c
|
||||||
foobarList:
|
foobarList:
|
||||||
b: bar_b
|
b: bar_b
|
||||||
a: foo_a
|
thing: foo_thing
|
||||||
thing: bar_thing
|
|
||||||
c: foobarList_c
|
c: foobarList_c
|
||||||
|
a: foo_a
|
||||||
foobar:
|
foobar:
|
||||||
c: foo_c
|
c: foo_c
|
||||||
a: foo_a
|
a: foo_a
|
||||||
|
@ -176,7 +176,7 @@ func explodeNode(node *yaml.Node, context Context) error {
|
|||||||
} else {
|
} else {
|
||||||
if valueNode.Kind == yaml.SequenceNode {
|
if valueNode.Kind == yaml.SequenceNode {
|
||||||
log.Debugf("an alias merge list!")
|
log.Debugf("an alias merge list!")
|
||||||
for index := 0; index < len(valueNode.Content); index = index + 1 {
|
for index := len(valueNode.Content) - 1; index >= 0; index = index - 1 {
|
||||||
aliasNode := valueNode.Content[index]
|
aliasNode := valueNode.Content[index]
|
||||||
err := applyAlias(node, aliasNode.Alias, index, context.ChildContext(newContent))
|
err := applyAlias(node, aliasNode.Alias, index, context.ChildContext(newContent))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -4,7 +4,36 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var specDocument = `- &CENTER { x: 1, y: 2 }
|
||||||
|
- &LEFT { x: 0, y: 2 }
|
||||||
|
- &BIG { r: 10 }
|
||||||
|
- &SMALL { r: 1 }
|
||||||
|
`
|
||||||
|
|
||||||
|
var expectedSpecResult = "D0, P[4], (!!map)::x: 1\ny: 2\nr: 10\n"
|
||||||
|
|
||||||
var anchorOperatorScenarios = []expressionScenario{
|
var anchorOperatorScenarios = []expressionScenario{
|
||||||
|
{
|
||||||
|
description: "Merge one map",
|
||||||
|
subdescription: "see https://yaml.org/type/merge.html",
|
||||||
|
document: specDocument + "- << : *CENTER\n r: 10\n",
|
||||||
|
expression: ".[4] | explode(.)",
|
||||||
|
expected: []string{expectedSpecResult},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "Merge multiple maps",
|
||||||
|
subdescription: "see https://yaml.org/type/merge.html",
|
||||||
|
document: specDocument + "- << : [ *CENTER, *BIG ]\n",
|
||||||
|
expression: ".[4] | explode(.)",
|
||||||
|
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: "Get anchor",
|
description: "Get anchor",
|
||||||
document: `a: &billyBob cat`,
|
document: `a: &billyBob cat`,
|
||||||
@ -91,9 +120,9 @@ bar:
|
|||||||
c: bar_c
|
c: bar_c
|
||||||
foobarList:
|
foobarList:
|
||||||
b: bar_b
|
b: bar_b
|
||||||
a: foo_a
|
thing: foo_thing
|
||||||
thing: bar_thing
|
|
||||||
c: foobarList_c
|
c: foobarList_c
|
||||||
|
a: foo_a
|
||||||
foobar:
|
foobar:
|
||||||
c: foo_c
|
c: foo_c
|
||||||
a: foo_a
|
a: foo_a
|
||||||
@ -106,7 +135,7 @@ foobar:
|
|||||||
expression: `.foo* | explode(.) | (. style="flow")`,
|
expression: `.foo* | explode(.) | (. style="flow")`,
|
||||||
expected: []string{
|
expected: []string{
|
||||||
"D0, P[foo], (!!map)::{a: foo_a, thing: foo_thing, c: foo_c}\n",
|
"D0, P[foo], (!!map)::{a: foo_a, thing: foo_thing, c: foo_c}\n",
|
||||||
"D0, P[foobarList], (!!map)::{b: bar_b, a: foo_a, thing: bar_thing, c: foobarList_c}\n",
|
"D0, P[foobarList], (!!map)::{b: bar_b, thing: foo_thing, c: foobarList_c, a: foo_a}\n",
|
||||||
"D0, P[foobar], (!!map)::{c: foo_c, a: foo_a, thing: foobar_thing}\n",
|
"D0, P[foobar], (!!map)::{c: foo_c, a: foo_a, thing: foobar_thing}\n",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -116,7 +145,7 @@ foobar:
|
|||||||
expression: `.foo* | explode(explode(.)) | (. style="flow")`,
|
expression: `.foo* | explode(explode(.)) | (. style="flow")`,
|
||||||
expected: []string{
|
expected: []string{
|
||||||
"D0, P[foo], (!!map)::{a: foo_a, thing: foo_thing, c: foo_c}\n",
|
"D0, P[foo], (!!map)::{a: foo_a, thing: foo_thing, c: foo_c}\n",
|
||||||
"D0, P[foobarList], (!!map)::{b: bar_b, a: foo_a, thing: bar_thing, c: foobarList_c}\n",
|
"D0, P[foobarList], (!!map)::{b: bar_b, thing: foo_thing, c: foobarList_c, a: foo_a}\n",
|
||||||
"D0, P[foobar], (!!map)::{c: foo_c, a: foo_a, thing: foobar_thing}\n",
|
"D0, P[foobar], (!!map)::{c: foo_c, a: foo_a, thing: foobar_thing}\n",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -71,7 +71,7 @@ func testScenario(t *testing.T, s *expressionScenario) {
|
|||||||
t.Error(fmt.Errorf("%v: %v", err, s.expression))
|
t.Error(fmt.Errorf("%v: %v", err, s.expression))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
test.AssertResultComplexWithContext(t, s.expected, resultsToString(context.MatchingNodes), fmt.Sprintf("exp: %v\ndoc: %v", s.expression, s.document))
|
test.AssertResultComplexWithContext(t, s.expected, resultsToString(context.MatchingNodes), fmt.Sprintf("desc: %v\nexp: %v\ndoc: %v", s.description, s.expression, s.document))
|
||||||
}
|
}
|
||||||
|
|
||||||
func resultsToString(results *list.List) []string {
|
func resultsToString(results *list.List) []string {
|
||||||
|
Loading…
Reference in New Issue
Block a user