forked from mirror/viper
Fixed AllKeys() to include env values added with BindEnv()
* Fixed: values bound with BindEnv added to AllKeys() Cast was not working, and v.env wasn't used when merging keys. Rewrote explicit and specific casts for maps storing strings or FlagValues. * Added: test for BindEnv() and AllKeys() To make sure AllSettings() and Unmarshal() will consider environment variables added with BindEnv().
This commit is contained in:
parent
50515b700e
commit
285f151019
23
viper.go
23
viper.go
|
@ -1162,6 +1162,14 @@ func castMapStringToMapInterface(src map[string]string) map[string]interface{} {
|
||||||
return tgt
|
return tgt
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func castMapFlagToMapInterface(src map[string]FlagValue) map[string]interface{} {
|
||||||
|
tgt := map[string]interface{}{}
|
||||||
|
for k, v := range src {
|
||||||
|
tgt[k] = v
|
||||||
|
}
|
||||||
|
return tgt
|
||||||
|
}
|
||||||
|
|
||||||
// mergeMaps merges two maps. The `itgt` parameter is for handling go-yaml's
|
// mergeMaps merges two maps. The `itgt` parameter is for handling go-yaml's
|
||||||
// insistence on parsing nested structures as `map[interface{}]interface{}`
|
// insistence on parsing nested structures as `map[interface{}]interface{}`
|
||||||
// instead of using a `string` as the key for nest structures beyond one level
|
// instead of using a `string` as the key for nest structures beyond one level
|
||||||
|
@ -1307,8 +1315,8 @@ func (v *Viper) AllKeys() []string {
|
||||||
// add all paths, by order of descending priority to ensure correct shadowing
|
// add all paths, by order of descending priority to ensure correct shadowing
|
||||||
m = v.flattenAndMergeMap(m, castMapStringToMapInterface(v.aliases), "")
|
m = v.flattenAndMergeMap(m, castMapStringToMapInterface(v.aliases), "")
|
||||||
m = v.flattenAndMergeMap(m, v.override, "")
|
m = v.flattenAndMergeMap(m, v.override, "")
|
||||||
m = v.mergeFlatMap(m, v.pflags)
|
m = v.mergeFlatMap(m, castMapFlagToMapInterface(v.pflags))
|
||||||
m = v.mergeFlatMap(m, v.env)
|
m = v.mergeFlatMap(m, castMapStringToMapInterface(v.env))
|
||||||
m = v.flattenAndMergeMap(m, v.config, "")
|
m = v.flattenAndMergeMap(m, v.config, "")
|
||||||
m = v.flattenAndMergeMap(m, v.kvstore, "")
|
m = v.flattenAndMergeMap(m, v.kvstore, "")
|
||||||
m = v.flattenAndMergeMap(m, v.defaults, "")
|
m = v.flattenAndMergeMap(m, v.defaults, "")
|
||||||
|
@ -1360,16 +1368,7 @@ func (v *Viper) flattenAndMergeMap(shadow map[string]bool, m map[string]interfac
|
||||||
|
|
||||||
// mergeFlatMap merges the given maps, excluding values of the second map
|
// mergeFlatMap merges the given maps, excluding values of the second map
|
||||||
// shadowed by values from the first map.
|
// shadowed by values from the first map.
|
||||||
func (v *Viper) mergeFlatMap(shadow map[string]bool, mi interface{}) map[string]bool {
|
func (v *Viper) mergeFlatMap(shadow map[string]bool, m map[string]interface{}) map[string]bool {
|
||||||
// unify input map
|
|
||||||
var m map[string]interface{}
|
|
||||||
switch mi.(type) {
|
|
||||||
case map[string]string, map[string]FlagValue:
|
|
||||||
m = cast.ToStringMap(mi)
|
|
||||||
default:
|
|
||||||
return shadow
|
|
||||||
}
|
|
||||||
|
|
||||||
// scan keys
|
// scan keys
|
||||||
outer:
|
outer:
|
||||||
for k, _ := range m {
|
for k, _ := range m {
|
||||||
|
|
|
@ -445,6 +445,23 @@ func TestAllKeys(t *testing.T) {
|
||||||
assert.Equal(t, all, AllSettings())
|
assert.Equal(t, all, AllSettings())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestAllKeysWithEnv(t *testing.T) {
|
||||||
|
v := New()
|
||||||
|
|
||||||
|
// bind and define environment variables (including a nested one)
|
||||||
|
v.BindEnv("id")
|
||||||
|
v.BindEnv("foo.bar")
|
||||||
|
v.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
|
||||||
|
os.Setenv("ID", "13")
|
||||||
|
os.Setenv("FOO_BAR", "baz")
|
||||||
|
|
||||||
|
expectedKeys := sort.StringSlice{"id", "foo.bar"}
|
||||||
|
expectedKeys.Sort()
|
||||||
|
keys := sort.StringSlice(v.AllKeys())
|
||||||
|
keys.Sort()
|
||||||
|
assert.Equal(t, expectedKeys, keys)
|
||||||
|
}
|
||||||
|
|
||||||
func TestAliasesOfAliases(t *testing.T) {
|
func TestAliasesOfAliases(t *testing.T) {
|
||||||
Set("Title", "Checking Case")
|
Set("Title", "Checking Case")
|
||||||
RegisterAlias("Foo", "Bar")
|
RegisterAlias("Foo", "Bar")
|
||||||
|
|
Loading…
Reference in New Issue