Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

basicflag Provider does not exclude default values #255

Closed
jkroepke opened this issue Nov 26, 2023 · 3 comments
Closed

basicflag Provider does not exclude default values #255

jkroepke opened this issue Nov 26, 2023 · 3 comments
Labels
bug Something isn't working

Comments

@jkroepke
Copy link

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`
@jkroepke jkroepke added the bug Something isn't working label Nov 26, 2023
@knadh
Copy link
Owner

knadh commented Nov 27, 2023

Hi @jkroepke. Isn't this the same behaviour as described in #254?

@jkroepke
Copy link
Author

Correct. But my proposal was closed, but the bug still exists.

knadh added a commit that referenced this issue Dec 15, 2023
…ag's default value behaviour in basic flag. Closes #255.
@knadh
Copy link
Owner

knadh commented Dec 15, 2023

I took a slightly different approach here without having to break Provider()'s backwards compatibility. It's a bit hacky, but preserves old behaviour and can take more options and config in the future. Please take a look at #259

basicflag.Provider(flags, ".", &basicflag.Opt{KeyMap: existingKoanfInstance}), nil)

@knadh knadh closed this as completed in 09d28ae Dec 19, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants