diff --git a/cmd/read_test.go b/cmd/read_test.go index bbbb6e6f..cb9fdfda 100644 --- a/cmd/read_test.go +++ b/cmd/read_test.go @@ -320,7 +320,7 @@ dog: bark defer test.RemoveTempYamlFile(filename) cmd := getRootCommand() - result := test.RunCmd(cmd, fmt.Sprintf("read -l %s", filename)) + result := test.RunCmd(cmd, fmt.Sprintf("read %s count(*)", filename)) if result.Error != nil { t.Error(result.Error) } @@ -336,7 +336,7 @@ func TestReadObjectLengthDeepCmd(t *testing.T) { defer test.RemoveTempYamlFile(filename) cmd := getRootCommand() - result := test.RunCmd(cmd, fmt.Sprintf("read -l %s holder", filename)) + result := test.RunCmd(cmd, fmt.Sprintf("read %s count(holder.*)", filename)) if result.Error != nil { t.Error(result.Error) } @@ -355,7 +355,7 @@ holderB: defer test.RemoveTempYamlFile(filename) cmd := getRootCommand() - result := test.RunCmd(cmd, fmt.Sprintf("read -l -c %s holder*", filename)) + result := test.RunCmd(cmd, fmt.Sprintf("read %s count(holder*)", filename)) if result.Error != nil { t.Error(result.Error) } @@ -374,7 +374,7 @@ holderB: defer test.RemoveTempYamlFile(filename) cmd := getRootCommand() - result := test.RunCmd(cmd, fmt.Sprintf("read -l -ppv %s holder*", filename)) + result := test.RunCmd(cmd, fmt.Sprintf("read -ppv %s holder*.(count(*))", filename)) if result.Error != nil { t.Error(result.Error) } @@ -387,7 +387,7 @@ func TestReadScalarLengthCmd(t *testing.T) { defer test.RemoveTempYamlFile(filename) cmd := getRootCommand() - result := test.RunCmd(cmd, fmt.Sprintf("read -l %s", filename)) + result := test.RunCmd(cmd, fmt.Sprintf("read %s 'count(.)'", filename)) if result.Error != nil { t.Error(result.Error) } diff --git a/pkg/yqlib/treeops/leaf_traverser.go b/pkg/yqlib/treeops/leaf_traverser.go index bb855b2a..1dee1740 100644 --- a/pkg/yqlib/treeops/leaf_traverser.go +++ b/pkg/yqlib/treeops/leaf_traverser.go @@ -1,6 +1,8 @@ package treeops import ( + "fmt" + "gopkg.in/yaml.v3" ) @@ -68,13 +70,23 @@ func (t *traverser) traverseArray(candidate *CandidateNode, pathNode *PathElemen } index := pathNode.Value.(int64) - if int64(len(candidate.Node.Content)) < index { + indexToUse := index + contentLength := int64(len(candidate.Node.Content)) + if contentLength <= index { // handle auto append here return make([]*CandidateNode, 0), nil } + if indexToUse < 0 { + indexToUse = contentLength + indexToUse + } + + if indexToUse < 0 { + return nil, fmt.Errorf("Index [%v] out of range, array size is %v", index, contentLength) + } + return []*CandidateNode{&CandidateNode{ - Node: candidate.Node.Content[index], + Node: candidate.Node.Content[indexToUse], Document: candidate.Document, Path: append(candidate.Path, index), }}, nil