From 829e890a3095eaa05c59bfbdfb399456f7d9b509 Mon Sep 17 00:00:00 2001 From: Joe Frank Date: Wed, 1 Aug 2018 13:51:20 -0600 Subject: [PATCH] Add IsExplicit function to check for non-default. The IsSet function returns true even if the value that's available comes from the default. Rather than changing the behavior of IsSet, adding a new IsExplicit function allows checking for non-default values without breaking existing behavior. This is intended to address issue #276 among other things. --- viper.go | 20 +++++++++++++++++--- viper_test.go | 15 +++++++++++++++ 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/viper.go b/viper.go index 907a102..bf28aae 100644 --- a/viper.go +++ b/viper.go @@ -612,7 +612,7 @@ func GetViper() *Viper { func Get(key string) interface{} { return v.Get(key) } func (v *Viper) Get(key string) interface{} { lcaseKey := strings.ToLower(key) - val := v.find(lcaseKey) + val := v.find(lcaseKey, true) if val == nil { return nil } @@ -887,7 +887,7 @@ func (v *Viper) BindEnv(input ...string) error { // flag, env, config file, key/value store, default. // Viper will check to see if an alias exists first. // Note: this assumes a lower-cased key given. -func (v *Viper) find(lcaseKey string) interface{} { +func (v *Viper) find(lcaseKey string, useDefault bool) interface{} { var ( val interface{} @@ -975,6 +975,11 @@ func (v *Viper) find(lcaseKey string) interface{} { return nil } + // Only use default values if asked + if !useDefault { + return nil + } + // Default next val = v.searchMap(v.defaults, path) if val != nil { @@ -1020,7 +1025,16 @@ func readAsCSV(val string) ([]string, error) { func IsSet(key string) bool { return v.IsSet(key) } func (v *Viper) IsSet(key string) bool { lcaseKey := strings.ToLower(key) - val := v.find(lcaseKey) + val := v.find(lcaseKey, true) + return val != nil +} + +// IsExplicit checks to see if the key has a non-default value set. +// IsExplicit is case-insensitive for a key. +func IsExplicit(key string) bool { return v.IsExplicit(key) } +func (v *Viper) IsExplicit(key string) bool { + lcaseKey := strings.ToLower(key) + val := v.find(lcaseKey, false) return val != nil } diff --git a/viper_test.go b/viper_test.go index 60543f5..4b9d09b 100644 --- a/viper_test.go +++ b/viper_test.go @@ -766,6 +766,21 @@ func TestIsSet(t *testing.T) { assert.False(t, v.IsSet("helloworld")) v.Set("helloworld", "fubar") assert.True(t, v.IsSet("helloworld")) + v.SetDefault("default", "value") + assert.True(t, v.IsSet("default")) +} + +func TestIsExplicit(t *testing.T) { + v := New() + v.SetConfigType("yaml") + v.ReadConfig(bytes.NewBuffer(yamlExample)) + assert.True(t, v.IsExplicit("clothing.jacket")) + assert.False(t, v.IsExplicit("clothing.jackets")) + assert.False(t, v.IsExplicit("helloworld")) + v.Set("helloworld", "fubar") + assert.True(t, v.IsExplicit("helloworld")) + v.SetDefault("default", "value") + assert.False(t, v.IsExplicit("default")) } func TestDirsSearch(t *testing.T) {