diff --git a/viper.go b/viper.go index 5f76cc0..a752f0c 100644 --- a/viper.go +++ b/viper.go @@ -205,6 +205,7 @@ type Viper struct { automaticEnvApplied bool envKeyReplacer StringReplacer allowEmptyEnv bool + allowEmptyMap bool config map[string]interface{} override map[string]interface{} @@ -535,6 +536,15 @@ func (v *Viper) AllowEmptyEnv(allowEmptyEnv bool) { v.allowEmptyEnv = allowEmptyEnv } +// AllowEmptyMap tells Viper to consider set, +// but empty maps as valid values instead of falling back. +// For backward compatibility reasons this is false by default. +func AllowEmptyMap(allowEmptyMap bool) { v.AllowEmptyMap(allowEmptyMap) } + +func (v *Viper) AllowEmptyMap(allowEmptyMap bool) { + v.allowEmptyMap = allowEmptyMap +} + // TODO: should getEnv logic be moved into find(). Can generalize the use of // rewriting keys many things, Ex: Get('someKey') -> some_key // (camel case to snake case for JSON keys perhaps) @@ -1550,6 +1560,8 @@ func (v *Viper) ReadInConfig() error { return err } + fmt.Println(config) + v.config = config return nil } @@ -1582,7 +1594,9 @@ func ReadConfig(in io.Reader) error { return v.ReadConfig(in) } func (v *Viper) ReadConfig(in io.Reader) error { v.config = make(map[string]interface{}) - return v.unmarshalReader(in, v.config) + err := v.unmarshalReader(in, v.config) + fmt.Println(v.config) + return err } // MergeConfig merges a new configuration with an existing config. @@ -2011,6 +2025,13 @@ func (v *Viper) flattenAndMergeMap(shadow map[string]bool, m map[string]interfac shadow[strings.ToLower(fullKey)] = true continue } + + if v.allowEmptyMap { + if len(val.(map[string]interface{})) == 0 { + shadow[strings.ToLower(fullKey)] = true + continue + } + } // recursively merge to shadow map shadow = v.flattenAndMergeMap(shadow, m2, fullKey) } diff --git a/viper_test.go b/viper_test.go index 926ffc2..1a114d6 100644 --- a/viper_test.go +++ b/viper_test.go @@ -60,6 +60,8 @@ type testUnmarshalExtra struct { var tomlExample = []byte(` title = "TOML Example" +[ecs.test] + [owner] organization = "MongoDB" Bio = "MongoDB Chief Developer Advocate & Hacker at Large" @@ -669,6 +671,16 @@ func TestEmptyEnv_Allowed(t *testing.T) { assert.Equal(t, "Cake", Get("name")) } +func TestEmptyMap_Allowed(t *testing.T) { + initTOML() + AllowEmptyMap(true) + + allkeys := sort.StringSlice(AllKeys()) + allkeys.Sort() + + assert.Equal(t, sort.StringSlice(sort.StringSlice{"ecs.test", "owner.bio", "owner.dob", "owner.organization", "title"}), allkeys) +} + func TestEnvPrefix(t *testing.T) { initJSON()