diff --git a/commands_test.go b/commands_test.go index 90409cb8..7b547650 100644 --- a/commands_test.go +++ b/commands_test.go @@ -1091,6 +1091,25 @@ c: ` test.AssertResult(t, expectedOutput, result.Output) } + +func TestMergeOverwriteAndAppendCmd(t *testing.T) { + cmd := getRootCommand() + result := test.RunCmd(cmd, "merge --append --overwrite examples/data1.yaml examples/data2.yaml") + if result.Error != nil { + t.Error(result.Error) + } + expectedOutput := `a: other +b: +- 1 +- 2 +- 3 +- 4 +c: + test: 1 +` + test.AssertResult(t, expectedOutput, result.Output) +} + func TestMergeArraysCmd(t *testing.T) { cmd := getRootCommand() result := test.RunCmd(cmd, "merge --append examples/sample_array.yaml examples/sample_array_2.yaml") diff --git a/pkg/yqlib/lib.go b/pkg/yqlib/lib.go index 8d330063..f61c37a2 100644 --- a/pkg/yqlib/lib.go +++ b/pkg/yqlib/lib.go @@ -58,11 +58,13 @@ func (l *lib) DeletePath(dataBucket interface{}, path string) (interface{}, erro return l.navigator.DeleteChildValue(dataBucket, paths) } -func (l *lib) Merge(dst interface{}, src interface{}, overwrite bool, append bool) error { - if overwrite { - return mergo.Merge(dst, src, mergo.WithOverride) - } else if append { - return mergo.Merge(dst, src, mergo.WithAppendSlice) +func (l *lib) Merge(dst interface{}, src interface{}, overwriteFlag bool, appendFlag bool) error { + opts := []func(*mergo.Config){} + if overwriteFlag { + opts = append(opts, mergo.WithOverride) } - return mergo.Merge(dst, src) + if appendFlag { + opts = append(opts, mergo.WithAppendSlice) + } + return mergo.Merge(dst, src, opts...) } diff --git a/pkg/yqlib/lib_test.go b/pkg/yqlib/lib_test.go index bcfac5ff..d28acb9e 100644 --- a/pkg/yqlib/lib_test.go +++ b/pkg/yqlib/lib_test.go @@ -156,6 +156,23 @@ b: 2 test.AssertResult(t, `[{a b} {c d} {a 1} {b 2}]`, fmt.Sprintf("%v", mergedData["root"])) }) + t.Run("TestMerge_WithAppendAndOverwrite", func(t *testing.T) { + var dst = map[interface{}]interface{}{ + "a": "initial", + "b": []string{"old"}, + } + var src = map[interface{}]interface{}{ + "a": "replaced", + "b": []string{"new"}, + } + + err := subject.Merge(&dst, src, true, true) + if err != nil { + t.Fatal("Unexpected error") + } + test.AssertResult(t, `map[a:replaced b:[old new]]`, fmt.Sprintf("%v", dst)) + }) + t.Run("TestMerge_WithError", func(t *testing.T) { err := subject.Merge(nil, nil, false, false) if err == nil {