Closed
Description
Describe the bug
I would like to use koanf with multiple providers in a chain. In my case
defaults (struct) -> file -> env -> flags
The flagset is enriched with default values, because then --help
will display all default values for each option.
With posflag
Provider, everything work fine. Since it will only include changed values. However the basicflag
provider does not have an behavior (see #254)
To Reproduce
package main
import (
"flag"
"fmt"
"github.com/knadh/koanf/providers/basicflag"
"log"
"os"
"strings"
"github.com/knadh/koanf/providers/env"
"github.com/knadh/koanf/providers/structs"
"github.com/knadh/koanf/v2"
)
// Global koanf instance. Use "." as the key path delimiter. This can be "/" or any character.
var k = koanf.New(".")
type parentStruct struct {
Name string `koanf:"name"`
ID int `koanf:"id"`
}
func init() {
os.Setenv("MYVAR_ID", "5000")
}
func main() {
defaults := parentStruct{
Name: "parent1",
ID: 1234,
}
k.Load(structs.Provider(defaults, "koanf"), nil)
k.Load(env.Provider("MYVAR_", ".", func(s string) string {
return strings.Replace(strings.ToLower(
strings.TrimPrefix(s, "MYVAR_")), "_", ".", -1)
}), nil)
f := flag.NewFlagSet("config", flag.ContinueOnError)
f.String("name", defaults.Name, "")
f.Int("id", defaults.ID, "")
f.Parse([]string{"--name", "changed-from-flags"})
if err := k.Load(basicflag.Provider(f, "."), nil); err != nil {
log.Fatalf("error loading config: %v", err)
}
fmt.Printf("id is = `%d`\n", k.Int("id"))
fmt.Printf("name is = `%s`\n", k.String("name"))
}
Output
id is = `1234`
name is = `changed-from-flags`
Expected behavior
A clear and concise description of what you expected to happen.
Defaults values from flagset are not used in final config,
Output
id is = `5000`
name is = `changed-from-flags`
Please provide the following information):
- OS: [e.g. linux/osx/windows]
- Koanf Version [e.g. v1.0.0]
Additional context
Add any other context about the problem here.
With posflag, everything works as expected:
package main
import (
"fmt"
"log"
"os"
"strings"
"github.com/knadh/koanf/providers/env"
"github.com/knadh/koanf/providers/posflag"
"github.com/knadh/koanf/providers/structs"
"github.com/knadh/koanf/v2"
flag "github.com/spf13/pflag"
)
// Global koanf instance. Use "." as the key path delimiter. This can be "/" or any character.
var k = koanf.New(".")
type parentStruct struct {
Name string `koanf:"name"`
ID int `koanf:"id"`
}
func init() {
os.Setenv("MYVAR_ID", "5000")
}
func main() {
defaults := parentStruct{
Name: "parent1",
ID: 1234,
}
k.Load(structs.Provider(defaults, "koanf"), nil)
k.Load(env.Provider("MYVAR_", ".", func(s string) string {
return strings.Replace(strings.ToLower(
strings.TrimPrefix(s, "MYVAR_")), "_", ".", -1)
}), nil)
f := flag.NewFlagSet("config", flag.ContinueOnError)
f.String("name", defaults.Name, "")
f.Int("id", defaults.ID, "")
f.Parse([]string{"--name", "changed-from-flags"})
if err := k.Load(posflag.Provider(f, ".", k), nil); err != nil {
log.Fatalf("error loading config: %v", err)
}
fmt.Printf("id is = `%d`\n", k.Int("id"))
fmt.Printf("name is = `%s`\n", k.String("name"))
}
# id is = `5000`
# name is = `changed-from-flags`
Activity