From 1f9a3f5f6c7299317266f1c94f2a369b936c05ed Mon Sep 17 00:00:00 2001 From: Mike Farah Date: Mon, 13 Apr 2020 10:36:46 +1000 Subject: [PATCH] Added negative index capability --- cmd/commands_test.go | 43 +++++++++++++++++++++++++++++++++++++ pkg/yqlib/data_navigator.go | 16 +++++++++++--- scripts/devtools.sh | 2 +- 3 files changed, 57 insertions(+), 4 deletions(-) diff --git a/cmd/commands_test.go b/cmd/commands_test.go index 3b7cb0c7..5945746e 100644 --- a/cmd/commands_test.go +++ b/cmd/commands_test.go @@ -201,6 +201,49 @@ func TestReadArrayCmd(t *testing.T) { test.AssertResult(t, "b.e.[1].name: sam\n", result.Output) } +func TestReadArrayBackwardsCmd(t *testing.T) { + content := `- one +- two +- three` + filename := test.WriteTempYamlFile(content) + defer test.RemoveTempYamlFile(filename) + + cmd := getRootCommand() + result := test.RunCmd(cmd, fmt.Sprintf("read -p pv %s [-1]", filename)) + if result.Error != nil { + t.Error(result.Error) + } + test.AssertResult(t, "'[-1]': three\n", result.Output) +} + +func TestReadArrayBackwardsNegative0Cmd(t *testing.T) { + content := `- one +- two +- three` + filename := test.WriteTempYamlFile(content) + defer test.RemoveTempYamlFile(filename) + + cmd := getRootCommand() + result := test.RunCmd(cmd, fmt.Sprintf("read -p pv %s [-0]", filename)) + if result.Error != nil { + t.Error(result.Error) + } + test.AssertResult(t, "'[0]': one\n", result.Output) +} + +func TestReadArrayBackwardsPastLimitCmd(t *testing.T) { + content := `- one +- two +- three` + filename := test.WriteTempYamlFile(content) + defer test.RemoveTempYamlFile(filename) + + cmd := getRootCommand() + result := test.RunCmd(cmd, fmt.Sprintf("read -p pv %s [-4]", filename)) + expectedOutput := "Error reading path in document index 0: Index [-4] out of range, array size is 3" + test.AssertResult(t, expectedOutput, result.Error.Error()) +} + func TestReadArrayLengthCmd(t *testing.T) { content := `- things - whatever diff --git a/pkg/yqlib/data_navigator.go b/pkg/yqlib/data_navigator.go index b0e0a28a..0c5211a1 100644 --- a/pkg/yqlib/data_navigator.go +++ b/pkg/yqlib/data_navigator.go @@ -260,11 +260,21 @@ func (n *navigator) appendArray(value *yaml.Node, head interface{}, tail []inter } func (n *navigator) recurseArray(value *yaml.Node, index int64, head interface{}, tail []interface{}, pathStack []interface{}) error { - for int64(len(value.Content)) <= index { + var contentLength = int64(len(value.Content)) + for contentLength <= index { value.Content = append(value.Content, &yaml.Node{Kind: guessKind(head, tail, 0)}) } + var indexToUse = index - value.Content[index] = n.getOrReplace(value.Content[index], guessKind(head, tail, value.Content[index].Kind)) + if indexToUse < 0 { + indexToUse = contentLength + indexToUse + } - return n.doTraverse(value.Content[index], head, tail, append(pathStack, index)) + if indexToUse < 0 { + return fmt.Errorf("Index [%v] out of range, array size is %v", index, contentLength) + } + + value.Content[indexToUse] = n.getOrReplace(value.Content[indexToUse], guessKind(head, tail, value.Content[indexToUse].Kind)) + + return n.doTraverse(value.Content[indexToUse], head, tail, append(pathStack, index)) } diff --git a/scripts/devtools.sh b/scripts/devtools.sh index cbd12f36..6e44517f 100755 --- a/scripts/devtools.sh +++ b/scripts/devtools.sh @@ -1,4 +1,4 @@ #!/bin/sh set -e -wget -O- -nv https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s v1.23.1 +wget -O- -nv https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s v1.24.0 go get golang.org/x/tools/cmd/goimports \ No newline at end of file