Add support for negated boolean flags
Will automatically set a boolean Struct field to false if the flag starts with `--no-`, even when the default is `true`.
For example:
```
type Cmd struct {
Output bool `default:"true"`
}
```
Calling
```
command
```
Will set `Output` to `true`, but
```
command --no-output
```
Will set `Output` to `false`.
This commit is contained in:
+8
-1
@@ -579,6 +579,9 @@ func (c *Context) getValue(value *Value) reflect.Value {
|
||||
}
|
||||
c.values[value] = v
|
||||
}
|
||||
if value.Flag != nil && value.Flag.Negated {
|
||||
v.SetBool(false)
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
@@ -639,15 +642,19 @@ func (c *Context) parseFlag(flags []*Flag, match string) (err error) {
|
||||
for _, flag := range flags {
|
||||
long := "--" + flag.Name
|
||||
short := "-" + string(flag.Short)
|
||||
neg := "--no-" + flag.Name
|
||||
candidates = append(candidates, long)
|
||||
if flag.Short != 0 {
|
||||
candidates = append(candidates, short)
|
||||
}
|
||||
if short != match && long != match {
|
||||
if short != match && long != match && neg != match {
|
||||
continue
|
||||
}
|
||||
// Found a matching flag.
|
||||
c.scan.Pop()
|
||||
if flag.Value.IsBool() && match == neg {
|
||||
flag.Negated = true
|
||||
}
|
||||
err := flag.Parse(c.scan, c.getValue(flag.Value))
|
||||
if err != nil {
|
||||
if e, ok := errors.Cause(err).(*expectedError); ok && e.token.InferredType().IsAny(FlagToken, ShortFlagToken) {
|
||||
|
||||
@@ -356,6 +356,19 @@ func TestTraceErrorPartiallySucceeds(t *testing.T) {
|
||||
require.Equal(t, "one", ctx.Command())
|
||||
}
|
||||
|
||||
func TestNegatedBooleanFlag(t *testing.T) {
|
||||
var cli struct {
|
||||
Cmd struct {
|
||||
Flag bool `kong:"default='true'"`
|
||||
} `kong:"cmd"`
|
||||
}
|
||||
|
||||
p := mustNew(t, &cli)
|
||||
_, err := p.Parse([]string{"cmd", "--no-flag"})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, false, cli.Cmd.Flag)
|
||||
}
|
||||
|
||||
type hookContext struct {
|
||||
cmd bool
|
||||
values []string
|
||||
|
||||
Reference in New Issue
Block a user