Added function to check for partial keys existing: Includes checking PFlags and Envs, unlike IsSet() (#764)

This commit is contained in:
inkychris 2019-09-18 09:07:48 +01:00
parent 99520c81d8
commit 78f7390c39
2 changed files with 56 additions and 2 deletions

View file

@ -1789,14 +1789,35 @@ outer:
return shadow
}
// Checks to see if a key may exist as a parent node.
// Similar to v.IsSet(), but checks pflags as a fallback.
func (v *Viper) isComponent(key string) bool {
lcaseKey := strings.ToLower(key)
val := v.find(lcaseKey)
if val != nil {
return true
}
for k := range v.pflags {
if strings.HasPrefix(k, lcaseKey) {
return true
}
}
for k := range v.env {
if strings.HasPrefix(k, lcaseKey) {
return true
}
}
return false
}
// Converts a fully qualified map key into a list of relative
// map keys, allowing for keys to contain the delimiter themselves
func keyComponents(v *Viper, key string) []string {
var result []string
components := strings.Split(key, v.keyDelim)
for index := 0; index < len(components); index++ {
for index := 1; index < len(components); index++ {
potentialKey := strings.Join(components[0:index], v.keyDelim)
if v.Get(potentialKey) != nil {
if v.isComponent(potentialKey) {
result = append(result, potentialKey)
}
}

View file

@ -758,6 +758,39 @@ func TestBindPFlags(t *testing.T) {
}
func TestUnmarshalOnlyPFlagSet(t *testing.T) {
flags := pflag.NewFlagSet("test", pflag.ContinueOnError)
flags.String("foo.bar", "cobra_flag", "")
v := New()
assert.NoError(t, v.BindPFlags(flags))
config := &struct {
Foo struct {
Bar string
}
}{}
assert.NoError(t, v.Unmarshal(config))
assert.Equal(t, "cobra_flag", config.Foo.Bar)
}
func TestUnmarshalOnlyEnvSet(t *testing.T) {
v := New()
v.SetEnvPrefix("viper")
assert.NoError(t, v.BindEnv("foo.bar"))
assert.NoError(t, os.Setenv("VIPER_FOO.BAR", "testval"))
config := &struct {
Foo struct {
Bar string
}
}{}
assert.NoError(t, v.Unmarshal(config))
assert.Equal(t, "testval", config.Foo.Bar)
}
func TestBindPFlagsStringSlice(t *testing.T) {
tests := []struct {
Expected []string