Revert "Make AllKeys and AllSettings return set-but-empty keys" (#22)

This commit is contained in:
Pablo Baeyens 2022-05-31 10:49:08 +02:00 committed by GitHub
parent 86d951dc13
commit 7e5da050b1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 11 additions and 69 deletions

View file

@ -339,16 +339,6 @@ func (v *Viper) getEnv(key string) (string, bool) {
return val, ok && (v.allowEmptyEnv || val != "")
}
func (v *Viper) getAllEnvBoundAndSet() map[string]interface{} {
tgt := map[string]interface{}{}
for key, value := range v.env {
if _, ok := v.getEnv(v.mergeWithEnvPrefix(key)); ok {
tgt[key] = value
}
}
return tgt
}
// ConfigFileUsed returns the file used to populate the config registry.
func ConfigFileUsed() string { return v.ConfigFileUsed() }
func (v *Viper) ConfigFileUsed() string { return v.configFile }
@ -1269,22 +1259,6 @@ func (v *Viper) Set(key string, value interface{}) {
deepestMap[lastKey] = value
}
// Unset removes a value set with Set
// Unset is case-insensitive for a key.
// Values which come from flags, config file, ENV or default can't be unset.
func Unset(key string) { v.Unset(key) }
func (v *Viper) Unset(key string) {
// If alias passed in, then set the proper override
key = v.realKey(strings.ToLower(key))
path := strings.Split(key, v.keyDelim)
lastKey := strings.ToLower(path[len(path)-1])
deepestMap := deepSearch(v.override, path[0:len(path)-1])
// unset innermost value
delete(deepestMap, lastKey)
}
// ReadInConfig will discover and load the configuration file from disk
// and key/value stores, searching in one of the defined paths.
func ReadInConfig() error { return v.ReadInConfig() }
@ -1597,6 +1571,14 @@ func castToMapStringInterface(
return tgt
}
func castMapStringSliceToMapInterface(src map[string][]string) map[string]interface{} {
tgt := map[string]interface{}{}
for k, v := range src {
tgt[k] = v
}
return tgt
}
func castMapStringToMapInterface(src map[string]string) map[string]interface{} {
tgt := map[string]interface{}{}
for k, v := range src {
@ -1763,7 +1745,7 @@ func (v *Viper) AllKeys() []string {
m = v.flattenAndMergeMap(m, castMapStringToMapInterface(v.aliases), "")
m = v.flattenAndMergeMap(m, v.override, "")
m = v.mergeFlatMap(m, castMapFlagToMapInterface(v.pflags))
m = v.mergeFlatMap(m, v.getAllEnvBoundAndSet())
m = v.mergeFlatMap(m, castMapStringSliceToMapInterface(v.env))
m = v.flattenAndMergeMap(m, v.config, "")
m = v.flattenAndMergeMap(m, v.kvstore, "")
m = v.flattenAndMergeMap(m, v.defaults, "")
@ -1807,10 +1789,6 @@ func (v *Viper) flattenAndMergeMap(shadow map[string]bool, m map[string]interfac
shadow[strings.ToLower(fullKey)] = true
continue
}
if len(m2) == 0 {
// empty dict explicitly present in the map
shadow[strings.ToLower(fullKey)] = true
}
// recursively merge to shadow map
shadow = v.flattenAndMergeMap(shadow, m2, fullKey)
}
@ -1847,8 +1825,8 @@ func (v *Viper) AllSettings() map[string]interface{} {
for _, k := range v.AllKeys() {
value := v.Get(k)
if value == nil {
// Key set but empty, include it in the output as a null value
m[k] = nil
// should not happen, since AllKeys() returns only keys holding a value,
// check just in case anything changes
continue
}

View file

@ -1818,39 +1818,3 @@ func TestKnownKeys(t *testing.T) {
t.Error("SetKnown didn't mark key as known")
}
}
func TestEmptySection(t *testing.T) {
var yamlWithEnvVars = `
key:
subkey:
another_key:
empty_dict: {}
`
v := New()
initConfig(v, "yaml", yamlWithEnvVars)
v.SetKnown("is_known")
v.SetDefault("has_default", true)
v.BindEnv("is_bound")
// AllKeys includes empty keys
keys := v.AllKeys()
assert.NotContains(t, keys, "key") // Only empty leaf nodes are returned
assert.Contains(t, keys, "key.subkey")
assert.Contains(t, keys, "another_key")
assert.Contains(t, keys, "empty_dict")
assert.NotContains(t, keys, "is_known")
assert.Contains(t, keys, "has_default")
assert.NotContains(t, keys, "is_bound")
// AllSettings includes empty keys
vars := v.AllSettings()
assert.NotContains(t, vars, "key") // Only empty leaf nodes are returned
assert.Contains(t, vars, "key.subkey")
assert.Contains(t, vars, "another_key")
assert.Contains(t, vars, "empty_dict")
assert.NotContains(t, vars, "is_known")
assert.Contains(t, vars, "has_default")
assert.NotContains(t, vars, "is_bound")
}