basicflag keymap opt does not respect key delimiter
Describe the bug
When specifying basicflag.Provider(f, "-", &basicflag.Opt{KeyMap: k}), the basicflag provider checks whether the given config key already exists in the koanf config instance, and, if so, does not overwrite it with the flag default. This, however, does not consider the delimiter argument. If, for example, the given Koanf already contains a key db.password, a flag db-password unconditionally overwrites it with the flag default, as the key db-password does not exist in the Koanf instance.
To Reproduce
Create a config yaml test.yaml:
db:
password: "test"
Then run:
k := koanf.New(".")
configPath := "./test.yaml"
if err := k.Load(file.Provider(configPath), &yaml.YAML{}); err != nil {
log.Fatalf("Could not load config file at %v: %v", configPath, err)
}
log.Printf("%v", k.All()) // contains db.password: test
f := flag.NewFlagSet("test", flag.ExitOnError)
f.String("db-password", "default-password", "Password of database")
f.Parse(os.Args[1:])
if err := k.Load(basicflag.Provider(f, "-", &basicflag.Opt{KeyMap: k}), nil); err != nil {
log.Fatalf("Could not set config from command line flags: %v", configPath, err)
}
log.Printf("%v", k.All()) // contains db.password: default-password, should be "test"
Additional context
This seems to be related to this line:
https://github.com/knadh/koanf/blob/733704a14a359ca9b3d78fead1839f7af871f8d1/providers/basicflag/basicflag.go#L126
I suppose one would need to replace all occurances of the p.delim in the key with the Koanf instance's delimiter before testing the map.
This is a tricky one. Whether the default value in the flags should overwrite a previously loaded key (given that they all have the same delimiters) can be context-dependent. db.password and db-password (where - is the delimiter) both represents {"db": {"password": "..."}}
Could you not use ProviderWithValue() to get control over the key in the basicflag parser to treat it differently depending on your context?