fix: conf anonymous overlay problem (#2847)
This commit is contained in:
@@ -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 {
|
func buildFieldsInfo(tp reflect.Type) map[string]fieldInfo {
|
||||||
tp = mapping.Deref(tp)
|
tp = mapping.Deref(tp)
|
||||||
|
|
||||||
@@ -134,11 +148,12 @@ func buildStructFieldsInfo(tp reflect.Type) map[string]fieldInfo {
|
|||||||
if ft.Kind() == reflect.Struct {
|
if ft.Kind() == reflect.Struct {
|
||||||
fields := buildFieldsInfo(ft)
|
fields := buildFieldsInfo(ft)
|
||||||
for k, v := range fields {
|
for k, v := range fields {
|
||||||
info[k] = v
|
addOrMergeFields(info, k, v.name, v.children)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
info[lowerCaseName] = fieldInfo{
|
info[lowerCaseName] = fieldInfo{
|
||||||
name: name,
|
name: name,
|
||||||
|
children: make(map[string]fieldInfo),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
@@ -154,17 +169,7 @@ func buildStructFieldsInfo(tp reflect.Type) map[string]fieldInfo {
|
|||||||
fields = buildFieldsInfo(ft.Elem())
|
fields = buildFieldsInfo(ft.Elem())
|
||||||
}
|
}
|
||||||
|
|
||||||
if prev, ok := info[lowerCaseName]; ok {
|
addOrMergeFields(info, lowerCaseName, name, fields)
|
||||||
// merge fields
|
|
||||||
for k, v := range fields {
|
|
||||||
prev.children[k] = v
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
info[lowerCaseName] = fieldInfo{
|
|
||||||
name: name,
|
|
||||||
children: fields,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return info
|
return info
|
||||||
|
|||||||
@@ -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) {
|
func TestLoadFromYamlItemOverlayWithMap(t *testing.T) {
|
||||||
type (
|
type (
|
||||||
Redis struct {
|
Redis struct {
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ import (
|
|||||||
|
|
||||||
// PropertyError represents a configuration error message.
|
// PropertyError represents a configuration error message.
|
||||||
type PropertyError struct {
|
type PropertyError struct {
|
||||||
error
|
|
||||||
message string
|
message string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -108,7 +108,7 @@ func TestNopWriter(t *testing.T) {
|
|||||||
w.Stack("foo")
|
w.Stack("foo")
|
||||||
w.Stat("foo")
|
w.Stat("foo")
|
||||||
w.Slow("foo")
|
w.Slow("foo")
|
||||||
w.Close()
|
_ = w.Close()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user