mirror of
https://github.com/mikefarah/yq.git
synced 2024-11-12 13:48:06 +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
|
// need to delete in reverse - otherwise the matching indexes
|
||||||
// become incorrect.
|
// become incorrect.
|
||||||
matchingIndices := make([]int, 0)
|
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)
|
matchingIndices = append(matchingIndices, indexInMap)
|
||||||
n.log.Debug("matchingIndices %v", indexInMap)
|
n.log.Debug("matchingIndices %v", indexInMap)
|
||||||
return nil
|
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.")
|
n.log.Debug("guess was an alias, okey doke.")
|
||||||
return guess
|
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
|
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 {
|
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(contents []*yaml.Node, indexInMap int) error {
|
||||||
value.Content[indexInMap+1] = n.getOrReplace(value.Content[indexInMap+1], n.GuessKind(tail, value.Content[indexInMap+1].Kind))
|
contents[indexInMap+1] = n.getOrReplace(contents[indexInMap+1], n.GuessKind(tail, contents[indexInMap+1].Kind))
|
||||||
return n.Visit(value.Content[indexInMap+1], tail, visitor)
|
return n.Visit(contents[indexInMap+1], tail, visitor)
|
||||||
})
|
})
|
||||||
|
|
||||||
if errorVisiting != nil {
|
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)
|
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) {
|
func (n *navigator) visitMatchingEntries(contents []*yaml.Node, key string, visit mapVisitorFn) (bool, error) {
|
||||||
visited := false
|
visited := false
|
||||||
|
n.log.Debug("visitMatchingEntries %v in %v", key, contents)
|
||||||
// value.Content is a concatenated array of key, value,
|
// value.Content is a concatenated array of key, value,
|
||||||
// so keys are in the even indexes, values in odd.
|
// 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]
|
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) {
|
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 {
|
if errorVisiting != nil {
|
||||||
return visited, errorVisiting
|
return visited, errorVisiting
|
||||||
}
|
}
|
||||||
|
63
yq.go
63
yq.go
@ -79,7 +79,7 @@ func newCommandCLI() *cobra.Command {
|
|||||||
createPrefixCmd(),
|
createPrefixCmd(),
|
||||||
createDeleteCmd(),
|
createDeleteCmd(),
|
||||||
createNewCmd(),
|
createNewCmd(),
|
||||||
// createMergeCmd(),
|
createMergeCmd(),
|
||||||
)
|
)
|
||||||
rootCmd.SetOutput(os.Stdout)
|
rootCmd.SetOutput(os.Stdout)
|
||||||
|
|
||||||
@ -211,36 +211,36 @@ Note that you can give a create script to perform more sophisticated yaml. This
|
|||||||
return cmdNew
|
return cmdNew
|
||||||
}
|
}
|
||||||
|
|
||||||
// func createMergeCmd() *cobra.Command {
|
func createMergeCmd() *cobra.Command {
|
||||||
// var cmdMerge = &cobra.Command{
|
var cmdMerge = &cobra.Command{
|
||||||
// Use: "merge [initial_yaml_file] [additional_yaml_file]...",
|
Use: "merge [initial_yaml_file] [additional_yaml_file]...",
|
||||||
// Aliases: []string{"m"},
|
Aliases: []string{"m"},
|
||||||
// Short: "yq m [--inplace/-i] [--doc/-d index] [--overwrite/-x] [--append/-a] sample.yaml sample2.yaml",
|
Short: "yq m [--inplace/-i] [--doc/-d index] [--overwrite/-x] [--append/-a] sample.yaml sample2.yaml",
|
||||||
// Example: `
|
Example: `
|
||||||
// yq merge things.yaml other.yaml
|
yq merge things.yaml other.yaml
|
||||||
// yq merge --inplace things.yaml other.yaml
|
yq merge --inplace things.yaml other.yaml
|
||||||
// yq m -i things.yaml other.yaml
|
yq m -i things.yaml other.yaml
|
||||||
// yq m --overwrite things.yaml other.yaml
|
yq m --overwrite things.yaml other.yaml
|
||||||
// yq m -i -x things.yaml other.yaml
|
yq m -i -x things.yaml other.yaml
|
||||||
// yq m -i -a 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).
|
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.
|
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 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 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.
|
Note that if you set both flags only overwrite will take effect.
|
||||||
// `,
|
`,
|
||||||
// RunE: mergeProperties,
|
RunE: mergeProperties,
|
||||||
// }
|
}
|
||||||
// cmdMerge.PersistentFlags().BoolVarP(&writeInplace, "inplace", "i", false, "update the yaml file inplace")
|
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(&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(&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().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)")
|
cmdMerge.PersistentFlags().StringVarP(&docIndex, "doc", "d", "0", "process document index number (0 based, * for all documents)")
|
||||||
// return cmdMerge
|
return cmdMerge
|
||||||
// }
|
}
|
||||||
|
|
||||||
func readProperty(cmd *cobra.Command, args []string) error {
|
func readProperty(cmd *cobra.Command, args []string) error {
|
||||||
var path = ""
|
var path = ""
|
||||||
@ -397,6 +397,11 @@ func writeProperty(cmd *cobra.Command, args []string) error {
|
|||||||
return updateDoc(args[0], updateCommands, cmd.OutOrStdout())
|
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 {
|
func newProperty(cmd *cobra.Command, args []string) error {
|
||||||
var updateCommands, updateCommandsError = readUpdateCommands(args, 2, "Must provide <path_to_update> <value>")
|
var updateCommands, updateCommandsError = readUpdateCommands(args, 2, "Must provide <path_to_update> <value>")
|
||||||
if updateCommandsError != nil {
|
if updateCommandsError != nil {
|
||||||
|
Loading…
Reference in New Issue
Block a user