mirror of
https://github.com/mikefarah/yq.git
synced 2025-01-27 00:47:56 +00:00
wip - new node
This commit is contained in:
parent
2344638da4
commit
b81fd638d7
@ -14,6 +14,7 @@ type DataNavigator interface {
|
|||||||
Get(rootNode *yaml.Node, path []string) (*yaml.Node, error)
|
Get(rootNode *yaml.Node, path []string) (*yaml.Node, error)
|
||||||
Update(rootNode *yaml.Node, path []string, changesToApply yaml.Node) error
|
Update(rootNode *yaml.Node, path []string, changesToApply yaml.Node) error
|
||||||
Delete(rootNode *yaml.Node, path []string) error
|
Delete(rootNode *yaml.Node, path []string) error
|
||||||
|
GuessKind(tail []string, guess yaml.Kind) yaml.Kind
|
||||||
}
|
}
|
||||||
|
|
||||||
type navigator struct {
|
type navigator struct {
|
||||||
@ -68,6 +69,7 @@ func (n *navigator) Update(rootNode *yaml.Node, path []string, changesToApply ya
|
|||||||
return errorVisiting
|
return errorVisiting
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: refactor delete..
|
||||||
func (n *navigator) Delete(rootNode *yaml.Node, path []string) error {
|
func (n *navigator) Delete(rootNode *yaml.Node, path []string) error {
|
||||||
|
|
||||||
lastBit, newTail := path[len(path)-1], path[:len(path)-1]
|
lastBit, newTail := path[len(path)-1], path[:len(path)-1]
|
||||||
@ -129,7 +131,7 @@ func (n *navigator) Visit(value *yaml.Node, path []string, visitor VisitorFn) er
|
|||||||
return visitor(realValue)
|
return visitor(realValue)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *navigator) guessKind(tail []string, guess yaml.Kind) yaml.Kind {
|
func (n *navigator) GuessKind(tail []string, guess yaml.Kind) yaml.Kind {
|
||||||
n.log.Debug("tail %v", tail)
|
n.log.Debug("tail %v", tail)
|
||||||
if len(tail) == 0 && guess == 0 {
|
if len(tail) == 0 && guess == 0 {
|
||||||
n.log.Debug("end of path, must be a scalar")
|
n.log.Debug("end of path, must be a scalar")
|
||||||
@ -195,7 +197,7 @@ func (n *navigator) splatMap(value *yaml.Node, tail []string, visitor VisitorFn)
|
|||||||
if index%2 == 0 {
|
if index%2 == 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
content = n.getOrReplace(content, n.guessKind(tail, content.Kind))
|
content = n.getOrReplace(content, n.GuessKind(tail, content.Kind))
|
||||||
var err = n.Visit(content, tail, visitor)
|
var err = n.Visit(content, tail, visitor)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -206,7 +208,7 @@ func (n *navigator) splatMap(value *yaml.Node, tail []string, visitor VisitorFn)
|
|||||||
|
|
||||||
func (n *navigator) recurseMap(value *yaml.Node, head string, tail []string, visitor VisitorFn) error {
|
func (n *navigator) recurseMap(value *yaml.Node, head string, tail []string, visitor VisitorFn) error {
|
||||||
visited, errorVisiting := n.visitMatchingEntries(value.Content, head, func(indexInMap int) error {
|
visited, errorVisiting := n.visitMatchingEntries(value.Content, head, func(indexInMap int) error {
|
||||||
value.Content[indexInMap+1] = n.getOrReplace(value.Content[indexInMap+1], n.guessKind(tail, value.Content[indexInMap+1].Kind))
|
value.Content[indexInMap+1] = n.getOrReplace(value.Content[indexInMap+1], n.GuessKind(tail, value.Content[indexInMap+1].Kind))
|
||||||
return n.Visit(value.Content[indexInMap+1], tail, visitor)
|
return n.Visit(value.Content[indexInMap+1], tail, visitor)
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -220,7 +222,7 @@ func (n *navigator) recurseMap(value *yaml.Node, head string, tail []string, vis
|
|||||||
|
|
||||||
//didn't find it, lets add it.
|
//didn't find it, lets add it.
|
||||||
value.Content = append(value.Content, &yaml.Node{Value: head, Kind: yaml.ScalarNode})
|
value.Content = append(value.Content, &yaml.Node{Value: head, Kind: yaml.ScalarNode})
|
||||||
mapEntryValue := yaml.Node{Kind: n.guessKind(tail, 0)}
|
mapEntryValue := yaml.Node{Kind: n.GuessKind(tail, 0)}
|
||||||
value.Content = append(value.Content, &mapEntryValue)
|
value.Content = append(value.Content, &mapEntryValue)
|
||||||
n.log.Debug("adding new node %v", value.Content)
|
n.log.Debug("adding new node %v", value.Content)
|
||||||
return n.Visit(&mapEntryValue, tail, visitor)
|
return n.Visit(&mapEntryValue, tail, visitor)
|
||||||
@ -259,7 +261,7 @@ func (n *navigator) splatArray(value *yaml.Node, tail []string, visitor VisitorF
|
|||||||
for _, childValue := range value.Content {
|
for _, childValue := range value.Content {
|
||||||
n.log.Debug("processing")
|
n.log.Debug("processing")
|
||||||
n.DebugNode(childValue)
|
n.DebugNode(childValue)
|
||||||
childValue = n.getOrReplace(childValue, n.guessKind(tail, childValue.Kind))
|
childValue = n.getOrReplace(childValue, n.GuessKind(tail, childValue.Kind))
|
||||||
var err = n.Visit(childValue, tail, visitor)
|
var err = n.Visit(childValue, tail, visitor)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -269,7 +271,7 @@ func (n *navigator) splatArray(value *yaml.Node, tail []string, visitor VisitorF
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (n *navigator) appendArray(value *yaml.Node, tail []string, visitor VisitorFn) error {
|
func (n *navigator) appendArray(value *yaml.Node, tail []string, visitor VisitorFn) error {
|
||||||
var newNode = yaml.Node{Kind: n.guessKind(tail, 0)}
|
var newNode = yaml.Node{Kind: n.GuessKind(tail, 0)}
|
||||||
value.Content = append(value.Content, &newNode)
|
value.Content = append(value.Content, &newNode)
|
||||||
n.log.Debug("appending a new node, %v", value.Content)
|
n.log.Debug("appending a new node, %v", value.Content)
|
||||||
return n.Visit(&newNode, tail, visitor)
|
return n.Visit(&newNode, tail, visitor)
|
||||||
@ -283,7 +285,7 @@ func (n *navigator) recurseArray(value *yaml.Node, head string, tail []string, v
|
|||||||
if index >= int64(len(value.Content)) {
|
if index >= int64(len(value.Content)) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
value.Content[index] = n.getOrReplace(value.Content[index], n.guessKind(tail, value.Content[index].Kind))
|
value.Content[index] = n.getOrReplace(value.Content[index], n.GuessKind(tail, value.Content[index].Kind))
|
||||||
return n.Visit(value.Content[index], tail, visitor)
|
return n.Visit(value.Content[index], tail, visitor)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,6 +17,7 @@ type YqLib interface {
|
|||||||
DebugNode(node *yaml.Node)
|
DebugNode(node *yaml.Node)
|
||||||
Get(rootNode *yaml.Node, path string) (*yaml.Node, error)
|
Get(rootNode *yaml.Node, path string) (*yaml.Node, error)
|
||||||
Update(rootNode *yaml.Node, updateCommand UpdateCommand) error
|
Update(rootNode *yaml.Node, updateCommand UpdateCommand) error
|
||||||
|
New(updateCommand UpdateCommand) (yaml.Node, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type lib struct {
|
type lib struct {
|
||||||
@ -42,6 +43,16 @@ func (l *lib) Get(rootNode *yaml.Node, path string) (*yaml.Node, error) {
|
|||||||
return l.navigator.Get(rootNode, paths)
|
return l.navigator.Get(rootNode, paths)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (l *lib) New(updateCommand UpdateCommand) (yaml.Node, error) {
|
||||||
|
var paths = l.parser.ParsePath(updateCommand.Path)
|
||||||
|
newNode := yaml.Node{Kind: l.navigator.GuessKind(paths, 0)}
|
||||||
|
errorUpdating := l.navigator.Update(&newNode, paths, updateCommand.Value)
|
||||||
|
if errorUpdating != nil {
|
||||||
|
return newNode, errorUpdating
|
||||||
|
}
|
||||||
|
return newNode, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (l *lib) Update(rootNode *yaml.Node, updateCommand UpdateCommand) error {
|
func (l *lib) Update(rootNode *yaml.Node, updateCommand UpdateCommand) error {
|
||||||
// later - support other command types
|
// later - support other command types
|
||||||
l.log.Debugf("%v to %v", updateCommand.Command, updateCommand.Path)
|
l.log.Debugf("%v to %v", updateCommand.Command, updateCommand.Path)
|
||||||
|
75
yq.go
75
yq.go
@ -78,7 +78,7 @@ func newCommandCLI() *cobra.Command {
|
|||||||
createWriteCmd(),
|
createWriteCmd(),
|
||||||
// createPrefixCmd(),
|
// createPrefixCmd(),
|
||||||
createDeleteCmd(),
|
createDeleteCmd(),
|
||||||
// createNewCmd(),
|
createNewCmd(),
|
||||||
// createMergeCmd(),
|
// createMergeCmd(),
|
||||||
)
|
)
|
||||||
rootCmd.SetOutput(os.Stdout)
|
rootCmd.SetOutput(os.Stdout)
|
||||||
@ -188,28 +188,28 @@ Outputs to STDOUT unless the inplace flag is used, in which case the file is upd
|
|||||||
return cmdDelete
|
return cmdDelete
|
||||||
}
|
}
|
||||||
|
|
||||||
// func createNewCmd() *cobra.Command {
|
func createNewCmd() *cobra.Command {
|
||||||
// var cmdNew = &cobra.Command{
|
var cmdNew = &cobra.Command{
|
||||||
// Use: "new [path] [value]",
|
Use: "new [path] [value]",
|
||||||
// Aliases: []string{"n"},
|
Aliases: []string{"n"},
|
||||||
// Short: "yq n [--script/-s script_file] a.b.c newValue",
|
Short: "yq n [--script/-s script_file] a.b.c newValue",
|
||||||
// Example: `
|
Example: `
|
||||||
// yq new a.b.c cat
|
yq new a.b.c cat
|
||||||
// yq n a.b.c cat
|
yq n a.b.c cat
|
||||||
// yq n -- --key-starting-with-dash cat
|
yq n -- --key-starting-with-dash cat
|
||||||
// yq n --script create_script.yaml
|
yq n --script create_script.yaml
|
||||||
// `,
|
`,
|
||||||
// Long: `Creates a new yaml w.r.t the given path and value.
|
Long: `Creates a new yaml w.r.t the given path and value.
|
||||||
// Outputs to STDOUT
|
Outputs to STDOUT
|
||||||
|
|
||||||
// Create Scripts:
|
Create Scripts:
|
||||||
// Note that you can give a create script to perform more sophisticated yaml. This follows the same format as the update script.
|
Note that you can give a create script to perform more sophisticated yaml. This follows the same format as the update script.
|
||||||
// `,
|
`,
|
||||||
// RunE: newProperty,
|
RunE: newProperty,
|
||||||
// }
|
}
|
||||||
// cmdNew.PersistentFlags().StringVarP(&writeScript, "script", "s", "", "yaml script for updating yaml")
|
cmdNew.PersistentFlags().StringVarP(&writeScript, "script", "s", "", "yaml script for updating yaml")
|
||||||
// return cmdNew
|
return cmdNew
|
||||||
// }
|
}
|
||||||
|
|
||||||
// func createMergeCmd() *cobra.Command {
|
// func createMergeCmd() *cobra.Command {
|
||||||
// var cmdMerge = &cobra.Command{
|
// var cmdMerge = &cobra.Command{
|
||||||
@ -417,6 +417,34 @@ func writeProperty(cmd *cobra.Command, args []string) error {
|
|||||||
return updateDoc(args[0], updateCommands, cmd.OutOrStdout())
|
return updateDoc(args[0], updateCommands, cmd.OutOrStdout())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func newProperty(cmd *cobra.Command, args []string) error {
|
||||||
|
var updateCommands, updateCommandsError = readUpdateCommands(args, 2, "Must provide <filename> <path_to_update> <value>")
|
||||||
|
if updateCommandsError != nil {
|
||||||
|
return updateCommandsError
|
||||||
|
}
|
||||||
|
firstCommand, restOfCommands := updateCommands[0], updateCommands[1:]
|
||||||
|
newNode, errorCreating := lib.New(firstCommand)
|
||||||
|
if errorCreating != nil {
|
||||||
|
return errorCreating
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, updateCommand := range restOfCommands {
|
||||||
|
|
||||||
|
errorUpdating := lib.Update(&newNode, updateCommand)
|
||||||
|
|
||||||
|
if errorUpdating != nil {
|
||||||
|
return errorUpdating
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var encoder = yaml.NewEncoder(cmd.OutOrStdout())
|
||||||
|
encoder.SetIndent(2)
|
||||||
|
encoder.Encode(&newNode)
|
||||||
|
encoder.Close()
|
||||||
|
return nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
func deleteProperty(cmd *cobra.Command, args []string) error {
|
func deleteProperty(cmd *cobra.Command, args []string) error {
|
||||||
if len(args) < 2 {
|
if len(args) < 2 {
|
||||||
return errors.New("Must provide <filename> <path_to_delete>")
|
return errors.New("Must provide <filename> <path_to_delete>")
|
||||||
@ -558,6 +586,9 @@ func readUpdateCommands(args []string, expectedArgs int, badArgsMessage string)
|
|||||||
return nil, errors.New(badArgsMessage)
|
return nil, errors.New(badArgsMessage)
|
||||||
} else {
|
} else {
|
||||||
updateCommands = make([]yqlib.UpdateCommand, 1)
|
updateCommands = make([]yqlib.UpdateCommand, 1)
|
||||||
|
log.Debug("args %v", args)
|
||||||
|
log.Debug("path %v", args[expectedArgs-2])
|
||||||
|
log.Debug("Value %v", args[expectedArgs-1])
|
||||||
updateCommands[0] = yqlib.UpdateCommand{Command: "update", Path: args[expectedArgs-2], Value: parseValue(args[expectedArgs-1])}
|
updateCommands[0] = yqlib.UpdateCommand{Command: "update", Path: args[expectedArgs-2], Value: parseValue(args[expectedArgs-1])}
|
||||||
}
|
}
|
||||||
return updateCommands, nil
|
return updateCommands, nil
|
||||||
|
Loading…
Reference in New Issue
Block a user