From a019a1f59fc5b9c5d34070babfcbeac74eaaafb8 Mon Sep 17 00:00:00 2001 From: Kevin Wan Date: Sun, 5 Feb 2023 14:40:57 +0800 Subject: [PATCH] fix: conf anonymous overlay problem (#2847) --- core/conf/config.go | 31 ++++++++++++++++++------------- core/conf/config_test.go | 36 ++++++++++++++++++++++++++++++++++++ core/conf/properties.go | 1 - core/logx/writer_test.go | 2 +- 4 files changed, 55 insertions(+), 15 deletions(-) diff --git a/core/conf/config.go b/core/conf/config.go index 062e1b8f..729accdb 100644 --- a/core/conf/config.go +++ b/core/conf/config.go @@ -107,6 +107,20 @@ func MustLoad(path string, v any, opts ...Option) { } } +func addOrMergeFields(info map[string]fieldInfo, key, name string, fields map[string]fieldInfo) { + if prev, ok := info[key]; ok { + // merge fields + for k, v := range fields { + prev.children[k] = v + } + } else { + info[key] = fieldInfo{ + name: name, + children: fields, + } + } +} + func buildFieldsInfo(tp reflect.Type) map[string]fieldInfo { tp = mapping.Deref(tp) @@ -134,11 +148,12 @@ func buildStructFieldsInfo(tp reflect.Type) map[string]fieldInfo { if ft.Kind() == reflect.Struct { fields := buildFieldsInfo(ft) for k, v := range fields { - info[k] = v + addOrMergeFields(info, k, v.name, v.children) } } else { info[lowerCaseName] = fieldInfo{ - name: name, + name: name, + children: make(map[string]fieldInfo), } } continue @@ -154,17 +169,7 @@ func buildStructFieldsInfo(tp reflect.Type) map[string]fieldInfo { fields = buildFieldsInfo(ft.Elem()) } - if prev, ok := info[lowerCaseName]; ok { - // merge fields - for k, v := range fields { - prev.children[k] = v - } - } else { - info[lowerCaseName] = fieldInfo{ - name: name, - children: fields, - } - } + addOrMergeFields(info, lowerCaseName, name, fields) } return info diff --git a/core/conf/config_test.go b/core/conf/config_test.go index 3465c729..c78c25de 100644 --- a/core/conf/config_test.go +++ b/core/conf/config_test.go @@ -420,6 +420,42 @@ func TestLoadFromYamlItemOverlay(t *testing.T) { } } +func TestLoadFromYamlItemOverlayReverse(t *testing.T) { + type ( + Redis struct { + Host string + Port int + } + + RedisKey struct { + Redis + Key string + } + + Server struct { + Redis Redis + } + + TestConfig struct { + Redis RedisKey + Server + } + ) + + input := []byte(`Redis: + Host: localhost + Port: 6379 + Key: test +`) + + var c TestConfig + if assert.NoError(t, LoadFromYamlBytes(input, &c)) { + assert.Equal(t, "localhost", c.Redis.Host) + assert.Equal(t, 6379, c.Redis.Port) + assert.Equal(t, "test", c.Redis.Key) + } +} + func TestLoadFromYamlItemOverlayWithMap(t *testing.T) { type ( Redis struct { diff --git a/core/conf/properties.go b/core/conf/properties.go index 2b7c1314..acd4fa61 100644 --- a/core/conf/properties.go +++ b/core/conf/properties.go @@ -12,7 +12,6 @@ import ( // PropertyError represents a configuration error message. type PropertyError struct { - error message string } diff --git a/core/logx/writer_test.go b/core/logx/writer_test.go index c2b476e4..ec5e8912 100644 --- a/core/logx/writer_test.go +++ b/core/logx/writer_test.go @@ -108,7 +108,7 @@ func TestNopWriter(t *testing.T) { w.Stack("foo") w.Stat("foo") w.Slow("foo") - w.Close() + _ = w.Close() }) }