Repository: zeromicro/go-zero
Pull request #2847 (2023-02-05 06:22:19)

fix: conf anonymous overlay problem

codecov[bot]: # [Codecov](https://codecov.io/gh/zeromicro/go-zero/pull/2847?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None) Report
> Merging [#2847](https://codecov.io/gh/zeromicro/go-zero/pull/2847?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None) (9c523d4) into [master](https://codecov.io/gh/zeromicro/go-zero/commit/aed312f3c041486861818ab30a20ae963145dc15?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None) (aed312f) will **increase** coverage by `0.00%`.
> The diff coverage is `100.00%`.


| [Impacted Files](https://codecov.io/gh/zeromicro/go-zero/pull/2847?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None) | Coverage Δ | |
|---|---|---|
| [core/conf/properties.go](https://codecov.io/gh/zeromicro/go-zero/pull/2847?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None#diff-Y29yZS9jb25mL3Byb3BlcnRpZXMuZ28=) | `100.00% <ø> (ø)` | |
| [core/conf/config.go](https://codecov.io/gh/zeromicro/go-zero/pull/2847?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None#diff-Y29yZS9jb25mL2NvbmZpZy5nbw==) | `93.18% <100.00%> (+0.15%)` | :arrow_up: |


Patch:
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/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
 }
 


Test patch:
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/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()
 	})
 }