diff --git a/README.md b/README.md index 54f61162..756f2960 100644 --- a/README.md +++ b/README.md @@ -80,7 +80,7 @@ yq() { ### Go Get: ``` -GO111MODULE=on go get github.com/mikefarah/yq/v4 +GO111MODULE=on go get github.com/mikefarah/yq ``` ## Community Supported Installation methods diff --git a/pkg/yqlib/candidate_node.go b/pkg/yqlib/candidate_node.go index 603bd9b8..f9f9e0cc 100644 --- a/pkg/yqlib/candidate_node.go +++ b/pkg/yqlib/candidate_node.go @@ -21,6 +21,14 @@ func (n *CandidateNode) GetKey() string { 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) { clone := &CandidateNode{} err := copier.Copy(clone, n) diff --git a/pkg/yqlib/operator_collect_object.go b/pkg/yqlib/operator_collect_object.go index 147fc633..734dc9f5 100644 --- a/pkg/yqlib/operator_collect_object.go +++ b/pkg/yqlib/operator_collect_object.go @@ -55,7 +55,7 @@ func CollectObjectOperator(d *dataTreeNavigator, matchMap *list.List, pathNode * func createChildCandidate(candidate *CandidateNode, index int) *CandidateNode { return &CandidateNode{ Document: candidate.Document, - Path: append(candidate.Path, index), + Path: candidate.CreateChildPath(index), Filename: candidate.Filename, Node: candidate.Node.Content[index], } diff --git a/pkg/yqlib/operator_delete.go b/pkg/yqlib/operator_delete.go index 34c39634..9d2f53ba 100644 --- a/pkg/yqlib/operator_delete.go +++ b/pkg/yqlib/operator_delete.go @@ -75,7 +75,7 @@ func deleteFromMap(candidate *CandidateNode, childPath interface{}) { childCandidate := &CandidateNode{ Node: value, Document: candidate.Document, - Path: append(candidate.Path, key.Value), + Path: candidate.CreateChildPath(key.Value), } shouldDelete := key.Value == childPath diff --git a/pkg/yqlib/operator_path_test.go b/pkg/yqlib/operator_path_test.go index d9170878..ba0bb666 100644 --- a/pkg/yqlib/operator_path_test.go +++ b/pkg/yqlib/operator_path_test.go @@ -13,6 +13,23 @@ var pathOperatorScenarios = []expressionScenario{ "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", document: `{a: {b: cat}}`, diff --git a/pkg/yqlib/operator_traverse_path.go b/pkg/yqlib/operator_traverse_path.go index 574cfb36..3aea7701 100644 --- a/pkg/yqlib/operator_traverse_path.go +++ b/pkg/yqlib/operator_traverse_path.go @@ -6,8 +6,7 @@ import ( "container/list" "github.com/elliotchance/orderedmap" - - "gopkg.in/yaml.v3" + yaml "gopkg.in/yaml.v3" ) type TraversePreferences struct { @@ -144,7 +143,7 @@ func traverseMap(newMatches *orderedmap.OrderedMap, candidate *CandidateNode, op log.Debug("MATCHED") candidateNode := &CandidateNode{ Node: value, - Path: append(candidate.Path, key.Value), + Path: candidate.CreateChildPath(key.Value), Document: candidate.Document, } newMatches.Set(candidateNode.GetKey(), candidateNode) @@ -182,9 +181,10 @@ func traverseArray(candidate *CandidateNode, operation *Operation) ([]*Candidate var newMatches = make([]*CandidateNode, len(contents)) var index int64 for index = 0; index < int64(len(contents)); index = index + 1 { + newMatches[index] = &CandidateNode{ Document: candidate.Document, - Path: append(candidate.Path, index), + Path: candidate.CreateChildPath(index), Node: contents[index], } } @@ -213,7 +213,7 @@ func traverseArray(candidate *CandidateNode, operation *Operation) ([]*Candidate return []*CandidateNode{&CandidateNode{ Node: candidate.Node.Content[indexToUse], Document: candidate.Document, - Path: append(candidate.Path, index), + Path: candidate.CreateChildPath(index), }}, nil default: log.Debug("argument not an int (%v), no array matches", operation.Value)