knadh / koanf

Simple, extremely lightweight, extensible, configuration management library for Go. Support for JSON, TOML, YAML, env, command line, file, S3 etc. Alternative to viper.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

posflag provider overrides values even if flags are not set for special delimiters

callebjorkell opened this issue · comments

Describe the bug
When loading flags from a cobra application, if using - as the delimiter, existing loaded values are overridden by empty values.

To Reproduce
Given a specified, but unused, pflag s3-bucket and an environment variable MYAPP_S3_BUCKET="five", if I have the following config loading:

        k := koanf.New(".")
	k.Load(env.Provider("MYAPP_", ".", func(s string) string {
		return strings.ReplaceAll(strings.ToLower(
			strings.TrimPrefix(s, "MYAPP_")), "_", ".")
	}), nil)
	k.Load(posflag.Provider(cmd.Flags(), "-", k), nil)

k.String("s3.bucket") will return "" when I have not set the s3-bucket flag for the application, even though the environment variable has a value.

Expected behavior
k.String("s3.bucket") should return "five"

Please provide the following information):

  • OS: linux
  • Koanf v2.1.0, (providers v0.1.0)

Additional context
I think this is because of the delimiter replacement happening only after the "existence check", so the provider is checking if "s3-bucket" exists as a key already in my koanf instance (which it doesn't) and then goes on to apply the delimiter (so "s3.bucket") before merging.

I was able to work around this by passing a callback to the load, rewriting the key value to use dots instead to align with what has already been loaded into the koanf map:

err = k.Load(posflag.ProviderWithValue(cmd.Flags(), ".", k, func(key string, value string) (string, interface{}) {
	return strings.ReplaceAll(key, "-", "."), value
}), nil)

In this way, the overrides work as expected. I assume that wrapping the koanf instance passed to replace the key before checking if it exists would also work, but I haven't tried that.