Allow BindEnv to register multiple environment variables. - viper - [fork] go viper port for 9front
(HTM) git clone git@git.drkhsh.at/viper.git
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) README
(DIR) LICENSE
---
(DIR) commit b655224c01bdc85dd8d755f21dbe32699258a626
(DIR) parent b534983313fbb5ef82f76d9b82cd550b1e05f5b0
(HTM) Author: Gabriel Aszalos <gabriel.aszalos@gmail.com>
Date: Thu, 10 Sep 2020 13:08:26 +0300
Allow BindEnv to register multiple environment variables.
This change modifies BindEnv to permit a list of environment variable
names in order to support multiple env. vars. for the same config key.
When this form is used, env. keys take precedence in the written order.
Closes #971
Diffstat:
M viper.go | 31 +++++++++++++++++++------------
M viper_test.go | 14 +++++++++++++-
2 files changed, 32 insertions(+), 13 deletions(-)
---
(DIR) diff --git a/viper.go b/viper.go
@@ -205,7 +205,7 @@ type Viper struct {
defaults map[string]interface{}
kvstore map[string]interface{}
pflags map[string]FlagValue
- env map[string]string
+ env map[string][]string
aliases map[string]string
typeByDefValue bool
@@ -228,7 +228,7 @@ func New() *Viper {
v.defaults = make(map[string]interface{})
v.kvstore = make(map[string]interface{})
v.pflags = make(map[string]FlagValue)
- v.env = make(map[string]string)
+ v.env = make(map[string][]string)
v.aliases = make(map[string]string)
v.typeByDefValue = false
@@ -1029,21 +1029,18 @@ func (v *Viper) BindFlagValue(key string, flag FlagValue) error {
func BindEnv(input ...string) error { return v.BindEnv(input...) }
func (v *Viper) BindEnv(input ...string) error {
- var key, envkey string
if len(input) == 0 {
return fmt.Errorf("missing key to bind to")
}
- key = strings.ToLower(input[0])
+ key := strings.ToLower(input[0])
if len(input) == 1 {
- envkey = v.mergeWithEnvPrefix(key)
+ v.env[key] = append(v.env[key], v.mergeWithEnvPrefix(key))
} else {
- envkey = input[1]
+ v.env[key] = append(v.env[key], input[1:]...)
}
- v.env[key] = envkey
-
return nil
}
@@ -1122,10 +1119,12 @@ func (v *Viper) find(lcaseKey string, flagDefault bool) interface{} {
return nil
}
}
- envkey, exists := v.env[lcaseKey]
+ envkeys, exists := v.env[lcaseKey]
if exists {
- if val, ok := v.getEnv(envkey); ok {
- return val
+ for _, envkey := range envkeys {
+ if val, ok := v.getEnv(envkey); ok {
+ return val
+ }
}
}
if nested && v.isPathShadowedInFlatMap(path, v.env) != "" {
@@ -1711,6 +1710,14 @@ func castToMapStringInterface(
return tgt
}
+func castMapStringSliceToMapInterface(src map[string][]string) map[string]interface{} {
+ tgt := map[string]interface{}{}
+ for k, v := range src {
+ tgt[k] = v
+ }
+ return tgt
+}
+
func castMapStringToMapInterface(src map[string]string) map[string]interface{} {
tgt := map[string]interface{}{}
for k, v := range src {
@@ -1883,7 +1890,7 @@ func (v *Viper) AllKeys() []string {
m = v.flattenAndMergeMap(m, castMapStringToMapInterface(v.aliases), "")
m = v.flattenAndMergeMap(m, v.override, "")
m = v.mergeFlatMap(m, castMapFlagToMapInterface(v.pflags))
- m = v.mergeFlatMap(m, castMapStringToMapInterface(v.env))
+ m = v.mergeFlatMap(m, castMapStringSliceToMapInterface(v.env))
m = v.flattenAndMergeMap(m, v.config, "")
m = v.flattenAndMergeMap(m, v.kvstore, "")
m = v.flattenAndMergeMap(m, v.defaults, "")
(DIR) diff --git a/viper_test.go b/viper_test.go
@@ -486,10 +486,11 @@ func TestEnv(t *testing.T) {
initJSON()
BindEnv("id")
- BindEnv("f", "FOOD")
+ BindEnv("f", "FOOD", "OLD_FOOD")
os.Setenv("ID", "13")
os.Setenv("FOOD", "apple")
+ os.Setenv("OLD_FOOD", "banana")
os.Setenv("NAME", "crunk")
assert.Equal(t, "13", Get("id"))
@@ -501,6 +502,17 @@ func TestEnv(t *testing.T) {
assert.Equal(t, "crunk", Get("name"))
}
+func TestMultipleEnv(t *testing.T) {
+ initJSON()
+
+ BindEnv("f", "FOOD", "OLD_FOOD")
+
+ os.Unsetenv("FOOD")
+ os.Setenv("OLD_FOOD", "banana")
+
+ assert.Equal(t, "banana", Get("f"))
+}
+
func TestEmptyEnv(t *testing.T) {
initJSON()