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

Value's that implement IsBoolFlag() always show a default value #360

Open
twelvelabs opened this issue Sep 22, 2022 · 0 comments · May be fixed by #361
Open

Value's that implement IsBoolFlag() always show a default value #360

twelvelabs opened this issue Sep 22, 2022 · 0 comments · May be fixed by #361

Comments

@twelvelabs
Copy link

I've implemented a custom Value type for managing generic data. Everything works as it should, but the flags always show a default in their usage string regardless of whether they have a zero value:

type Value struct {
    data     interface{}
    dataType string
}

func (v *Value) String() string {
    return cast.ToString(v.Get())
}

func (v *Value) Get() interface{} {
    return v.data
}

func (v *Value) Set(data string) error {
    // validates, casts, and sets v.data using v.Type()
}

func (v *Value) Type() string {
    return v.dataType
}

func (v *Value) IsBoolFlag() bool {
    return v.Type() == "bool"
}


func main() {
    value := &Value{
        data: "",
        dataType: "string",
    }
    pflag.Var(value, "project-name", "Some usage text")
    pflag.Parse()
    // Prints:
    // --project-name string   Some usage text (default "")
    pflag.Usage()


    flag := pflag.Lookup("project-name")
    // Prints:
    // default: '', isZero: false
    fmt.Printf("default: %q, isZero: %v", flag.DefValue, flag.defaultIsZeroValue())
}

The issue seems to be caused here - by checking for whether the value implements the boolFlag interface (rather than the return value of IsBoolFlag()):

pflag/flag.go

Lines 536 to 541 in d5e0c06

// defaultIsZeroValue returns true if the default value for this flag represents
// a zero value.
func (f *Flag) defaultIsZeroValue() bool {
switch f.Value.(type) {
case boolFlag:
return f.DefValue == "false"

Seems like the fix would be to move the boolFlag check prior to the switch statement and have it actually call IsBoolFlag(), like so:

    if bf, ok := f.Value.(boolFlag); ok && bf.IsBoolFlag() {
        return f.DefValue == "false"
    }
    switch f.Value.(type) { ... }

Then custom values would make it through to the default case in the switch statement.

twelvelabs added a commit to twelvelabs/pflag that referenced this issue Sep 22, 2022
The defaultIsZeroValue() method was erroneously assuming that all types that implement IsBoolFlag() were bools - regardless of the return value of IsBoolFlag().

Fixes spf13#360
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant