Prevent AutomaticEnv from clobbering an explicit mapping

When an explicit environment variable mapping is set for a key, do not
use the automatic mapping. This allows using AutomaticEnv while
specifying a special mapping for a single key.

It's important to both check for the explicit mapping first, and to not
fall back to the automatic mapping when the explicit environment variable
is not set. Otherwise it's very difficult to use AutomaticEnv when you
have a flag that uses a commonly set environment variable, such as
--path. When I map --path to SPECIAL_PATH, it shouldn't fall back to
PATH when SPECIAL_PATH isn't set.
This commit is contained in:
Carolyn Van Slyck 2018-01-10 10:35:47 -06:00
parent aafc9e6bc7
commit 11588a03fa
No known key found for this signature in database
GPG key ID: AEF5F64E6B9D8197
2 changed files with 22 additions and 9 deletions

View file

@ -931,9 +931,14 @@ func (v *Viper) find(lcaseKey string) interface{} {
}
// Env override next
if v.automaticEnvApplied {
// even if it hasn't been registered, if automaticEnv is used,
// check any Get request
// Check for an explicit environment key mapping first, before applying AutomaticEnv
envkey, exists := v.env[lcaseKey]
if exists {
if val = v.getEnv(envkey); val != "" {
return val
}
} else if v.automaticEnvApplied {
// If it hasn't been registered, check any Get request
if val = v.getEnv(v.mergeWithEnvPrefix(lcaseKey)); val != "" {
return val
}
@ -941,12 +946,6 @@ func (v *Viper) find(lcaseKey string) interface{} {
return nil
}
}
envkey, exists := v.env[lcaseKey]
if exists {
if val = v.getEnv(envkey); val != "" {
return val
}
}
if nested && v.isPathShadowedInFlatMap(path, v.env) != "" {
return nil
}

View file

@ -409,6 +409,20 @@ func TestAutoEnv(t *testing.T) {
assert.Equal(t, "13", Get("foo_bar"))
}
func TestAutoEnvOverride(t *testing.T) {
Reset()
BindEnv("path", "SPECIAL_PATH")
AutomaticEnv()
os.Setenv("SPECIAL_PATH", "/home/me/special")
os.Setenv("PATH", "/usr/local/bin:/usr/bin")
assert.Equal(t, "/home/me/special", Get("path"))
os.Unsetenv("SPECIAL_PATH")
assert.Nil(t, Get("path"))
}
func TestAutoEnvWithPrefix(t *testing.T) {
Reset()