Allow environment variables to be set to empty string

This commit is contained in:
Harrison Healey 2018-06-20 14:31:47 -04:00
parent b5e8006cbe
commit f1c29ce273
2 changed files with 22 additions and 7 deletions

View file

@ -334,14 +334,14 @@ func (v *Viper) mergeWithEnvPrefix(in string) string {
// rewriting keys many things, Ex: Get('someKey') -> some_key // rewriting keys many things, Ex: Get('someKey') -> some_key
// (camel case to snake case for JSON keys perhaps) // (camel case to snake case for JSON keys perhaps)
// getEnv is a wrapper around os.Getenv which replaces characters in the original // getEnv is a wrapper around os.LookupEnv which replaces characters in the original
// key. This allows env vars which have different keys than the config object // key. This allows env vars which have different keys than the config object
// keys. // keys.
func (v *Viper) getEnv(key string) string { func (v *Viper) getEnv(key string) (string, bool) {
if v.envKeyReplacer != nil { if v.envKeyReplacer != nil {
key = v.envKeyReplacer.Replace(key) key = v.envKeyReplacer.Replace(key)
} }
return os.Getenv(key) return os.LookupEnv(key)
} }
// ConfigFileUsed returns the file used to populate the config registry. // ConfigFileUsed returns the file used to populate the config registry.
@ -568,10 +568,10 @@ func (v *Viper) isPathShadowedInFlatMap(path []string, mi interface{}) string {
// "foo.bar.baz" in a lower-priority map // "foo.bar.baz" in a lower-priority map
func (v *Viper) isPathShadowedInAutoEnv(path []string) string { func (v *Viper) isPathShadowedInAutoEnv(path []string) string {
var parentKey string var parentKey string
var val string var ok bool
for i := 1; i < len(path); i++ { for i := 1; i < len(path); i++ {
parentKey = strings.Join(path[0:i], v.keyDelim) parentKey = strings.Join(path[0:i], v.keyDelim)
if val = v.getEnv(v.mergeWithEnvPrefix(parentKey)); val != "" { if _, ok = v.getEnv(v.mergeWithEnvPrefix(parentKey)); ok {
return parentKey return parentKey
} }
} }
@ -934,7 +934,7 @@ func (v *Viper) find(lcaseKey string) interface{} {
if v.automaticEnvApplied { if v.automaticEnvApplied {
// even if it hasn't been registered, if automaticEnv is used, // even if it hasn't been registered, if automaticEnv is used,
// check any Get request // check any Get request
if val = v.getEnv(v.mergeWithEnvPrefix(lcaseKey)); val != "" { if val, ok := v.getEnv(v.mergeWithEnvPrefix(lcaseKey)); ok {
return val return val
} }
if nested && v.isPathShadowedInAutoEnv(path) != "" { if nested && v.isPathShadowedInAutoEnv(path) != "" {
@ -943,7 +943,7 @@ func (v *Viper) find(lcaseKey string) interface{} {
} }
envkey, exists := v.env[lcaseKey] envkey, exists := v.env[lcaseKey]
if exists { if exists {
if val = v.getEnv(envkey); val != "" { if val, ok := v.getEnv(envkey); ok {
return val return val
} }
} }

View file

@ -375,10 +375,17 @@ func TestEnv(t *testing.T) {
assert.Equal(t, "apple", Get("f")) assert.Equal(t, "apple", Get("f"))
assert.Equal(t, "Cake", Get("name")) assert.Equal(t, "Cake", Get("name"))
os.Setenv("FOOD", "")
assert.Equal(t, "", Get("f"))
AutomaticEnv() AutomaticEnv()
assert.Equal(t, "crunk", Get("name")) assert.Equal(t, "crunk", Get("name"))
os.Setenv("NAME", "")
assert.Equal(t, "", Get("name"))
} }
func TestEnvPrefix(t *testing.T) { func TestEnvPrefix(t *testing.T) {
@ -396,9 +403,17 @@ func TestEnvPrefix(t *testing.T) {
assert.Equal(t, "apple", Get("f")) assert.Equal(t, "apple", Get("f"))
assert.Equal(t, "Cake", Get("name")) assert.Equal(t, "Cake", Get("name"))
os.Setenv("FOO_ID", "")
assert.Equal(t, "", Get("id"))
AutomaticEnv() AutomaticEnv()
assert.Equal(t, "crunk", Get("name")) assert.Equal(t, "crunk", Get("name"))
os.Setenv("FOO_NAME", "")
assert.Equal(t, "", Get("name"))
} }
func TestAutoEnv(t *testing.T) { func TestAutoEnv(t *testing.T) {