Kaynağa Gözat

fix: conf anonymous overlay problem (#2847)

Kevin Wan 2 yıl önce
ebeveyn
işleme
a019a1f59f

+ 18 - 13
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

+ 36 - 0
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 {

+ 0 - 1
core/conf/properties.go

@@ -12,7 +12,6 @@ import (
 
 // PropertyError represents a configuration error message.
 type PropertyError struct {
-	error
 	message string
 }
 

+ 1 - 1
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()
 	})
 }