diff --git a/README.md b/README.md index 9ad9549f..c37367b2 100644 --- a/README.md +++ b/README.md @@ -96,7 +96,7 @@ Usage: yq [command] Available Commands: - delete yq d [--inplace/-i] [--doc/-d index] sample.yaml 'b.e(name==fred).value' + delete yq d [--inplace/-i] [--doc/-d index] sample.yaml 'b.e(name==fred)' help Help about any command merge yq m [--inplace/-i] [--doc/-d index] [--overwrite/-x] [--append/-a] sample.yaml sample2.yaml new yq n [--script/-s script_file] a.b.c newValue diff --git a/cmd/commands_test.go b/cmd/commands_test.go index 772885a4..220728f1 100644 --- a/cmd/commands_test.go +++ b/cmd/commands_test.go @@ -1255,7 +1255,7 @@ b: test.AssertResult(t, expectedOutput, result.Output) } -func TestDeleteYamlArray(t *testing.T) { +func TestDeleteYamlArrayCmd(t *testing.T) { content := `- 1 - 2 - 3 @@ -1275,6 +1275,26 @@ func TestDeleteYamlArray(t *testing.T) { test.AssertResult(t, expectedOutput, result.Output) } +func TestDeleteYamlArrayExpressionCmd(t *testing.T) { + content := `- name: fred +- name: cat +- name: thing +` + filename := test.WriteTempYamlFile(content) + defer test.RemoveTempYamlFile(filename) + + cmd := getRootCommand() + result := test.RunCmd(cmd, fmt.Sprintf("delete %s (name==cat)", filename)) + if result.Error != nil { + t.Error(result.Error) + } + + expectedOutput := `- name: fred +- name: thing +` + test.AssertResult(t, expectedOutput, result.Output) +} + func TestDeleteYamlMulti(t *testing.T) { content := `apples: great --- diff --git a/cmd/delete.go b/cmd/delete.go index 5d857751..b1153109 100644 --- a/cmd/delete.go +++ b/cmd/delete.go @@ -10,7 +10,7 @@ func createDeleteCmd() *cobra.Command { var cmdDelete = &cobra.Command{ Use: "delete [yaml_file] [path_expression]", Aliases: []string{"d"}, - Short: "yq d [--inplace/-i] [--doc/-d index] sample.yaml 'b.e(name==fred).value'", + Short: "yq d [--inplace/-i] [--doc/-d index] sample.yaml 'b.e(name==fred)'", Example: ` yq delete things.yaml 'a.b.c' yq delete things.yaml 'a.*.c' diff --git a/pkg/yqlib/delete_navigation_strategy.go b/pkg/yqlib/delete_navigation_strategy.go index becad835..de51e306 100644 --- a/pkg/yqlib/delete_navigation_strategy.go +++ b/pkg/yqlib/delete_navigation_strategy.go @@ -22,10 +22,7 @@ func DeleteNavigationStrategy(pathElementToDelete string) NavigationStrategy { log.Debug("need to find and delete %v in here", pathElementToDelete) DebugNode(node) if node.Kind == yaml.SequenceNode { - newContent, errorDeleting := deleteFromArray(node.Content, pathElementToDelete) - if errorDeleting != nil { - return errorDeleting - } + newContent := deleteFromArray(parser, node.Content, nodeContext.PathStack, pathElementToDelete) node.Content = newContent } else if node.Kind == yaml.MappingNode { node.Content = deleteFromMap(parser, node.Content, nodeContext.PathStack, pathElementToDelete) @@ -49,19 +46,28 @@ func deleteFromMap(pathParser PathParser, contents []*yaml.Node, pathStack []int return newContents } -func deleteFromArray(content []*yaml.Node, pathElementToDelete string) ([]*yaml.Node, error) { +func deleteFromArray(pathParser PathParser, content []*yaml.Node, pathStack []interface{}, pathElementToDelete string) []*yaml.Node { - if pathElementToDelete == "*" { - return make([]*yaml.Node, 0), nil + var indexToDelete, err = strconv.ParseInt(pathElementToDelete, 10, 64) // nolint + if err == nil { + return deleteIndexInArray(content, indexToDelete) } + log.Debug("%v is not a numeric index, finding matching patterns", pathElementToDelete) + var newArray = make([]*yaml.Node, 0) - var index, err = strconv.ParseInt(pathElementToDelete, 10, 64) // nolint - if err != nil { - return content, err + for _, childValue := range content { + if !pathParser.MatchesNextPathElement(NewNodeContext(childValue, pathElementToDelete, []string{}, pathStack), childValue.Value) { + newArray = append(newArray, childValue) + } } + return newArray +} + +func deleteIndexInArray(content []*yaml.Node, index int64) []*yaml.Node { + log.Debug("deleting index %v in array", index) if index >= int64(len(content)) { log.Debug("index %v is greater than content length %v", index, len(content)) - return content, nil + return content } - return append(content[:index], content[index+1:]...), nil + return append(content[:index], content[index+1:]...) }