substitute environment variables when loading yaml config

This commit is contained in:
Andrew Savinykh 2026-02-15 20:36:03 +13:00
parent d22bdebff7
commit 2fe6d306aa
2 changed files with 14 additions and 29 deletions

View File

@ -8,6 +8,7 @@ import (
"sort"
"strings"
"github.com/go-viper/mapstructure/v2"
"github.com/knadh/koanf/parsers/yaml"
"github.com/knadh/koanf/providers/file"
"github.com/knadh/koanf/v2"
@ -51,6 +52,14 @@ func AppendSource(cfg *Config, k *koanf.Koanf, configPath string) {
func unmarshalRoot(k *koanf.Koanf, cfg *Config) bool {
err := k.UnmarshalWithConf("", cfg, koanf.UnmarshalConf{
Tag: "koanf",
DecoderConfig: &mapstructure.DecoderConfig{
DecodeHook: mapstructure.ComposeDecodeHookFunc(
envDecodeHookFunc,
mapstructure.StringToTimeDurationHookFunc(),
mapstructure.TextUnmarshallerHookFunc(),
),
WeaklyTypedInput: true,
},
})
if err != nil {

View File

@ -90,26 +90,19 @@ var envConfigTests = []struct {
}
func TestEnvInConfig(t *testing.T) {
t.Skip("Skipping test in 3k")
for _, tt := range envConfigTests {
cfg := DefaultConfig()
setIfNotEmpty("INPUT", tt.input)
processed := processYamlWithEnv(tt.yaml)
k, err := loadKoanf(processed)
k := koanf.New(".")
err := k.Load(rawbytes.Provider([]byte(tt.yaml)), yaml.Parser())
if err != nil {
t.Errorf("Error loading YAML: %v", err)
continue
}
if err := k.UnmarshalWithConf("", cfg, koanf.UnmarshalConf{
Tag: "koanf",
}); err != nil {
t.Errorf("Error unmarshalling config: %v", err)
continue
}
unmarshalRoot(k, cfg)
field := tt.selector(cfg)
assert.Equal(t, tt.output, field, "Unmarshaled config field doesn't match expected value: env=\"%s\"", tt.input)
assert.Equal(t, tt.output, field,
"Unmarshaled config field doesn't match expected value: env=%q", tt.input)
os.Unsetenv("INPUT")
}
}
@ -119,20 +112,3 @@ func setIfNotEmpty(key, val string) {
os.Setenv(key, val)
}
}
func processYamlWithEnv(content string) string {
return envRegex.ReplaceAllStringFunc(content, func(match string) string {
submatches := envRegex.FindStringSubmatch(match)
key := submatches[1]
val, _ := os.LookupEnv(key)
return val
})
}
func loadKoanf(processed string) (*koanf.Koanf, error) {
k := koanf.New(".")
if err := k.Load(rawbytes.Provider([]byte(processed)), yaml.Parser()); err != nil {
return nil, err
}
return k, nil
}