From 2ecf3ac9a3f9ca0dc563da7473c9b39477504235 Mon Sep 17 00:00:00 2001 From: Joe Frank Date: Tue, 26 Feb 2019 16:05:23 -0700 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 cee37b2..2187e74 100644 --- a/viper.go +++ b/viper.go @@ -666,7 +666,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 } @@ -951,7 +951,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{} @@ -1039,6 +1039,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 { @@ -1084,7 +1089,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 f4263d3..abba75c 100644 --- a/viper_test.go +++ b/viper_test.go @@ -847,6 +847,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) {