From 4a9d408fe0bbf4c563546e35d2be7ade4e920c4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Pedersen?= Date: Tue, 22 Jun 2021 09:53:37 +0200 Subject: config: Fix merge of config with map[string]string values. Fixes #8679 --- config/compositeConfig.go | 4 ++ config/configProvider.go | 1 + config/defaultConfigProvider.go | 20 ++++++--- config/defaultConfigProvider_test.go | 79 ++++++++++++++++++++++++++++++++++++ 4 files changed, 98 insertions(+), 6 deletions(-) (limited to 'config') diff --git a/config/compositeConfig.go b/config/compositeConfig.go index c68419533..92bb165b7 100644 --- a/config/compositeConfig.go +++ b/config/compositeConfig.go @@ -104,6 +104,10 @@ func (c *compositeConfig) Set(key string, value interface{}) { c.layer.Set(key, value) } +func (c *compositeConfig) SetDefaults(params maps.Params) { + c.layer.SetDefaults(params) +} + func (c *compositeConfig) WalkParams(walkFn func(params ...KeyParams) bool) { panic("not supported") } diff --git a/config/configProvider.go b/config/configProvider.go index 92206ca9e..481524c3b 100644 --- a/config/configProvider.go +++ b/config/configProvider.go @@ -30,6 +30,7 @@ type Provider interface { Get(key string) interface{} Set(key string, value interface{}) Merge(key string, value interface{}) + SetDefaults(params maps.Params) SetDefaultMergeStrategy() WalkParams(walkFn func(params ...KeyParams) bool) IsSet(key string) bool diff --git a/config/defaultConfigProvider.go b/config/defaultConfigProvider.go index d9c9db7f1..fd32c08a6 100644 --- a/config/defaultConfigProvider.go +++ b/config/defaultConfigProvider.go @@ -163,10 +163,9 @@ func (c *defaultConfigProvider) Set(k string, v interface{}) { } switch vv := v.(type) { - case map[string]interface{}: - var p maps.Params = vv + case map[string]interface{}, map[interface{}]interface{}, map[string]string: + p := maps.MustToParamsAndPrepare(vv) v = p - maps.PrepareParams(p) } key, m := c.getNestedKeyAndMap(k, true) @@ -183,6 +182,16 @@ func (c *defaultConfigProvider) Set(k string, v interface{}) { m[key] = v } +// SetDefaults will set values from params if not already set. +func (c *defaultConfigProvider) SetDefaults(params maps.Params) { + maps.PrepareParams(params) + for k, v := range params { + if _, found := c.root[k]; !found { + c.root[k] = v + } + } +} + func (c *defaultConfigProvider) Merge(k string, v interface{}) { c.mu.Lock() defer c.mu.Unlock() @@ -226,10 +235,9 @@ func (c *defaultConfigProvider) Merge(k string, v interface{}) { } switch vv := v.(type) { - case map[string]interface{}: - var p maps.Params = vv + case map[string]interface{}, map[interface{}]interface{}, map[string]string: + p := maps.MustToParamsAndPrepare(vv) v = p - maps.PrepareParams(p) } key, m := c.getNestedKeyAndMap(k, true) diff --git a/config/defaultConfigProvider_test.go b/config/defaultConfigProvider_test.go index 834165d96..6752ab2e5 100644 --- a/config/defaultConfigProvider_test.go +++ b/config/defaultConfigProvider_test.go @@ -204,6 +204,85 @@ func TestDefaultConfigProvider(t *testing.T) { }) }) + // Issue #8679 + c.Run("Merge typed maps", func(c *qt.C) { + + for _, left := range []interface{}{ + map[string]string{ + "c": "cv1", + }, + map[string]interface{}{ + "c": "cv1", + }, + map[interface{}]interface{}{ + "c": "cv1", + }, + } { + cfg := New() + + cfg.Set("", map[string]interface{}{ + "b": left, + }) + + cfg.Merge("", maps.Params{ + "b": maps.Params{ + "c": "cv2", + "d": "dv2", + }, + }) + + c.Assert(cfg.Get(""), qt.DeepEquals, maps.Params{ + "b": maps.Params{ + "c": "cv1", + "d": "dv2", + }, + }) + } + + for _, left := range []interface{}{ + map[string]string{ + "b": "bv1", + }, + map[string]interface{}{ + "b": "bv1", + }, + map[interface{}]interface{}{ + "b": "bv1", + }, + } { + + for _, right := range []interface{}{ + map[string]string{ + "b": "bv2", + "c": "cv2", + }, + map[string]interface{}{ + "b": "bv2", + "c": "cv2", + }, + map[interface{}]interface{}{ + "b": "bv2", + "c": "cv2", + }, + } { + cfg := New() + + cfg.Set("a", left) + + cfg.Merge("a", right) + + c.Assert(cfg.Get(""), qt.DeepEquals, maps.Params{ + "a": maps.Params{ + "b": "bv1", + "c": "cv2", + }, + }) + } + + } + + }) + c.Run("IsSet", func(c *qt.C) { cfg := New() -- cgit v1.2.3