Fixed nested array splat path

This commit is contained in:
Mike Farah 2020-12-25 12:46:08 +11:00
parent eb539ff326
commit 98e8b3479f
6 changed files with 33 additions and 8 deletions

View File

@ -80,7 +80,7 @@ yq() {
### Go Get: ### Go Get:
``` ```
GO111MODULE=on go get github.com/mikefarah/yq/v4 GO111MODULE=on go get github.com/mikefarah/yq
``` ```
## Community Supported Installation methods ## Community Supported Installation methods

View File

@ -21,6 +21,14 @@ func (n *CandidateNode) GetKey() string {
return fmt.Sprintf("%v - %v", n.Document, n.Path) return fmt.Sprintf("%v - %v", n.Document, n.Path)
} }
func (n *CandidateNode) CreateChildPath(path interface{}) []interface{} {
//don't use append as they may actually modify the path of the orignal node!
newPath := make([]interface{}, len(n.Path)+1)
copy(newPath, n.Path)
newPath[len(n.Path)] = path
return newPath
}
func (n *CandidateNode) Copy() (*CandidateNode, error) { func (n *CandidateNode) Copy() (*CandidateNode, error) {
clone := &CandidateNode{} clone := &CandidateNode{}
err := copier.Copy(clone, n) err := copier.Copy(clone, n)

View File

@ -55,7 +55,7 @@ func CollectObjectOperator(d *dataTreeNavigator, matchMap *list.List, pathNode *
func createChildCandidate(candidate *CandidateNode, index int) *CandidateNode { func createChildCandidate(candidate *CandidateNode, index int) *CandidateNode {
return &CandidateNode{ return &CandidateNode{
Document: candidate.Document, Document: candidate.Document,
Path: append(candidate.Path, index), Path: candidate.CreateChildPath(index),
Filename: candidate.Filename, Filename: candidate.Filename,
Node: candidate.Node.Content[index], Node: candidate.Node.Content[index],
} }

View File

@ -75,7 +75,7 @@ func deleteFromMap(candidate *CandidateNode, childPath interface{}) {
childCandidate := &CandidateNode{ childCandidate := &CandidateNode{
Node: value, Node: value,
Document: candidate.Document, Document: candidate.Document,
Path: append(candidate.Path, key.Value), Path: candidate.CreateChildPath(key.Value),
} }
shouldDelete := key.Value == childPath shouldDelete := key.Value == childPath

View File

@ -13,6 +13,23 @@ var pathOperatorScenarios = []expressionScenario{
"D0, P[a b], (!!seq)::- a\n- b\n", "D0, P[a b], (!!seq)::- a\n- b\n",
}, },
}, },
{
skipDoc: true,
document: `a:
b:
c:
- 0
- 1
- 2
- 3`,
expression: `.a.b.c.[]`,
expected: []string{
"D0, P[a b c 0], (!!int)::0\n",
"D0, P[a b c 1], (!!int)::1\n",
"D0, P[a b c 2], (!!int)::2\n",
"D0, P[a b c 3], (!!int)::3\n",
},
},
{ {
description: "Get map key", description: "Get map key",
document: `{a: {b: cat}}`, document: `{a: {b: cat}}`,

View File

@ -6,8 +6,7 @@ import (
"container/list" "container/list"
"github.com/elliotchance/orderedmap" "github.com/elliotchance/orderedmap"
yaml "gopkg.in/yaml.v3"
"gopkg.in/yaml.v3"
) )
type TraversePreferences struct { type TraversePreferences struct {
@ -144,7 +143,7 @@ func traverseMap(newMatches *orderedmap.OrderedMap, candidate *CandidateNode, op
log.Debug("MATCHED") log.Debug("MATCHED")
candidateNode := &CandidateNode{ candidateNode := &CandidateNode{
Node: value, Node: value,
Path: append(candidate.Path, key.Value), Path: candidate.CreateChildPath(key.Value),
Document: candidate.Document, Document: candidate.Document,
} }
newMatches.Set(candidateNode.GetKey(), candidateNode) newMatches.Set(candidateNode.GetKey(), candidateNode)
@ -182,9 +181,10 @@ func traverseArray(candidate *CandidateNode, operation *Operation) ([]*Candidate
var newMatches = make([]*CandidateNode, len(contents)) var newMatches = make([]*CandidateNode, len(contents))
var index int64 var index int64
for index = 0; index < int64(len(contents)); index = index + 1 { for index = 0; index < int64(len(contents)); index = index + 1 {
newMatches[index] = &CandidateNode{ newMatches[index] = &CandidateNode{
Document: candidate.Document, Document: candidate.Document,
Path: append(candidate.Path, index), Path: candidate.CreateChildPath(index),
Node: contents[index], Node: contents[index],
} }
} }
@ -213,7 +213,7 @@ func traverseArray(candidate *CandidateNode, operation *Operation) ([]*Candidate
return []*CandidateNode{&CandidateNode{ return []*CandidateNode{&CandidateNode{
Node: candidate.Node.Content[indexToUse], Node: candidate.Node.Content[indexToUse],
Document: candidate.Document, Document: candidate.Document,
Path: append(candidate.Path, index), Path: candidate.CreateChildPath(index),
}}, nil }}, nil
default: default:
log.Debug("argument not an int (%v), no array matches", operation.Value) log.Debug("argument not an int (%v), no array matches", operation.Value)