fix: When a Grammar combines flags with passthrough args, see if an unrecognized flag may be treated as a positional argument (#435)
* ci: Add a test for positional args that are passthrough on a command that isn't passthrough
* fix: When a Grammar combines flags with passthrough args, see if an unrecognized flag may be treated as a positional argument
Given a grammar like this:
```golang
var cli struct {
Args []string `arg:"" optional:"" passthrough:""`
}
```
The first positional argument implies that it was preceded by `--`, so subsequent flags are not parsed.
If Kong parses `cli 1 --unknown 3`, it will populate `Args` with `[]string{"1", "--unknown", "3"}`.
However, if Kong parses `cli --unknown 2 3`, it will fail saying that `--unknown` is an unrecognized flag.
This commit changes the parser so that if an unknown flag _could_ be treated as the first passthrough argument, it is.
After this change, if Kong parses `cli --unknown 2 3`, it will populate `Args` with `[]string{"--unknown", "2", "3"}`.
* ci: Skip the `maintidx` linter for `trace()`
This commit is contained in:
@@ -1526,6 +1526,54 @@ func TestEnumValidation(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestPassthroughArgs(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
args []string
|
||||
flag string
|
||||
cmdArgs []string
|
||||
}{
|
||||
{
|
||||
"NoArgs",
|
||||
[]string{},
|
||||
"",
|
||||
[]string(nil),
|
||||
},
|
||||
{
|
||||
"RecognizedFlagAndArgs",
|
||||
[]string{"--flag", "foobar", "something"},
|
||||
"foobar",
|
||||
[]string{"something"},
|
||||
},
|
||||
{
|
||||
"DashDashBeforeRecognizedFlag",
|
||||
[]string{"--", "--flag", "foobar"},
|
||||
"",
|
||||
[]string{"--flag", "foobar"},
|
||||
},
|
||||
{
|
||||
"UnrecognizedFlagAndArgs",
|
||||
[]string{"--unrecognized-flag", "something"},
|
||||
"",
|
||||
[]string{"--unrecognized-flag", "something"},
|
||||
},
|
||||
}
|
||||
for _, test := range tests {
|
||||
test := test
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
var cli struct {
|
||||
Flag string
|
||||
Args []string `arg:"" optional:"" passthrough:""`
|
||||
}
|
||||
p := mustNew(t, &cli)
|
||||
_, err := p.Parse(test.args)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, test.flag, cli.Flag)
|
||||
assert.Equal(t, test.cmdArgs, cli.Args)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestPassthroughCmd(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
|
||||
Reference in New Issue
Block a user