mirror of https://github.com/spf13/viper.git
Allow nil values to be returned by AllSettings
Signed-off-by: Bogdan Drutu <bogdandrutu@gmail.com>
This commit is contained in:
parent
d9d7dcdc63
commit
dcd7fbbff7
14
viper.go
14
viper.go
|
@ -199,6 +199,7 @@ type Viper struct {
|
||||||
automaticEnvApplied bool
|
automaticEnvApplied bool
|
||||||
envKeyReplacer StringReplacer
|
envKeyReplacer StringReplacer
|
||||||
allowEmptyEnv bool
|
allowEmptyEnv bool
|
||||||
|
allowNilValues bool
|
||||||
|
|
||||||
config map[string]interface{}
|
config map[string]interface{}
|
||||||
override map[string]interface{}
|
override map[string]interface{}
|
||||||
|
@ -257,6 +258,14 @@ func KeyDelimiter(d string) Option {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AllowNilValues tells Viper to not ignore keys with nil values.
|
||||||
|
// For backward compatibility reasons this is false by default.
|
||||||
|
func AllowNilValues(allowNilValues bool) Option {
|
||||||
|
return optionFunc(func(v *Viper) {
|
||||||
|
v.allowNilValues = allowNilValues
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// StringReplacer applies a set of replacements to a string.
|
// StringReplacer applies a set of replacements to a string.
|
||||||
type StringReplacer interface {
|
type StringReplacer interface {
|
||||||
// Replace returns a copy of s with all replacements performed.
|
// Replace returns a copy of s with all replacements performed.
|
||||||
|
@ -1960,9 +1969,8 @@ func (v *Viper) AllSettings() map[string]interface{} {
|
||||||
// start from the list of keys, and construct the map one value at a time
|
// start from the list of keys, and construct the map one value at a time
|
||||||
for _, k := range v.AllKeys() {
|
for _, k := range v.AllKeys() {
|
||||||
value := v.Get(k)
|
value := v.Get(k)
|
||||||
if value == nil {
|
// Default behavior is to not allow nil values, but users can enable this via config.
|
||||||
// should not happen, since AllKeys() returns only keys holding a value,
|
if value == nil && !v.allowNilValues {
|
||||||
// check just in case anything changes
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
path := strings.Split(k, v.keyDelim)
|
path := strings.Split(k, v.keyDelim)
|
||||||
|
|
|
@ -2258,6 +2258,37 @@ func TestKeyDelimiter(t *testing.T) {
|
||||||
assert.Equal(t, expected, actual)
|
assert.Equal(t, expected, actual)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var yamlExampleWithNilValues = []byte(`Hacker: true
|
||||||
|
name: steve
|
||||||
|
hobbies:
|
||||||
|
clothing:
|
||||||
|
jacket:
|
||||||
|
`)
|
||||||
|
|
||||||
|
func TestNilValues(t *testing.T) {
|
||||||
|
vNil := NewWithOptions(AllowNilValues(true))
|
||||||
|
vNil.SetConfigType("yaml")
|
||||||
|
require.NoError(t, vNil.ReadConfig(strings.NewReader(string(yamlExampleWithNilValues))))
|
||||||
|
expectedNil := map[string]interface{}{
|
||||||
|
"hacker": true,
|
||||||
|
"name": "steve",
|
||||||
|
"hobbies": nil,
|
||||||
|
"clothing": map[string]interface{}{
|
||||||
|
"jacket": nil,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
assert.EqualValues(t, expectedNil, vNil.AllSettings())
|
||||||
|
|
||||||
|
vNotNil := NewWithOptions(AllowNilValues(false))
|
||||||
|
vNotNil.SetConfigType("yaml")
|
||||||
|
require.NoError(t, vNotNil.ReadConfig(strings.NewReader(string(yamlExampleWithNilValues))))
|
||||||
|
expectedNotNil := map[string]interface{}{
|
||||||
|
"hacker": true,
|
||||||
|
"name": "steve",
|
||||||
|
}
|
||||||
|
assert.EqualValues(t, expectedNotNil, vNotNil.AllSettings())
|
||||||
|
}
|
||||||
|
|
||||||
func BenchmarkGetBool(b *testing.B) {
|
func BenchmarkGetBool(b *testing.B) {
|
||||||
key := "BenchmarkGetBool"
|
key := "BenchmarkGetBool"
|
||||||
v = New()
|
v = New()
|
||||||
|
|
Loading…
Reference in New Issue