From 48128aabffb8ba7408128966c66c544e802104b8 Mon Sep 17 00:00:00 2001 From: karantin2020 Date: Sat, 28 Jul 2018 10:21:05 +0500 Subject: [PATCH 1/6] Added option funcs to env backend --- backend/env/env.go | 33 ++++++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/backend/env/env.go b/backend/env/env.go index 94b024f..8051905 100644 --- a/backend/env/env.go +++ b/backend/env/env.go @@ -11,20 +11,35 @@ import ( // NewBackend creates a configuration loader that loads from the environment. // If the key is not found, this backend tries again by turning any kebabcase key to snakecase and // lowercase letters to uppercase. -func NewBackend() backend.Backend { +func NewBackend(fns ...opt) backend.Backend { return backend.Func("env", func(ctx context.Context, key string) ([]byte, error) { - val, ok := os.LookupEnv(key) + val, ok := os.LookupEnv(opts(key, fns...)) if ok { return []byte(val), nil } + return nil, backend.ErrNotFound + }) +} - key = strings.Replace(strings.ToUpper(key), "-", "_", -1) +// WithPreffix adds preffix for searching env variable +func WithPreffix(preffix string) opt { + return func(key string) string { + return preffix + key + } +} - val, ok = os.LookupEnv(key) - if ok { - return []byte(val), nil - } +// ToUpper uppercases searching env variable +func ToUpper() opt { + return func(key string) string { + return strings.Replace(strings.ToUpper(key), "-", "_", -1) + } +} - return nil, backend.ErrNotFound - }) +type opt func(key string) string + +func opts(key string, fns ...opt) string { + for i := range fns { + key = fns[i](key) + } + return key } From 0c7d9c3e7a2f7088ceff2b7a1cae6af20c500e62 Mon Sep 17 00:00:00 2001 From: karantin2020 Date: Sat, 28 Jul 2018 10:34:42 +0500 Subject: [PATCH 2/6] Added older logic to backward compatibility --- backend/env/env.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/backend/env/env.go b/backend/env/env.go index 8051905..8436de4 100644 --- a/backend/env/env.go +++ b/backend/env/env.go @@ -17,6 +17,14 @@ func NewBackend(fns ...opt) backend.Backend { if ok { return []byte(val), nil } + if len(fns) == 0 { + key = strings.Replace(strings.ToUpper(key), "-", "_", -1) + + val, ok = os.LookupEnv(key) + if ok { + return []byte(val), nil + } + } return nil, backend.ErrNotFound }) } From 38b4559e4b632e1a766b4424b033c96649678165 Mon Sep 17 00:00:00 2001 From: karantin2020 Date: Tue, 1 Jan 2019 11:37:30 +0500 Subject: [PATCH 3/6] Cleared env backend processing. Added env backend tests --- backend/env/env.go | 18 ++++----- backend/env/env_test.go | 86 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 93 insertions(+), 11 deletions(-) diff --git a/backend/env/env.go b/backend/env/env.go index 8436de4..d9c5702 100644 --- a/backend/env/env.go +++ b/backend/env/env.go @@ -13,24 +13,20 @@ import ( // lowercase letters to uppercase. func NewBackend(fns ...opt) backend.Backend { return backend.Func("env", func(ctx context.Context, key string) ([]byte, error) { + key = strings.Replace(key, "-", "_", -1) val, ok := os.LookupEnv(opts(key, fns...)) if ok { return []byte(val), nil } - if len(fns) == 0 { - key = strings.Replace(strings.ToUpper(key), "-", "_", -1) - - val, ok = os.LookupEnv(key) - if ok { - return []byte(val), nil - } - } return nil, backend.ErrNotFound }) } -// WithPreffix adds preffix for searching env variable -func WithPreffix(preffix string) opt { +// WithPrefix adds preffix for searching env variable +func WithPrefix(preffix string) opt { + if !strings.HasSuffix(preffix, "_") { + preffix = preffix + "_" + } return func(key string) string { return preffix + key } @@ -39,7 +35,7 @@ func WithPreffix(preffix string) opt { // ToUpper uppercases searching env variable func ToUpper() opt { return func(key string) string { - return strings.Replace(strings.ToUpper(key), "-", "_", -1) + return strings.ToUpper(key) } } diff --git a/backend/env/env_test.go b/backend/env/env_test.go index 904f8b7..8bb42fc 100644 --- a/backend/env/env_test.go +++ b/backend/env/env_test.go @@ -3,6 +3,7 @@ package env import ( "context" "os" + "reflect" "testing" "github.com/heetch/confita/backend" @@ -35,3 +36,88 @@ func TestEnvBackend(t *testing.T) { require.Equal(t, "ok", string(val)) }) } + +func TestOpts(t *testing.T) { + type args struct { + fns []opt + key string + } + tests := []struct { + name string + args args + want string + }{ + { + name: "Test opts positive", + args: args{ + fns: []opt{ + ToUpper(), + WithPrefix("TEST_"), + }, + key: "var", + }, + want: "TEST_VAR", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := opts(tt.args.key, tt.args.fns...); !reflect.DeepEqual(got, tt.want) { + t.Errorf("NewBackend() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestWithPrefix(t *testing.T) { + type args struct { + preffix string + key string + } + tests := []struct { + name string + args args + want string + }{ + { + name: "Test add preffix positive", + args: args{ + preffix: "TEST", + key: "VAR", + }, + want: "TEST_VAR", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := WithPrefix(tt.args.preffix)(tt.args.key); !reflect.DeepEqual(got, tt.want) { + t.Errorf("WithPrefix() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestToUpper(t *testing.T) { + type args struct { + key string + } + tests := []struct { + name string + args args + want string + }{ + { + name: "Test add preffix positive", + args: args{ + "test", + }, + want: "TEST", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := ToUpper()(tt.args.key); !reflect.DeepEqual(got, tt.want) { + t.Errorf("ToUpper() = %v, want %v", got, tt.want) + } + }) + } +} From bae8a1218af5c17f33ff104059d5bdff4f124664 Mon Sep 17 00:00:00 2001 From: karantin2020 Date: Tue, 1 Jan 2019 11:43:16 +0500 Subject: [PATCH 4/6] Added env backend test with opts combination --- backend/env/env_test.go | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/backend/env/env_test.go b/backend/env/env_test.go index 8bb42fc..85720b3 100644 --- a/backend/env/env_test.go +++ b/backend/env/env_test.go @@ -58,6 +58,17 @@ func TestOpts(t *testing.T) { }, want: "TEST_VAR", }, + { + name: "Test upper after prefix with lower key", + args: args{ + fns: []opt{ + WithPrefix("test"), + ToUpper(), + }, + key: "var", + }, + want: "TEST_VAR", + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { From 49e74a3882c4daaa45e5b7dc119bb83c2737ba28 Mon Sep 17 00:00:00 2001 From: karantin2020 Date: Tue, 1 Jan 2019 11:51:26 +0500 Subject: [PATCH 5/6] Fix env backend: added lookup for upper-case key if lower-case was not found for old logic compatibility --- backend/env/env.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/backend/env/env.go b/backend/env/env.go index d9c5702..28ed6bf 100644 --- a/backend/env/env.go +++ b/backend/env/env.go @@ -18,6 +18,10 @@ func NewBackend(fns ...opt) backend.Backend { if ok { return []byte(val), nil } + val, ok = os.LookupEnv(opts(strings.ToUpper(key), fns...)) + if ok { + return []byte(val), nil + } return nil, backend.ErrNotFound }) } From 4f002f3f263bde1e235cc64a9fea0866c29e5346 Mon Sep 17 00:00:00 2001 From: karantin2020 Date: Tue, 1 Jan 2019 11:57:16 +0500 Subject: [PATCH 6/6] Added env options example to README file --- README.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index c860ee0..2ab37d3 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ Confita is a library that loads configuration from multiple backends and stores ## Install ```sh -go get -u github.com/heetch/confita +go get -u github.com/karantin2020/confita ``` ## Usage @@ -95,7 +95,10 @@ A loader can take other configured backends as parameters. ```go loader := confita.NewLoader( - env.NewBackend(), + env.NewBackend( + env.WithPrefix("PREFIX"), + env.ToUpper(), + ), file.NewBackend("/path/to/config.json"), file.NewBackend("/path/to/config.yaml"), flags.NewBackend(), @@ -124,7 +127,6 @@ err := loader.Load(ctx, &cfg) If a key is not found, Confita won't change the respective struct field. With that in mind, default values can simply be implemented by filling the structure before passing it to Confita. ```go - type Config struct { Host string `config:"host"` Port uint32 `config:"port"`