mirror of
https://github.com/spf13/viper
synced 2024-12-22 19:47:01 +00:00
correct GetStringMap inconsistency, fixes #708
This commit is contained in:
parent
81089eeca9
commit
a60b38b333
2 changed files with 53 additions and 3 deletions
29
viper.go
29
viper.go
|
@ -1041,21 +1041,21 @@ func (v *Viper) GetStringSlice(key string) []string {
|
|||
func GetStringMap(key string) map[string]interface{} { return v.GetStringMap(key) }
|
||||
|
||||
func (v *Viper) GetStringMap(key string) map[string]interface{} {
|
||||
return cast.ToStringMap(v.Get(key))
|
||||
return cast.ToStringMap(v.allSettingsUnderParent(key))
|
||||
}
|
||||
|
||||
// GetStringMapString returns the value associated with the key as a map of strings.
|
||||
func GetStringMapString(key string) map[string]string { return v.GetStringMapString(key) }
|
||||
|
||||
func (v *Viper) GetStringMapString(key string) map[string]string {
|
||||
return cast.ToStringMapString(v.Get(key))
|
||||
return cast.ToStringMapString(v.allSettingsUnderParent(key))
|
||||
}
|
||||
|
||||
// GetStringMapStringSlice returns the value associated with the key as a map to a slice of strings.
|
||||
func GetStringMapStringSlice(key string) map[string][]string { return v.GetStringMapStringSlice(key) }
|
||||
|
||||
func (v *Viper) GetStringMapStringSlice(key string) map[string][]string {
|
||||
return cast.ToStringMapStringSlice(v.Get(key))
|
||||
return cast.ToStringMapStringSlice(v.allSettingsUnderParent(key))
|
||||
}
|
||||
|
||||
// GetSizeInBytes returns the size of the value associated with the given key
|
||||
|
@ -2016,6 +2016,29 @@ func (v *Viper) AllSettings() map[string]interface{} {
|
|||
return m
|
||||
}
|
||||
|
||||
func (v *Viper) allSettingsUnderParent(parent string) map[string]interface{} {
|
||||
m := map[string]interface{}{}
|
||||
// start from the list of keys, and construct the map one value at a time
|
||||
for _, k := range v.AllKeys() {
|
||||
if !strings.HasPrefix(k, parent) {
|
||||
continue
|
||||
}
|
||||
|
||||
value := v.Get(k)
|
||||
if value == nil {
|
||||
// should not happen, since AllKeys() returns only keys holding a value,
|
||||
// check just in case anything changes
|
||||
continue
|
||||
}
|
||||
path := strings.Split(strings.TrimPrefix(k, parent+v.keyDelim), v.keyDelim)
|
||||
lastKey := strings.ToLower(path[len(path)-1])
|
||||
deepestMap := deepSearch(m, path[0:len(path)-1])
|
||||
// set innermost value
|
||||
deepestMap[lastKey] = value
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
// SetFs sets the filesystem to use to read configuration.
|
||||
func SetFs(fs afero.Fs) { v.SetFs(fs) }
|
||||
|
||||
|
|
|
@ -878,6 +878,33 @@ func TestRecursiveAliases(t *testing.T) {
|
|||
RegisterAlias("Roo", "baz")
|
||||
}
|
||||
|
||||
func TestStringMapOverrides(t *testing.T) {
|
||||
v := New()
|
||||
|
||||
v.SetDefault("foo.bar", "default-value")
|
||||
v.SetDefault("foo.baz", 1)
|
||||
v.SetDefault("deeper.nest.a", "default-value")
|
||||
v.SetDefault("deeper.nest.b", "default-value")
|
||||
|
||||
v.SetEnvPrefix("test")
|
||||
v.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
|
||||
v.AutomaticEnv()
|
||||
|
||||
testutil.Setenv(t, "TEST_FOO_BAR", "overidden")
|
||||
testutil.Setenv(t, "TEST_DEEPER_NEST_A", "overidden")
|
||||
|
||||
assert.Equal(t, "overidden", v.GetString("foo.bar"))
|
||||
assert.Equal(t, map[string]interface{}{
|
||||
"bar": "overidden",
|
||||
"baz": 1,
|
||||
}, v.GetStringMap("foo"))
|
||||
|
||||
assert.Equal(t, map[string]string{
|
||||
"a": "overidden",
|
||||
"b": "default-value",
|
||||
}, v.GetStringMapString("deeper.nest"))
|
||||
}
|
||||
|
||||
func TestUnmarshal(t *testing.T) {
|
||||
SetDefault("port", 1313)
|
||||
Set("name", "Steve")
|
||||
|
|
Loading…
Reference in a new issue