diff --git a/dict.go b/dict.go index 46692d15..fabc736b 100644 --- a/dict.go +++ b/dict.go @@ -75,10 +75,12 @@ func dict(v ...interface{}) map[string]interface{} { return dict } -func merge(dst map[string]interface{}, src map[string]interface{}) interface{} { - if err := mergo.Merge(&dst, src); err != nil { - // Swallow errors inside of a template. - return "" +func merge(dst map[string]interface{}, srcs ...map[string]interface{}) interface{} { + for _, src := range srcs { + if err := mergo.Merge(&dst, src); err != nil { + // Swallow errors inside of a template. + return "" + } } return dst } diff --git a/dict_test.go b/dict_test.go index 0206523e..100dccca 100644 --- a/dict_test.go +++ b/dict_test.go @@ -138,13 +138,20 @@ func TestCompact(t *testing.T) { func TestMerge(t *testing.T) { dict := map[string]interface{}{ - "src": map[string]interface{}{ + "src2": map[string]interface{}{ + "h": 10, + "i": "i", + "j": "j", + }, + "src1": map[string]interface{}{ "a": 1, "b": 2, "d": map[string]interface{}{ "e": "four", }, "g": []int{6, 7}, + "i": "aye", + "j": "jay", }, "dst": map[string]interface{}{ "a": "one", @@ -153,22 +160,26 @@ func TestMerge(t *testing.T) { "f": 5, }, "g": []int{8, 9}, + "i": "eye", }, } - tpl := `{{merge .dst .src}}` + tpl := `{{merge .dst .src1 .src2}}` _, err := runRaw(tpl, dict) if err != nil { t.Error(err) } expected := map[string]interface{}{ "a": "one", // key overridden - "b": 2, // merged from src + "b": 2, // merged from src1 "c": 3, // merged from dst "d": map[string]interface{}{ // deep merge "e": "four", "f": 5, }, "g": []int{8, 9}, // overridden - arrays are not merged + "h": 10, // merged from src2 + "i": "eye", // overridden twice + "j": "jay", // overridden and merged } assert.Equal(t, expected, dict["dst"]) } diff --git a/docs/dicts.md b/docs/dicts.md index fa110c67..54c9b064 100644 --- a/docs/dicts.md +++ b/docs/dicts.md @@ -77,10 +77,10 @@ matching key out of a collection of dictionaries. ## merge -Merge two dictionaries into one, giving precedence to the dest dictionary: +Merge two or more dictionaries into one, giving precedence to the dest dictionary: ``` -$newdict := merge $dest $source +$newdict := merge $dest $source1 $source2 ``` This is a deep merge operation.