-
Notifications
You must be signed in to change notification settings - Fork 60
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
fix: --long= should not consume the next argument #139
base: main
Are you sure you want to change the base?
Conversation
I added a couple of tests to confirm that (1) for a boolean, In the parsing code, I tried to minimize changes, but while I was there I updated two comments to reflect that only long flags were at issue, and I changed I considered adding a further test (like below) for {
Name: "--flt= -a",
Constructors: []fftest.Constructor{fftest.CoreConstructor},
Args: []string{`--flt=`, `-a`},
Want: fftest.Vars{WantParseErrorIs: strconv.ErrSyntax},
}, |
flag_set.go
Outdated
if value == "" && !eqFound { | ||
switch { | ||
case f.isBoolFlag: | ||
value = "true" // `-b` or `--foo` default to true | ||
value = "true" // `--foo` defaults to true | ||
if len(args) > 0 { | ||
if _, err := strconv.ParseBool(args[0]); err == nil { | ||
value = args[0] // `-b true` or `--foo false` should also work | ||
value = args[0] // `--foo false` should also work | ||
args = args[1:] | ||
} | ||
} | ||
case !f.isBoolFlag && len(args) > 0: | ||
value, args = args[0], args[1:] | ||
case !f.isBoolFlag && len(args) <= 0: | ||
case !f.isBoolFlag && len(args) == 0: | ||
return nil, fmt.Errorf("missing value") | ||
default: | ||
panic("unreachable") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The complexity of this code is outstanding
if value == "" && !eqFound {
switch {
case f.isBoolFlag:
value = "true" // `--foo` defaults to true
if len(args) > 0 {
if _, err := strconv.ParseBool(args[0]); err == nil {
value = args[0] // `--foo false` should also work
args = args[1:]
}
}
case !f.isBoolFlag && len(args) > 0:
value, args = args[0], args[1:]
case !f.isBoolFlag && len(args) == 0:
return nil, fmt.Errorf("missing value")
default:
panic("unreachable")
}
}
Unless I'm wrong, it could be this
if value == "" && !eqFound {
switch {
case f.isBoolFlag:
value = "true" // `--foo` defaults to true
if len(args) > 0 {
if _, err := strconv.ParseBool(args[0]); err == nil {
value = args[0] // `--foo false` should also work
args = args[1:]
}
}
case len(args) > 0:
value, args = args[0], args[1:]
default:
return nil, fmt.Errorf("missing value")
}
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are not wrong. Thanks.
if len(args) > 0 { | ||
if _, err := strconv.ParseBool(args[0]); err == nil { | ||
value = args[0] // `-b true` or `--foo false` should also work | ||
value = args[0] // `--foo false` should also work | ||
args = args[1:] | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is also something strange with the code (the code that already exists)
Let's assume --foo expects a string
--foo leads to an error
--foo true leads to "true"
--foo=1 leads to "1"
--foo=false leads to "false"
--foo= leads to ""
But if --foo is a boolean
--foo false
--foo whatever
--foo 0
--foo 2
--foo=2
Leads to this
--foo=false
--foo whatever
--foo=false
--foo=true 2
an error
This behavior is strange to me, but I'm unsure how other libraries parsing flags do
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The difference between --foo 2
and --foo=2
is...not great. That is probably why flag
in Go's standard library restricts the form --flag arg
to non-boolean flags.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Exactly
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would be in favor of that here as well, but I think @peterbourgon wants to keep boolean parsing as is. (Also, that would probably be a very breaking API change now. Don't know how that plays with v4 being in beta.)
fba0909
to
a86c7b7
Compare
No description provided.