Can delete arrays

This commit is contained in:
Mike Farah 2019-12-12 20:47:22 +11:00
parent 8c0046a622
commit d061b2f9f9
4 changed files with 75 additions and 51 deletions

View File

@ -1,7 +1,7 @@
a: Easy! as one two three a: Easy! as one two three
b: b:
c: 2 c: 2
d: [3, 4] d: [3, 4, 5]
e: e:
- name: fred - name: fred
value: 3 value: 3

View File

@ -10,8 +10,9 @@ import (
type DataNavigator interface { type DataNavigator interface {
DebugNode(node *yaml.Node) DebugNode(node *yaml.Node)
Get(rootNode *yaml.Node, remainingPath []string) (*yaml.Node, error) Get(rootNode *yaml.Node, path []string) (*yaml.Node, error)
Update(rootNode *yaml.Node, remainingPath []string, changesToApply yaml.Node) error Update(rootNode *yaml.Node, path []string, changesToApply yaml.Node) error
Delete(rootNode *yaml.Node, path []string) error
} }
type navigator struct { type navigator struct {
@ -34,8 +35,8 @@ func (n *navigator) Get(value *yaml.Node, path []string) (*yaml.Node, error) {
return n.Visit(value, path, identityVisitor) return n.Visit(value, path, identityVisitor)
} }
func (n *navigator) Update(value *yaml.Node, path []string, changesToApply yaml.Node) error { func (n *navigator) Update(rootNode *yaml.Node, path []string, changesToApply yaml.Node) error {
_, errorVisiting := n.Visit(value, path, func(nodeToUpdate *yaml.Node) (*yaml.Node, error) { _, errorVisiting := n.Visit(rootNode, path, func(nodeToUpdate *yaml.Node) (*yaml.Node, error) {
n.log.Debug("going to update") n.log.Debug("going to update")
n.DebugNode(nodeToUpdate) n.DebugNode(nodeToUpdate)
n.log.Debug("with") n.log.Debug("with")
@ -53,6 +54,36 @@ func (n *navigator) Update(value *yaml.Node, path []string, changesToApply yaml.
return errorVisiting return errorVisiting
} }
func (n *navigator) Delete(rootNode *yaml.Node, path []string) error {
lastBit, newTail := path[len(path)-1], path[:len(path)-1]
n.log.Debug("splitting path, %v", lastBit)
n.log.Debug("new tail, %v", newTail)
_, errorVisiting := n.Visit(rootNode, newTail, func(nodeToUpdate *yaml.Node) (*yaml.Node, error) {
n.log.Debug("need to find %v in here", lastBit)
n.DebugNode(nodeToUpdate)
if nodeToUpdate.Kind == yaml.SequenceNode {
var index, err = strconv.ParseInt(lastBit, 10, 64) // nolint
if err != nil {
return nil, err
}
if index >= int64(len(nodeToUpdate.Content)) {
n.log.Debug("index %v is greater than content lenth %v", index, len(nodeToUpdate.Content))
return nodeToUpdate, nil
}
original := nodeToUpdate.Content
nodeToUpdate.Content = append(original[:index], original[index+1:]...)
} else if nodeToUpdate.Kind == yaml.MappingNode {
}
return nodeToUpdate, nil
})
return errorVisiting
}
func (n *navigator) Visit(value *yaml.Node, path []string, visitor VisitorFn) (*yaml.Node, error) { func (n *navigator) Visit(value *yaml.Node, path []string, visitor VisitorFn) (*yaml.Node, error) {
realValue := value realValue := value
if realValue.Kind == yaml.DocumentNode { if realValue.Kind == yaml.DocumentNode {

View File

@ -50,8 +50,8 @@ func (l *lib) Update(rootNode *yaml.Node, updateCommand UpdateCommand) error {
var paths = l.parser.ParsePath(updateCommand.Path) var paths = l.parser.ParsePath(updateCommand.Path)
return l.navigator.Update(rootNode, paths, updateCommand.Value) return l.navigator.Update(rootNode, paths, updateCommand.Value)
case "delete": case "delete":
l.log.Debugf("need to implement delete") var paths = l.parser.ParsePath(updateCommand.Path)
return nil return l.navigator.Delete(rootNode, paths)
default: default:
return fmt.Errorf("Unknown command %v", updateCommand.Command) return fmt.Errorf("Unknown command %v", updateCommand.Command)
} }

81
yq.go
View File

@ -77,7 +77,7 @@ func newCommandCLI() *cobra.Command {
createReadCmd(), createReadCmd(),
createWriteCmd(), createWriteCmd(),
// createPrefixCmd(), // createPrefixCmd(),
// createDeleteCmd(), createDeleteCmd(),
// createNewCmd(), // createNewCmd(),
// createMergeCmd(), // createMergeCmd(),
) )
@ -166,27 +166,27 @@ a.b.e:
// return cmdWrite // return cmdWrite
// } // }
// func createDeleteCmd() *cobra.Command { func createDeleteCmd() *cobra.Command {
// var cmdDelete = &cobra.Command{ var cmdDelete = &cobra.Command{
// Use: "delete [yaml_file] [path]", Use: "delete [yaml_file] [path]",
// Aliases: []string{"d"}, Aliases: []string{"d"},
// Short: "yq d [--inplace/-i] [--doc/-d index] sample.yaml a.b.c", Short: "yq d [--inplace/-i] [--doc/-d index] sample.yaml a.b.c",
// Example: ` Example: `
// yq delete things.yaml a.b.c yq delete things.yaml a.b.c
// yq delete --inplace things.yaml a.b.c yq delete --inplace things.yaml a.b.c
// yq delete --inplace -- things.yaml --key-starting-with-dash yq delete --inplace -- things.yaml --key-starting-with-dash
// yq d -i things.yaml a.b.c yq d -i things.yaml a.b.c
// yq d things.yaml a.b.c yq d things.yaml a.b.c
// `, `,
// Long: `Deletes the given path from the YAML file. Long: `Deletes the given path from the YAML file.
// Outputs to STDOUT unless the inplace flag is used, in which case the file is updated instead. Outputs to STDOUT unless the inplace flag is used, in which case the file is updated instead.
// `, `,
// RunE: deleteProperty, RunE: deleteProperty,
// } }
// cmdDelete.PersistentFlags().BoolVarP(&writeInplace, "inplace", "i", false, "update the yaml file inplace") cmdDelete.PersistentFlags().BoolVarP(&writeInplace, "inplace", "i", false, "update the yaml file inplace")
// cmdDelete.PersistentFlags().StringVarP(&docIndex, "doc", "d", "0", "process document index number (0 based, * for all documents)") cmdDelete.PersistentFlags().StringVarP(&docIndex, "doc", "d", "0", "process document index number (0 based, * for all documents)")
// return cmdDelete return cmdDelete
// } }
// func createNewCmd() *cobra.Command { // func createNewCmd() *cobra.Command {
// var cmdNew = &cobra.Command{ // var cmdNew = &cobra.Command{
@ -407,6 +407,20 @@ func writeProperty(cmd *cobra.Command, args []string) error {
if updateCommandsError != nil { if updateCommandsError != nil {
return updateCommandsError return updateCommandsError
} }
return updateDoc(args[0], updateCommands, cmd.OutOrStdout())
}
func deleteProperty(cmd *cobra.Command, args []string) error {
if len(args) < 2 {
return errors.New("Must provide <filename> <path_to_delete>")
}
var updateCommands []yqlib.UpdateCommand = make([]yqlib.UpdateCommand, 1)
updateCommands[0] = yqlib.UpdateCommand{Command: "delete", Path: args[1]}
return updateDoc(args[0], updateCommands, cmd.OutOrStdout())
}
func updateDoc(inputFile string, updateCommands []yqlib.UpdateCommand, writer io.Writer) error {
var updateAll, docIndexInt, errorParsingDocIndex = parseDocumentIndex() var updateAll, docIndexInt, errorParsingDocIndex = parseDocumentIndex()
if errorParsingDocIndex != nil { if errorParsingDocIndex != nil {
return errorParsingDocIndex return errorParsingDocIndex
@ -424,7 +438,7 @@ func writeProperty(cmd *cobra.Command, args []string) error {
} }
return nil return nil
} }
return readAndUpdate(cmd.OutOrStdout(), args[0], updateData) return readAndUpdate(writer, inputFile, updateData)
} }
// func prefixProperty(cmd *cobra.Command, args []string) error { // func prefixProperty(cmd *cobra.Command, args []string) error {
@ -484,27 +498,6 @@ func readAndUpdate(stdOut io.Writer, inputFile string, updateData updateDataFn)
return readStream(inputFile, mapYamlDecoder(updateData, encoder)) return readStream(inputFile, mapYamlDecoder(updateData, encoder))
} }
// func deleteProperty(cmd *cobra.Command, args []string) error {
// if len(args) < 2 {
// return errors.New("Must provide <filename> <path_to_delete>")
// }
// var deletePath = args[1]
// var updateAll, docIndexInt, errorParsingDocIndex = parseDocumentIndex()
// if errorParsingDocIndex != nil {
// return errorParsingDocIndex
// }
// var updateData = func(dataBucket interface{}, currentIndex int) (interface{}, error) {
// if updateAll || currentIndex == docIndexInt {
// log.Debugf("Deleting path in doc %v", currentIndex)
// return lib.DeletePath(dataBucket, deletePath)
// }
// return dataBucket, nil
// }
// return readAndUpdate(cmd.OutOrStdout(), args[0], updateData)
// }
// func mergeProperties(cmd *cobra.Command, args []string) error { // func mergeProperties(cmd *cobra.Command, args []string) error {
// if len(args) < 2 { // if len(args) < 2 {
// return errors.New("Must provide at least 2 yaml files") // return errors.New("Must provide at least 2 yaml files")