Fixed delete array pattern matching

This commit is contained in:
Mike Farah 2020-01-30 14:55:58 +11:00
parent 789ea02096
commit 44f36833cf
4 changed files with 41 additions and 15 deletions

View File

@ -96,7 +96,7 @@ Usage:
yq [command] yq [command]
Available Commands: 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 help Help about any command
merge yq m [--inplace/-i] [--doc/-d index] [--overwrite/-x] [--append/-a] sample.yaml sample2.yaml 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 new yq n [--script/-s script_file] a.b.c newValue

View File

@ -1255,7 +1255,7 @@ b:
test.AssertResult(t, expectedOutput, result.Output) test.AssertResult(t, expectedOutput, result.Output)
} }
func TestDeleteYamlArray(t *testing.T) { func TestDeleteYamlArrayCmd(t *testing.T) {
content := `- 1 content := `- 1
- 2 - 2
- 3 - 3
@ -1275,6 +1275,26 @@ func TestDeleteYamlArray(t *testing.T) {
test.AssertResult(t, expectedOutput, result.Output) 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) { func TestDeleteYamlMulti(t *testing.T) {
content := `apples: great content := `apples: great
--- ---

View File

@ -10,7 +10,7 @@ func createDeleteCmd() *cobra.Command {
var cmdDelete = &cobra.Command{ var cmdDelete = &cobra.Command{
Use: "delete [yaml_file] [path_expression]", Use: "delete [yaml_file] [path_expression]",
Aliases: []string{"d"}, 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: ` Example: `
yq delete things.yaml 'a.b.c' yq delete things.yaml 'a.b.c'
yq delete things.yaml 'a.*.c' yq delete things.yaml 'a.*.c'

View File

@ -22,10 +22,7 @@ func DeleteNavigationStrategy(pathElementToDelete string) NavigationStrategy {
log.Debug("need to find and delete %v in here", pathElementToDelete) log.Debug("need to find and delete %v in here", pathElementToDelete)
DebugNode(node) DebugNode(node)
if node.Kind == yaml.SequenceNode { if node.Kind == yaml.SequenceNode {
newContent, errorDeleting := deleteFromArray(node.Content, pathElementToDelete) newContent := deleteFromArray(parser, node.Content, nodeContext.PathStack, pathElementToDelete)
if errorDeleting != nil {
return errorDeleting
}
node.Content = newContent node.Content = newContent
} else if node.Kind == yaml.MappingNode { } else if node.Kind == yaml.MappingNode {
node.Content = deleteFromMap(parser, node.Content, nodeContext.PathStack, pathElementToDelete) node.Content = deleteFromMap(parser, node.Content, nodeContext.PathStack, pathElementToDelete)
@ -49,19 +46,28 @@ func deleteFromMap(pathParser PathParser, contents []*yaml.Node, pathStack []int
return newContents 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 == "*" { var indexToDelete, err = strconv.ParseInt(pathElementToDelete, 10, 64) // nolint
return make([]*yaml.Node, 0), nil 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 for _, childValue := range content {
if err != nil { if !pathParser.MatchesNextPathElement(NewNodeContext(childValue, pathElementToDelete, []string{}, pathStack), childValue.Value) {
return content, err 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)) { if index >= int64(len(content)) {
log.Debug("index %v is greater than content length %v", index, 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:]...)
} }