Skip to content

Commit

Permalink
fix!: Include -- in passthrough args (#436)
Browse files Browse the repository at this point in the history
Given a grammar like this:

```golang
var cli struct {
        Args []string `arg:"" optional:"" passthrough:""`
}
```

If Kong parses `cli foo -- bar`, it will populate `Args` with `[]string{"foo", "--", "bar"}` (including "`--`").
However, if Kong parses `cli -- foo bar`, will populate `Args` with `[]string{"foo", "bar"}` (leaving off `"--"`).

This differs from the behavior of a passthrough Command, where `"--"` is included with the args in both cases.

There are 3 places where `c.endParsing()` is called
1. When `node.Passthrough` is true: https://github.com/alecthomas/kong/blob/5f9c5cc822bdb888a3671c44d4688a6f602ecb90/context.go#L366-L368
2. When `arg.Passthrough` is true: https://github.com/alecthomas/kong/blob/5f9c5cc822bdb888a3671c44d4688a6f602ecb90/context.go#L451-L453
3. When `"--"` is encountered: https://github.com/alecthomas/kong/blob/5f9c5cc822bdb888a3671c44d4688a6f602ecb90/context.go#L384-L387

The first two do not also pop any tokens. The third one does.

This commit makes `c.scan.Pop()` conditional, skipping it when the next positional argument is passthrough.

I believe this will cause Kong to behave a little more consistently — and from my perspective, `--` is relevant for args intended to be passed through! — but it will change the behavior of existing projects that use `arg:"" passthrough:""`.
  • Loading branch information
boblail authored Sep 11, 2024
1 parent 4ecb535 commit 9924ec4
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 3 deletions.
6 changes: 5 additions & 1 deletion context.go
Original file line number Diff line number Diff line change
Expand Up @@ -383,9 +383,13 @@ func (c *Context) trace(node *Node) (err error) { //nolint: gocyclo

// Indicates end of parsing. All remaining arguments are treated as positional arguments only.
case v == "--":
c.scan.Pop()
c.endParsing()

// Pop the -- token unless the next positional argument accepts passthrough arguments.
if !(positional < len(node.Positional) && node.Positional[positional].Passthrough) {
c.scan.Pop()
}

// Long flag.
case strings.HasPrefix(v, "--"):
c.scan.Pop()
Expand Down
10 changes: 8 additions & 2 deletions kong_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1743,10 +1743,16 @@ func TestPassthroughArgs(t *testing.T) {
[]string{"something"},
},
{
"DashDashBeforeRecognizedFlag",
"DashDashBetweenArgs",
[]string{"foo", "--", "bar"},
"",
[]string{"foo", "--", "bar"},
},
{
"DashDash",
[]string{"--", "--flag", "foobar"},
"",
[]string{"--flag", "foobar"},
[]string{"--", "--flag", "foobar"},
},
{
"UnrecognizedFlagAndArgs",
Expand Down

0 comments on commit 9924ec4

Please sign in to comment.