From cf43d0dcb872038271b8e1a6987175cbf7bd170e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Fabianski?= Date: Mon, 18 Dec 2023 18:07:28 +0100 Subject: [PATCH] feat: handle other options for prefix --- viper.go | 33 ++++++++++++++++++++++++++++++--- viper_test.go | 46 ++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 74 insertions(+), 5 deletions(-) diff --git a/viper.go b/viper.go index 122280b..cf1cd84 100644 --- a/viper.go +++ b/viper.go @@ -1240,8 +1240,9 @@ func (v *Viper) BindFlagValue(key string, flag FlagValue) error { // If only a key is provided, it will use the env key matching the key, uppercased. // If more arguments are provided, they will represent the env variable names that // should bind to this key and will be taken in the specified order. -// EnvPrefix will be used when set when env name is not provided. -func BindEnv(input ...string) error { return v.BindEnv(input...) } +// EnvPrefix will be used when set. +func BindEnv(input ...string) error { return v.BindEnv(input...) } +func BindEnvNoPrefix(input ...string) error { return v.BindEnvNoPrefix(input...) } func (v *Viper) BindEnv(input ...string) error { if len(input) == 0 { @@ -1253,7 +1254,33 @@ func (v *Viper) BindEnv(input ...string) error { if len(input) == 1 { v.env[key] = append(v.env[key], v.mergeWithEnvPrefix(key)) } else { - v.env[key] = append(v.env[key], input[1:]...) + for _, otherKey := range input[1:] { + v.env[key] = append(v.env[key], v.mergeWithEnvPrefix(otherKey)) + } + } + + return nil +} + +// BindEnvNoPrefix binds a Viper key to a ENV variable. +// ENV variables are case sensitive. +// If only a key is provided, it will use the env key matching the key, uppercased. +// If more arguments are provided, they will represent the env variable names that +// should bind to this key and will be taken in the specified order. +// EnvPrefix will not be used even when set. +func (v *Viper) BindEnvNoPrefix(input ...string) error { + if len(input) == 0 { + return fmt.Errorf("missing key to bind to") + } + + key := strings.ToLower(input[0]) + + if len(input) == 1 { + v.env[key] = append(v.env[key], strings.ToUpper(key)) + } else { + for _, otherKey := range input[1:] { + v.env[key] = append(v.env[key], strings.ToUpper(otherKey)) + } } return nil diff --git a/viper_test.go b/viper_test.go index 4dc52ac..36d008d 100644 --- a/viper_test.go +++ b/viper_test.go @@ -658,10 +658,10 @@ func TestEnvPrefix(t *testing.T) { SetEnvPrefix("foo") // will be uppercased automatically BindEnv("id") - BindEnv("f", "FOOD") // not using prefix + BindEnv("f", "FOOD") t.Setenv("FOO_ID", "13") - t.Setenv("FOOD", "apple") + t.Setenv("FOO_FOOD", "apple") t.Setenv("FOO_NAME", "crunk") assert.Equal(t, "13", Get("id")) @@ -694,6 +694,48 @@ func TestAutoEnvWithPrefix(t *testing.T) { assert.Equal(t, "13", Get("bar")) } +func TestAutoEnvWithPrefixAndOthers(t *testing.T) { + Reset() + + AutomaticEnv() + replacer := strings.NewReplacer("-", "_", ".", "_") + SetEnvKeyReplacer(replacer) + SetEnvPrefix("foo") + BindEnv([]string{"bar", "baz.id", "qux"}...) + + t.Setenv("FOO_BAZ_ID", "13") + + assert.Equal(t, "13", Get("bar")) +} + +func TestAutoEnvWithPrefixAndOthersNoPrefixArray(t *testing.T) { + Reset() + + AutomaticEnv() + replacer := strings.NewReplacer("-", "_", ".", "_") + SetEnvKeyReplacer(replacer) + SetEnvPrefix("foo") + BindEnvNoPrefix([]string{"bar", "OTHER"}...) + + t.Setenv("OTHER", "13") + + assert.Equal(t, "13", Get("bar")) +} + +func TestAutoEnvWithPrefixAndOthersNoPrefixSingle(t *testing.T) { + Reset() + + AutomaticEnv() + replacer := strings.NewReplacer("-", "_", ".", "_") + SetEnvKeyReplacer(replacer) + SetEnvPrefix("foo") + BindEnvNoPrefix([]string{"bar"}...) + + t.Setenv("BAR", "13") + + assert.Equal(t, "13", Get("bar")) +} + func TestSetEnvKeyReplacer(t *testing.T) { Reset()