mirror of
https://github.com/spf13/viper
synced 2024-12-22 19:47:01 +00:00
Allow merging configs with different types of leaf values
This commit is contained in:
parent
788403a47c
commit
0353c6ea50
2 changed files with 48 additions and 13 deletions
29
viper.go
29
viper.go
|
@ -1780,17 +1780,6 @@ func mergeMaps(
|
||||||
|
|
||||||
svType := reflect.TypeOf(sv)
|
svType := reflect.TypeOf(sv)
|
||||||
tvType := reflect.TypeOf(tv)
|
tvType := reflect.TypeOf(tv)
|
||||||
if tvType != nil && svType != tvType { // Allow for the target to be nil
|
|
||||||
v.logger.Error(
|
|
||||||
"svType != tvType",
|
|
||||||
"key", sk,
|
|
||||||
"st", svType,
|
|
||||||
"tt", tvType,
|
|
||||||
"sv", sv,
|
|
||||||
"tv", tv,
|
|
||||||
)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
v.logger.Trace(
|
v.logger.Trace(
|
||||||
"processing",
|
"processing",
|
||||||
|
@ -1804,13 +1793,27 @@ func mergeMaps(
|
||||||
switch ttv := tv.(type) {
|
switch ttv := tv.(type) {
|
||||||
case map[interface{}]interface{}:
|
case map[interface{}]interface{}:
|
||||||
v.logger.Trace("merging maps (must convert)")
|
v.logger.Trace("merging maps (must convert)")
|
||||||
tsv := sv.(map[interface{}]interface{})
|
tsv, ok := sv.(map[interface{}]interface{})
|
||||||
|
if !ok {
|
||||||
|
v.logger.Error(
|
||||||
|
"Could not cast sv to map[interface{}]interface{}; key=%s, st=%v, tt=%v, sv=%v, tv=%v",
|
||||||
|
sk, svType, tvType, sv, tv)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
ssv := castToMapStringInterface(tsv)
|
ssv := castToMapStringInterface(tsv)
|
||||||
stv := castToMapStringInterface(ttv)
|
stv := castToMapStringInterface(ttv)
|
||||||
mergeMaps(ssv, stv, ttv)
|
mergeMaps(ssv, stv, ttv)
|
||||||
case map[string]interface{}:
|
case map[string]interface{}:
|
||||||
v.logger.Trace("merging maps")
|
v.logger.Trace("merging maps")
|
||||||
mergeMaps(sv.(map[string]interface{}), ttv, nil)
|
tsv, ok := sv.(map[string]interface{})
|
||||||
|
if !ok {
|
||||||
|
jww.ERROR.Printf(
|
||||||
|
"Could not cast sv to map[string]interface{}; key=%s, st=%v, tt=%v, sv=%v, tv=%v",
|
||||||
|
sk, svType, tvType, sv, tv)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
mergeMaps(tsv, ttv, nil)
|
||||||
default:
|
default:
|
||||||
v.logger.Trace("setting value")
|
v.logger.Trace("setting value")
|
||||||
tgt[tk] = sv
|
tgt[tk] = sv
|
||||||
|
|
|
@ -1912,6 +1912,22 @@ hello:
|
||||||
fu: bar
|
fu: bar
|
||||||
`)
|
`)
|
||||||
|
|
||||||
|
var jsonMergeExampleTgt = []byte(`
|
||||||
|
{
|
||||||
|
"hello": {
|
||||||
|
"pop": 123456
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`)
|
||||||
|
|
||||||
|
var jsonMergeExampleSrc = []byte(`
|
||||||
|
{
|
||||||
|
"hello": {
|
||||||
|
"pop": "pop str"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`)
|
||||||
|
|
||||||
func TestMergeConfig(t *testing.T) {
|
func TestMergeConfig(t *testing.T) {
|
||||||
v := New()
|
v := New()
|
||||||
v.SetConfigType("yml")
|
v.SetConfigType("yml")
|
||||||
|
@ -1984,6 +2000,22 @@ func TestMergeConfig(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestMergeConfigOverrideType(t *testing.T) {
|
||||||
|
v := New()
|
||||||
|
v.SetConfigType("json")
|
||||||
|
if err := v.ReadConfig(bytes.NewBuffer(jsonMergeExampleTgt)); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := v.MergeConfig(bytes.NewBuffer(jsonMergeExampleSrc)); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if pop := v.GetString("hello.pop"); pop != "pop str" {
|
||||||
|
t.Fatalf("pop != \"pop str\", = %s", pop)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestMergeConfigNoMerge(t *testing.T) {
|
func TestMergeConfigNoMerge(t *testing.T) {
|
||||||
v := New()
|
v := New()
|
||||||
v.SetConfigType("yml")
|
v.SetConfigType("yml")
|
||||||
|
|
Loading…
Reference in a new issue