diff --git a/confmap/confmap.go b/confmap/confmap.go index 9a525a47f02..f64e7c037a7 100644 --- a/confmap/confmap.go +++ b/confmap/confmap.go @@ -157,28 +157,6 @@ func (l *Conf) IsSet(key string) bool { return l.k.Exists(key) } -type mergeOption struct { - mergePaths []string -} - -// WithMergePaths sets an option to merge the lists instead of -// overriding them. -func WithMergePaths(paths []string) MergeOpts { - return mergeOptionFunc(func(uo *mergeOption) { - uo.mergePaths = paths - }) -} - -type MergeOpts interface { - apply(*mergeOption) -} - -type mergeOptionFunc func(*mergeOption) - -func (fn mergeOptionFunc) apply(set *mergeOption) { - fn(set) -} - // Merge merges the input given configuration into the existing config. // Note that the given map may be modified. @@ -188,10 +166,7 @@ func (l *Conf) Merge(in *Conf, opts ...MergeOpts) error { opt.apply(&set) } if len(set.mergePaths) > 0 { - m := mergeComponents{ - mergePaths: set.mergePaths, - } - return l.mergeWithFunc(in, m.mergeComponentsAppend) + return l.mergeWithFunc(in, set.mergeComponentsAppend) } return l.merge(in) } diff --git a/confmap/merge.go b/confmap/merge.go index 4bddb7bc710..d706d507e42 100644 --- a/confmap/merge.go +++ b/confmap/merge.go @@ -14,11 +14,29 @@ const ( mergeAllAlias = "*" ) -type mergeComponents struct { +type mergeOption struct { mergePaths []string } -func (m *mergeComponents) mergeComponentsAppend(src, dest map[string]any) error { +// WithMergePaths sets an option to merge the lists instead of +// overriding them. +func WithMergePaths(paths []string) MergeOpts { + return mergeOptionFunc(func(uo *mergeOption) { + uo.mergePaths = paths + }) +} + +type MergeOpts interface { + apply(*mergeOption) +} + +type mergeOptionFunc func(*mergeOption) + +func (fn mergeOptionFunc) apply(set *mergeOption) { + fn(set) +} + +func (m *mergeOption) mergeComponentsAppend(src, dest map[string]any) error { // mergeComponentsAppend recursively merges the src map into the dest map (left to right), // modifying and expanding the dest map in the process. // This function does not overwrite lists, and ensures that the final value is a name-aware @@ -67,7 +85,7 @@ func merge(path string, src, dest map[string]any) { maps.Delete(src, pathSplit) // Note: path is a delimited by KeyDelimiter. We will call "Unflatten" later to get the final config - src[path] = mergeSlice(destVal, srcVal) + src[path] = mergeSlice(srcVal, destVal) case reflect.Map: // both of them are maps. Recursively call the mergeMaps mergeMaps(sVal.(map[string]any), dVal.(map[string]any)) @@ -83,18 +101,18 @@ func mergeMaps(src, dest map[string]any) { continue } - newVal := reflect.ValueOf(sVal) - oldVal := reflect.ValueOf(dVal) + srcVal := reflect.ValueOf(sVal) + destVal := reflect.ValueOf(dVal) - if newVal.Kind() != oldVal.Kind() { + if destVal.Kind() != srcVal.Kind() { // different kinds, maps.Merge will override the old config continue } - switch oldVal.Kind() { + switch srcVal.Kind() { case reflect.Array, reflect.Slice: // both of them are array. Merge them - src[dKey] = mergeSlice(oldVal, newVal) + src[dKey] = mergeSlice(srcVal, destVal) case reflect.Map: // both of them are maps. Recursively call the mergeMaps mergeMaps(sVal.(map[string]any), dVal.(map[string]any)) @@ -102,23 +120,23 @@ func mergeMaps(src, dest map[string]any) { } } -func mergeSlice(old, new reflect.Value) any { - if old.Type() != new.Type() { - return new +func mergeSlice(src, dest reflect.Value) any { + if src.Type() != dest.Type() { + return src } - slice := reflect.MakeSlice(old.Type(), 0, old.Cap()+new.Cap()) - for i := 0; i < old.Len(); i++ { - slice = reflect.Append(slice, old.Index(i)) + slice := reflect.MakeSlice(src.Type(), 0, src.Cap()+dest.Cap()) + for i := 0; i < dest.Len(); i++ { + slice = reflect.Append(slice, dest.Index(i)) } OUTER2: - for i := 0; i < new.Len(); i++ { + for i := 0; i < src.Len(); i++ { for j := 0; j < slice.Len(); j++ { - if slice.Index(j).Equal(new.Index(i)) { + if slice.Index(j).Equal(src.Index(i)) { continue OUTER2 } } - slice = reflect.Append(slice, new.Index(i)) + slice = reflect.Append(slice, src.Index(i)) } return slice.Interface() } diff --git a/confmap/resolver_test.go b/confmap/resolver_test.go index 3c8dfd8eecc..f55e7d94dc7 100644 --- a/confmap/resolver_test.go +++ b/confmap/resolver_test.go @@ -451,7 +451,6 @@ func TestMergeFunctionality(t *testing.T) { require.NoError(t, err) for _, tt := range testcases { t.Run(tt.Name, func(t *testing.T) { - conf := New() for _, c := range tt.Configs { require.NoError(t, conf.Merge(NewFromStringMap(c), WithMergePaths(tt.AppendPaths)))