`passthrough:""` or `passthrough:"all"` (the default) will pass through
all further arguments including unrecognised flags.
`passthrough:"partial"` will validate flags up until the `--` or the
first positional argument, then pass through all subsequent flags and
arguments.
This allows provider functions to accept parameters that are injected by other
bindings or binding providers, eg. call the provider function with the root CLI
struct (which is automatically bound by Kong):
kong.BindToProvider(func(cli *CLI) (*Injected, error) { ... })
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:""`.
* fix: Check if negatable duplicates another flag
Add a check for flags with the `negatable` option if the negative flag
conflicts with another tag, such as:
Flag bool `negatable:""`
NoFlag bool
The flag `--no-flag` is ambiguous in this scenario.
* feat: Make negatable flag name customisable
Allow a value on the `negatable` tag to specify a flag name to use for
negation instead of using `--no-<flag-name>` as the flag.
e.g.
Approve bool `default:"true",negatable:"deny"`
This example will allow `--deny` to set the `Approve` field to false.
* Docs: Clean and group description
* Feat: Add check for overlapping xor and and groups
Co-authored-by: inful <jone.marius@vign.es>
* Chore: Rewrite overlap err to avoid duplicated words
---------
Co-authored-by: inful <jone.marius@vign.es>
* Feat: Add xand group and check for missing
* Fix: Split and combine err in TestMultiand for consistency
* Feat: Check missing required flags in xand groups
* Feat: Handle combined xor and xand
* Docs: Add info about combined xand and required use
* Docs: Fix language error in xand description
Co-authored-by: Stautis <thkrst@gmail.com>
* Feat: Rename xand to and
* Refactor: Switch from fmt.Sprintf to err.Error
* Refactor: Get requiredAndGroup map in separate function
---------
Co-authored-by: Stautis <thkrst@gmail.com>
* feat: allow non-structs to be used as commands
This small MR allows using the func-to-interface trick to implement a command (see commandFunc in kong_test.go).
This is useful e.g. for commands that have no flags or arguments of their own, but instead receive all required information via bound parameters.
* fix: check DynamicCommand is runnable when adding
* 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()`