mirror of
https://github.com/mikefarah/yq.git
synced 2025-01-12 19:25:37 +00:00
Aliases!
This commit is contained in:
parent
290579ac7f
commit
19fe718cfb
17
examples/merge-anchor.yml
Normal file
17
examples/merge-anchor.yml
Normal file
@ -0,0 +1,17 @@
|
||||
foo: &foo
|
||||
a: original
|
||||
thing: coolasdf
|
||||
|
||||
bar: &bar
|
||||
b: 2
|
||||
|
||||
|
||||
overrideA:
|
||||
<<: [*foo,*bar]
|
||||
a: vanilla
|
||||
c: 3
|
||||
|
||||
foobar:
|
||||
<<: *foo
|
||||
thing: ice
|
||||
c: 3
|
@ -96,7 +96,7 @@ func (n *navigator) Delete(rootNode *yaml.Node, path []string) error {
|
||||
// need to delete in reverse - otherwise the matching indexes
|
||||
// become incorrect.
|
||||
matchingIndices := make([]int, 0)
|
||||
_, errorVisiting := n.visitMatchingEntries(nodeToUpdate.Content, lastBit, func(indexInMap int) error {
|
||||
_, errorVisiting := n.visitMatchingEntries(nodeToUpdate.Content, lastBit, func(matchingNode []*yaml.Node, indexInMap int) error {
|
||||
matchingIndices = append(matchingIndices, indexInMap)
|
||||
n.log.Debug("matchingIndices %v", indexInMap)
|
||||
return nil
|
||||
@ -153,6 +153,9 @@ func (n *navigator) GuessKind(tail []string, guess yaml.Kind) yaml.Kind {
|
||||
n.log.Debug("guess was an alias, okey doke.")
|
||||
return guess
|
||||
}
|
||||
n.log.Debug("forcing a mapping node")
|
||||
n.log.Debug("yaml.SequenceNode ?", guess == yaml.SequenceNode)
|
||||
n.log.Debug("yaml.ScalarNode ?", guess == yaml.ScalarNode)
|
||||
return yaml.MappingNode
|
||||
}
|
||||
|
||||
@ -221,9 +224,9 @@ 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 {
|
||||
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))
|
||||
return n.Visit(value.Content[indexInMap+1], tail, visitor)
|
||||
visited, errorVisiting := n.visitMatchingEntries(value.Content, head, func(contents []*yaml.Node, indexInMap int) error {
|
||||
contents[indexInMap+1] = n.getOrReplace(contents[indexInMap+1], n.GuessKind(tail, contents[indexInMap+1].Kind))
|
||||
return n.Visit(contents[indexInMap+1], tail, visitor)
|
||||
})
|
||||
|
||||
if errorVisiting != nil {
|
||||
@ -242,18 +245,36 @@ func (n *navigator) recurseMap(value *yaml.Node, head string, tail []string, vis
|
||||
return n.Visit(&mapEntryValue, tail, visitor)
|
||||
}
|
||||
|
||||
type mapVisitorFn func(int) error
|
||||
// need to pass the node in, as it may be aliased
|
||||
type mapVisitorFn func([]*yaml.Node, int) error
|
||||
|
||||
func (n *navigator) visitMatchingEntries(contents []*yaml.Node, key string, visit mapVisitorFn) (bool, error) {
|
||||
visited := false
|
||||
|
||||
n.log.Debug("visitMatchingEntries %v in %v", key, contents)
|
||||
// value.Content is a concatenated array of key, value,
|
||||
// so keys are in the even indexes, values in odd.
|
||||
for index := 0; index < len(contents); index = index + 2 {
|
||||
// merge aliases are defined first, but we only want to traverse them
|
||||
// if we dont find a match on this node first.
|
||||
for index := len(contents) - 2; index >= 0; index = index - 2 {
|
||||
content := contents[index]
|
||||
n.log.Debug("index %v, checking %v", index, content.Value))
|
||||
n.log.Debug("index %v, checking %v, %v", index, content.Value, content.Tag)
|
||||
|
||||
// only visit aliases if we didn't find a match in this object.
|
||||
if n.followAliases && !visited && contents[index+1].Kind == yaml.AliasNode {
|
||||
valueNode := contents[index+1]
|
||||
|
||||
n.log.Debug("need to visit the alias too")
|
||||
n.DebugNode(valueNode)
|
||||
visitedAlias, errorInAlias := n.visitMatchingEntries(valueNode.Alias.Content, key, visit)
|
||||
if errorInAlias != nil {
|
||||
return false, errorInAlias
|
||||
}
|
||||
visited = visited || visitedAlias
|
||||
}
|
||||
|
||||
if n.matchesKey(key, content.Value) {
|
||||
errorVisiting := visit(index)
|
||||
n.log.Debug("found a match! %v", content.Value)
|
||||
errorVisiting := visit(contents, index)
|
||||
if errorVisiting != nil {
|
||||
return visited, errorVisiting
|
||||
}
|
||||
|
63
yq.go
63
yq.go
@ -79,7 +79,7 @@ func newCommandCLI() *cobra.Command {
|
||||
createPrefixCmd(),
|
||||
createDeleteCmd(),
|
||||
createNewCmd(),
|
||||
// createMergeCmd(),
|
||||
createMergeCmd(),
|
||||
)
|
||||
rootCmd.SetOutput(os.Stdout)
|
||||
|
||||
@ -211,36 +211,36 @@ Note that you can give a create script to perform more sophisticated yaml. This
|
||||
return cmdNew
|
||||
}
|
||||
|
||||
// func createMergeCmd() *cobra.Command {
|
||||
// var cmdMerge = &cobra.Command{
|
||||
// Use: "merge [initial_yaml_file] [additional_yaml_file]...",
|
||||
// Aliases: []string{"m"},
|
||||
// Short: "yq m [--inplace/-i] [--doc/-d index] [--overwrite/-x] [--append/-a] sample.yaml sample2.yaml",
|
||||
// Example: `
|
||||
// yq merge things.yaml other.yaml
|
||||
// yq merge --inplace things.yaml other.yaml
|
||||
// yq m -i things.yaml other.yaml
|
||||
// yq m --overwrite things.yaml other.yaml
|
||||
// yq m -i -x things.yaml other.yaml
|
||||
// yq m -i -a things.yaml other.yaml
|
||||
// `,
|
||||
// Long: `Updates the yaml file by adding/updating the path(s) and value(s) from additional yaml file(s).
|
||||
// Outputs to STDOUT unless the inplace flag is used, in which case the file is updated instead.
|
||||
func createMergeCmd() *cobra.Command {
|
||||
var cmdMerge = &cobra.Command{
|
||||
Use: "merge [initial_yaml_file] [additional_yaml_file]...",
|
||||
Aliases: []string{"m"},
|
||||
Short: "yq m [--inplace/-i] [--doc/-d index] [--overwrite/-x] [--append/-a] sample.yaml sample2.yaml",
|
||||
Example: `
|
||||
yq merge things.yaml other.yaml
|
||||
yq merge --inplace things.yaml other.yaml
|
||||
yq m -i things.yaml other.yaml
|
||||
yq m --overwrite things.yaml other.yaml
|
||||
yq m -i -x things.yaml other.yaml
|
||||
yq m -i -a things.yaml other.yaml
|
||||
`,
|
||||
Long: `Updates the yaml file by adding/updating the path(s) and value(s) from additional yaml file(s).
|
||||
Outputs to STDOUT unless the inplace flag is used, in which case the file is updated instead.
|
||||
|
||||
// If overwrite flag is set then existing values will be overwritten using the values from each additional yaml file.
|
||||
// If append flag is set then existing arrays will be merged with the arrays from each additional yaml file.
|
||||
If overwrite flag is set then existing values will be overwritten using the values from each additional yaml file.
|
||||
If append flag is set then existing arrays will be merged with the arrays from each additional yaml file.
|
||||
|
||||
// Note that if you set both flags only overwrite will take effect.
|
||||
// `,
|
||||
// RunE: mergeProperties,
|
||||
// }
|
||||
// cmdMerge.PersistentFlags().BoolVarP(&writeInplace, "inplace", "i", false, "update the yaml file inplace")
|
||||
// cmdMerge.PersistentFlags().BoolVarP(&overwriteFlag, "overwrite", "x", false, "update the yaml file by overwriting existing values")
|
||||
// cmdMerge.PersistentFlags().BoolVarP(&appendFlag, "append", "a", false, "update the yaml file by appending array values")
|
||||
// cmdMerge.PersistentFlags().BoolVarP(&allowEmptyFlag, "allow-empty", "e", false, "allow empty yaml files")
|
||||
// cmdMerge.PersistentFlags().StringVarP(&docIndex, "doc", "d", "0", "process document index number (0 based, * for all documents)")
|
||||
// return cmdMerge
|
||||
// }
|
||||
Note that if you set both flags only overwrite will take effect.
|
||||
`,
|
||||
RunE: mergeProperties,
|
||||
}
|
||||
cmdMerge.PersistentFlags().BoolVarP(&writeInplace, "inplace", "i", false, "update the yaml file inplace")
|
||||
// cmdMerge.PersistentFlags().BoolVarP(&overwriteFlag, "overwrite", "x", false, "update the yaml file by overwriting existing values")
|
||||
// cmdMerge.PersistentFlags().BoolVarP(&appendFlag, "append", "a", false, "update the yaml file by appending array values")
|
||||
// cmdMerge.PersistentFlags().BoolVarP(&allowEmptyFlag, "allow-empty", "e", false, "allow empty yaml files")
|
||||
cmdMerge.PersistentFlags().StringVarP(&docIndex, "doc", "d", "0", "process document index number (0 based, * for all documents)")
|
||||
return cmdMerge
|
||||
}
|
||||
|
||||
func readProperty(cmd *cobra.Command, args []string) error {
|
||||
var path = ""
|
||||
@ -397,6 +397,11 @@ func writeProperty(cmd *cobra.Command, args []string) error {
|
||||
return updateDoc(args[0], updateCommands, cmd.OutOrStdout())
|
||||
}
|
||||
|
||||
func mergeProperties(cmd *cobra.Command, args []string) error {
|
||||
// first generate update commands from the file
|
||||
return nil
|
||||
}
|
||||
|
||||
func newProperty(cmd *cobra.Command, args []string) error {
|
||||
var updateCommands, updateCommandsError = readUpdateCommands(args, 2, "Must provide <path_to_update> <value>")
|
||||
if updateCommandsError != nil {
|
||||
|
Loading…
Reference in New Issue
Block a user