1
0
mirror of https://github.com/taigrr/yq synced 2025-01-18 04:53:17 -08:00

refactored array merge flags into a strategy

This commit is contained in:
Mike Farah
2020-07-17 13:26:20 +10:00
parent 2fc39b3865
commit d66a709213
7 changed files with 48 additions and 30 deletions

View File

@@ -26,8 +26,7 @@ var defaultValue = ""
var indent = 2
var overwriteFlag = false
var autoCreateFlag = true
var appendFlag = false
var overwriteArrays = false
var arrayMergeStrategyFlag = "update"
var verbose = false
var version = false
var docIndex = "0"

View File

@@ -11,14 +11,14 @@ 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",
Short: "yq m [--inplace/-i] [--doc/-d index] [--overwrite/-x] [--arrayMerge/-a strategy] 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
yq m -i -a=append things.yaml other.yaml
yq m -i --autocreate=false things.yaml other.yaml
`,
Long: `Updates the yaml file by adding/updating the path(s) and value(s) from additional yaml file(s).
@@ -32,9 +32,8 @@ If append flag is set then existing arrays will be merged with the arrays from e
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(&autoCreateFlag, "autocreate", "c", true, "automatically create any missing entries")
cmdMerge.PersistentFlags().BoolVarP(&appendFlag, "append", "a", false, "update the yaml file by appending array values")
cmdMerge.PersistentFlags().StringVarP(&arrayMergeStrategyFlag, "array", "a", "update", "array merge strategy (update/append/overwrite)")
cmdMerge.PersistentFlags().StringVarP(&docIndex, "doc", "d", "0", "process document index number (0 based, * for all documents)")
cmdMerge.PersistentFlags().BoolVarP(&overwriteArrays, "overwriteArrays", "", false, "overwrite arrays rather than update recursively")
return cmdMerge
}
@@ -42,9 +41,9 @@ If append flag is set then existing arrays will be merged with the arrays from e
* We don't deeply traverse arrays when appending a merge, instead we want to
* append the entire array element.
*/
func createReadFunctionForMerge() func(*yaml.Node) ([]*yqlib.NodeContext, error) {
func createReadFunctionForMerge(arrayMergeStrategy yqlib.ArrayMergeStrategy) func(*yaml.Node) ([]*yqlib.NodeContext, error) {
return func(dataBucket *yaml.Node) ([]*yqlib.NodeContext, error) {
return lib.GetForMerge(dataBucket, "**", !appendFlag, overwriteArrays)
return lib.GetForMerge(dataBucket, "**", arrayMergeStrategy)
}
}
@@ -54,13 +53,25 @@ func mergeProperties(cmd *cobra.Command, args []string) error {
if len(args) < 1 {
return errors.New("Must provide at least 1 yaml file")
}
var arrayMergeStrategy yqlib.ArrayMergeStrategy
switch arrayMergeStrategyFlag {
case "update":
arrayMergeStrategy = yqlib.UpdateArrayMergeStrategy
case "append":
arrayMergeStrategy = yqlib.AppendArrayMergeStrategy
case "overwrite":
arrayMergeStrategy = yqlib.OverwriteArrayMergeStrategy
default:
return errors.New("Array merge strategy must be one of: update/append/overwrite")
}
if len(args) > 1 {
// first generate update commands from the file
var filesToMerge = args[1:]
for _, fileToMerge := range filesToMerge {
matchingNodes, errorProcessingFile := doReadYamlFile(fileToMerge, createReadFunctionForMerge(), false, 0)
matchingNodes, errorProcessingFile := doReadYamlFile(fileToMerge, createReadFunctionForMerge(arrayMergeStrategy), false, 0)
if errorProcessingFile != nil {
return errorProcessingFile
}
@@ -70,14 +81,14 @@ func mergeProperties(cmd *cobra.Command, args []string) error {
yqlib.DebugNode(matchingNode.Node)
}
for _, matchingNode := range matchingNodes {
mergePath := lib.MergePathStackToString(matchingNode.PathStack, appendFlag)
mergePath := lib.MergePathStackToString(matchingNode.PathStack, arrayMergeStrategy)
updateCommands = append(updateCommands, yqlib.UpdateCommand{
Command: "merge",
Path: mergePath,
Value: matchingNode.Node,
Overwrite: overwriteFlag,
// dont update the content for nodes midway, only leaf nodes
DontUpdateNodeContent: matchingNode.IsMiddleNode && (!overwriteArrays || matchingNode.Node.Kind != yaml.SequenceNode),
DontUpdateNodeContent: matchingNode.IsMiddleNode && (arrayMergeStrategy != yqlib.OverwriteArrayMergeStrategy || matchingNode.Node.Kind != yaml.SequenceNode),
})
}
}

View File

@@ -97,7 +97,7 @@ func TestMergeOverwriteDeepExampleCmd(t *testing.T) {
func TestMergeAppendCmd(t *testing.T) {
cmd := getRootCommand()
result := test.RunCmd(cmd, "merge --autocreate=false --append ../examples/data1.yaml ../examples/data2.yaml")
result := test.RunCmd(cmd, "merge --autocreate=false --array=append ../examples/data1.yaml ../examples/data2.yaml")
if result.Error != nil {
t.Error(result.Error)
}
@@ -123,7 +123,7 @@ func TestMergeAppendArraysCmd(t *testing.T) {
defer test.RemoveTempYamlFile(mergeFilename)
cmd := getRootCommand()
result := test.RunCmd(cmd, fmt.Sprintf("merge --append -d* %s %s", filename, mergeFilename))
result := test.RunCmd(cmd, fmt.Sprintf("merge --array=append -d* %s %s", filename, mergeFilename))
if result.Error != nil {
t.Error(result.Error)
}
@@ -181,7 +181,7 @@ usage:
func TestMergeOverwriteAndAppendCmd(t *testing.T) {
cmd := getRootCommand()
result := test.RunCmd(cmd, "merge --autocreate=false --append --overwrite ../examples/data1.yaml ../examples/data2.yaml")
result := test.RunCmd(cmd, "merge --autocreate=false --array=append --overwrite ../examples/data1.yaml ../examples/data2.yaml")
if result.Error != nil {
t.Error(result.Error)
}
@@ -208,7 +208,7 @@ b: [6]`
defer test.RemoveTempYamlFile(mergeFilename)
cmd := getRootCommand()
result := test.RunCmd(cmd, fmt.Sprintf("merge --autocreate=false --overwriteArrays --overwrite %s %s", filename, mergeFilename))
result := test.RunCmd(cmd, fmt.Sprintf("merge --autocreate=false --array=overwrite --overwrite %s %s", filename, mergeFilename))
if result.Error != nil {
t.Error(result.Error)
}
@@ -223,7 +223,7 @@ c:
func TestMergeRootArraysCmd(t *testing.T) {
cmd := getRootCommand()
result := test.RunCmd(cmd, "merge --append ../examples/sample_array.yaml ../examples/sample_array_2.yaml")
result := test.RunCmd(cmd, "merge --array=append ../examples/sample_array.yaml ../examples/sample_array_2.yaml")
if result.Error != nil {
t.Error(result.Error)
}
@@ -238,7 +238,7 @@ func TestMergeRootArraysCmd(t *testing.T) {
func TestMergeOverwriteArraysCmd(t *testing.T) {
cmd := getRootCommand()
result := test.RunCmd(cmd, "merge --overwriteArrays ../examples/sample_array.yaml ../examples/sample_array_2.yaml")
result := test.RunCmd(cmd, "merge --array=overwrite ../examples/sample_array.yaml ../examples/sample_array_2.yaml")
if result.Error != nil {
t.Error(result.Error)
}