Closed
Description
Describe the bug
Env Vars Starting with USER
not loading
To Reproduce
package config
import (
"errors"
"fmt"
"github.com/knadh/koanf/providers/env"
"github.com/knadh/koanf/v2"
"os"
"reflect"
"strings"
"testing"
)
type Config struct {
loader *koanf.Koanf
}
var (
ErrFailedToLoadFromEnv = errors.New("failed to load from env")
ErrFailedToUnmarshalToStruct = errors.New("failed to unmarshal to struct")
)
const (
emptyPrefix = ""
emptyDelim = ""
emptyPath = ""
)
// New constructs a new config receiver
func New() *Config {
c := &Config{
loader: koanf.New(emptyDelim),
}
return c
}
// Hydrate takes a pointer to config and hydrates it
func (c *Config) Hydrate(cfgStruct any) error {
// Load environment variables and merge into the loaded config.
// emptyPrefix and emptyDelim. There is no env prefix and we do not need a delimiter
if err := c.loader.Load(env.Provider(emptyPrefix, emptyDelim, func(s string) string {
return strings.ToLower(s)
}), nil); err != nil {
return fmt.Errorf("%w: %v", ErrFailedToLoadFromEnv, err)
}
// Unmarshal to `config` tags using "FlatPaths" -> ie, don't bother with nesting config
if err := c.loader.UnmarshalWithConf(emptyPath, cfgStruct, koanf.UnmarshalConf{
Tag: "config",
FlatPaths: true,
}); err != nil {
return fmt.Errorf("%w: %v", ErrFailedToUnmarshalToStruct, err)
}
return nil
}
type TestConfig struct {
ValueHere string `config:"value_here"`
UserValueHere string `config:"user_value_here"`
}
func TestHydrate(test *testing.T) {
cases := []struct {
name string
input any
envVals map[string]string
expectedOutput any
expectedError error
}{
{
name: "env values set correctly",
input: TestConfig{},
envVals: map[string]string{
"USER_VALUE_HERE": "hi",
"VALUE_HERE": "hello",
},
expectedOutput: TestConfig{
UserValueHere: "hi",
ValueHere: "hello",
},
},
}
for _, c := range cases {
test.Run(c.name, func(t *testing.T) {
for k, v := range c.envVals {
if err := os.Setenv(k, v); err != nil {
t.Fatal("failed to set env var", err)
}
defer os.Unsetenv(k)
}
conf := New()
var toHydrate TestConfig
if err := conf.Hydrate(&toHydrate); !errors.Is(err, c.expectedError) {
t.Fatalf("mismatched errors - expected %v, got %v", c.expectedError, err)
}
if !reflect.DeepEqual(toHydrate, c.expectedOutput) {
t.Fatalf("mismatched results - expected %v, got %v", c.expectedOutput, toHydrate)
}
})
}
}
Expected behavior
Both env vars are mapped to the input struct
Please provide the following information):
- OS: mac
- Koanf Version v2.1.1
Activity