From 4ad4c8df70ec1bed8329e5d986f09d34f66200b4 Mon Sep 17 00:00:00 2001 From: Mark Sagi-Kazar Date: Fri, 6 Dec 2019 14:11:31 +0100 Subject: [PATCH] Add string replacer interface and env key replacer option --- README.md | 3 +++ viper.go | 15 ++++++++++++++- viper_test.go | 9 +++++++++ 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index b0392c9..327308b 100644 --- a/README.md +++ b/README.md @@ -263,6 +263,9 @@ keys to an extent. This is useful if you want to use `-` or something in your `Get()` calls, but want your environmental variables to use `_` delimiters. An example of using it can be found in `viper_test.go`. +Alternatively, you can use `EnvKeyReplacer` with `NewWithOptions` factory function. +Unlike `SetEnvKeyReplacer`, it accepts a `StringReplacer` interface allowing you to write custom string replacing logic. + By default empty environment variables are considered unset and will fall back to the next configuration source. To treat empty environment variables as set, use the `AllowEmptyEnv` method. diff --git a/viper.go b/viper.go index 4e4d6da..19f15d8 100644 --- a/viper.go +++ b/viper.go @@ -197,7 +197,7 @@ type Viper struct { envPrefix string automaticEnvApplied bool - envKeyReplacer *strings.Replacer + envKeyReplacer StringReplacer allowEmptyEnv bool config map[string]interface{} @@ -257,6 +257,19 @@ func KeyDelimiter(d string) Option { }) } +// StringReplacer applies a set of replacements to a string. +type StringReplacer interface { + // Replace returns a copy of s with all replacements performed. + Replace(s string) string +} + +// EnvKeyReplacer sets a replacer used for mapping environment variables to internal keys. +func EnvKeyReplacer(r StringReplacer) Option { + return optionFunc(func(v *Viper) { + v.envKeyReplacer = r + }) +} + // NewWithOptions creates a new Viper instance. func NewWithOptions(opts ...Option) *Viper { v := New() diff --git a/viper_test.go b/viper_test.go index 9f4dff3..8f010c7 100644 --- a/viper_test.go +++ b/viper_test.go @@ -549,6 +549,15 @@ func TestSetEnvKeyReplacer(t *testing.T) { assert.Equal(t, "30s", Get("refresh-interval")) } +func TestEnvKeyReplacer(t *testing.T) { + v := NewWithOptions(EnvKeyReplacer(strings.NewReplacer("-", "_"))) + + v.AutomaticEnv() + _ = os.Setenv("REFRESH_INTERVAL", "30s") + + assert.Equal(t, "30s", v.Get("refresh-interval")) +} + func TestAllKeys(t *testing.T) { initConfigs()