mirror of
https://github.com/mikefarah/yq.git
synced 2026-07-06 21:55:37 +00:00
Fix excessive exploding for merge anchor
This commit is contained in:
parent
4d88d51b1b
commit
4734be9a4d
@ -148,12 +148,12 @@ func reconstructAliasedMap(node *CandidateNode, context Context) error {
|
|||||||
valueNode := node.Content[index+1]
|
valueNode := node.Content[index+1]
|
||||||
log.Debugf("traversing %v", keyNode.Value)
|
log.Debugf("traversing %v", keyNode.Value)
|
||||||
if keyNode.Tag != "!!merge" {
|
if keyNode.Tag != "!!merge" {
|
||||||
err := overrideEntry(node, keyNode, valueNode, index, context.ChildContext(newContent))
|
err := overrideEntry(node, keyNode, valueNode, index, true, context.ChildContext(newContent))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
err := applyMergeAnchor(node, valueNode, index, context, newContent)
|
err := applyMergeAnchor(node, valueNode, index, context.ChildContext(newContent))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -225,14 +225,14 @@ func explodeNode(node *CandidateNode, context Context) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func applyMergeAnchor(node *CandidateNode, merge *CandidateNode, mergeIndex int, context Context, newContent *list.List) error {
|
func applyMergeAnchor(node *CandidateNode, merge *CandidateNode, mergeIndex int, newContent Context) error {
|
||||||
if merge.Kind == AliasNode {
|
if merge.Kind == AliasNode {
|
||||||
merge = merge.Alias
|
merge = merge.Alias
|
||||||
}
|
}
|
||||||
switch merge.Kind {
|
switch merge.Kind {
|
||||||
case MappingNode:
|
case MappingNode:
|
||||||
log.Debugf("a merge map!")
|
log.Debugf("a merge map!")
|
||||||
return applyMergeAnchorMap(node, merge, mergeIndex, context.ChildContext(newContent))
|
return applyMergeAnchorMap(node, merge, mergeIndex, newContent)
|
||||||
case SequenceNode:
|
case SequenceNode:
|
||||||
log.Debugf("a merge list!")
|
log.Debugf("a merge list!")
|
||||||
// Earlier keys take precedence
|
// Earlier keys take precedence
|
||||||
@ -245,9 +245,8 @@ func applyMergeAnchor(node *CandidateNode, merge *CandidateNode, mergeIndex int,
|
|||||||
return fmt.Errorf(
|
return fmt.Errorf(
|
||||||
"can only use merge anchors with maps (!!map) or sequences (!!seq) of maps, but got sequence containing %v",
|
"can only use merge anchors with maps (!!map) or sequences (!!seq) of maps, but got sequence containing %v",
|
||||||
childValue.Tag)
|
childValue.Tag)
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
err := applyMergeAnchorMap(node, childValue, mergeIndex, context.ChildContext(newContent))
|
err := applyMergeAnchorMap(node, childValue, mergeIndex, newContent)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -258,20 +257,21 @@ func applyMergeAnchor(node *CandidateNode, merge *CandidateNode, mergeIndex int,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func applyMergeAnchorMap(node *CandidateNode, mergeMap *CandidateNode, aliasIndex int, newContent Context) error {
|
func applyMergeAnchorMap(node *CandidateNode, mergeMap *CandidateNode, mergeIndex int, newContent Context) error {
|
||||||
log.Debug("merge map is nil ?")
|
|
||||||
if mergeMap == nil {
|
if mergeMap == nil {
|
||||||
|
log.Debug("merge map is nil")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
log.Debug("merge map: %v", NodeToString(mergeMap))
|
log.Debug("merge map: %v", NodeToString(mergeMap))
|
||||||
if mergeMap.Kind != MappingNode {
|
if mergeMap.Kind != MappingNode {
|
||||||
return fmt.Errorf("applyMergeAnchorMap expects !!map, got %v instead", mergeMap.Tag)
|
return fmt.Errorf("applyMergeAnchorMap expects !!map, got %v instead", mergeMap.Tag)
|
||||||
}
|
}
|
||||||
|
|
||||||
for index := 0; index < len(mergeMap.Content); index = index + 2 {
|
for index := 0; index < len(mergeMap.Content); index = index + 2 {
|
||||||
keyNode := mergeMap.Content[index]
|
keyNode := mergeMap.Content[index]
|
||||||
log.Debugf("applying merge map key %v", keyNode.Value)
|
log.Debugf("applying merge map key %v", keyNode.Value)
|
||||||
valueNode := mergeMap.Content[index+1]
|
valueNode := mergeMap.Content[index+1]
|
||||||
err := overrideEntry(node, keyNode, valueNode, aliasIndex, newContent)
|
err := overrideEntry(node, keyNode, valueNode, mergeIndex, false, newContent)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -279,12 +279,12 @@ func applyMergeAnchorMap(node *CandidateNode, mergeMap *CandidateNode, aliasInde
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func overrideEntry(node *CandidateNode, key *CandidateNode, value *CandidateNode, startIndex int, newContent Context) error {
|
func overrideEntry(node *CandidateNode, key *CandidateNode, value *CandidateNode, startIndex int, explode bool, newContent Context) error {
|
||||||
|
if explode {
|
||||||
err := explodeNode(value, newContent)
|
err := explodeNode(value, newContent)
|
||||||
|
if err != nil {
|
||||||
if err != nil {
|
return err
|
||||||
return err
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for newEl := newContent.MatchingNodes.Front(); newEl != nil; newEl = newEl.Next() {
|
for newEl := newContent.MatchingNodes.Front(); newEl != nil; newEl = newEl.Next() {
|
||||||
@ -308,9 +308,11 @@ func overrideEntry(node *CandidateNode, key *CandidateNode, value *CandidateNode
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = explodeNode(key, newContent)
|
if explode {
|
||||||
if err != nil {
|
err := explodeNode(key, newContent)
|
||||||
return err
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
log.Debugf("adding %v:%v", key.Value, value.Value)
|
log.Debugf("adding %v:%v", key.Value, value.Value)
|
||||||
newContent.MatchingNodes.PushBack(key)
|
newContent.MatchingNodes.PushBack(key)
|
||||||
|
|||||||
@ -307,6 +307,15 @@ var anchorOperatorScenarios = []expressionScenario{
|
|||||||
"D0, P[m], (!!map)::{a: 42}\n",
|
"D0, P[m], (!!map)::{a: 42}\n",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{ // Exploding merge anchor should not explode neighbors
|
||||||
|
skipDoc: true,
|
||||||
|
// b must not be exploded, as `r: *a` will become invalid
|
||||||
|
document: `{b: &b {a: &a 42}, r: *a, c: {<<: *b}}`,
|
||||||
|
expression: `explode(.c)`,
|
||||||
|
expected: []string{
|
||||||
|
"D0, P[], (!!map)::{b: &b {a: &a 42}, r: *a, c: {a: &a 42}}\n",
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAnchorAliasOperatorScenarios(t *testing.T) {
|
func TestAnchorAliasOperatorScenarios(t *testing.T) {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user