This commit changes the flag groups feature logic. New implementation is more clean, readable and extendable (hope it won't be just my opinion).
The following changes have been made:
1. Main change:
Flags annotating by "cobra_annotation_required_if_others_set" and "cobra_annotation_mutually_exclusive" annotations was removed as well as all related and hard-to-understand "hacks" to combine flags back into groups on validation process.
Instead, `flagGroups` field was added to the `Command` struct. `flagGroups` field is a list of (new) structs `flagGroup`, which represents the "relationships" between flags within the command.
2. "Required together" and "mutually exclusive" groups logic was updated by implementing `requiredTogetherFlagGroup` and `mutuallyExclusiveFlagGroup` `flagGroup`s.
3. `enforceFlagGroupsForCompletion` `Command`'s method was renamed to `adjustByFlagGroupsForCompletions`.
4. Groups failed validation error messages were changed:
- `"if any flags in the group [...] are set they must all be set; missing [...]"` to `"flags [...] must be set together, but [...] were not set"`
- `"if any flags in the group [...] are set none of the others can be; [...] were all set"` to `"exactly one of the flags [...] can be set, but [...] were set"`
5. Not found flag on group marking error messages were updated from "Failed to find flag %q and mark it as being required in a flag group" and "Failed to find flag %q and mark it as being in a mutually exclusive flag group" to "flag %q is not defined"
6. `TestValidateFlagGroups` test was updated in `flag_groups_test.go`.
- `getCmd` function was updated and test flag names were changed to improve readability
- 2 testcases (`Validation of required groups occurs on groups in sorted order` and `Validation of exclusive groups occurs on groups in sorted order`) were removed, because groups validation now occur in the same order those groups were registered
- other 16 testcases are preserved with updated descriptions, error messages
The completions generation tests that contain flag groups related testcases and updated flag groups tests, as well as all other tests, have been passed.
API was not changed: `MarkFlagsRequiredTogether` and `MarkFlagsMutuallyExclusive` functions have the same signatures.
Fixes#1786
The --help, -h, --version and -v flags are normally added when the
`execute()` function is called on a command. When doing completion
we don't call `execute()` so we need to add these flags explicitly to
the command being completed.
Also, we disable all further completions if the 'help' or 'version'
flags are present on the command-line.
Signed-off-by: Marc Khouzam <marc.khouzam@gmail.com>
Fixes#1562
Programs that don't have sub-commands can accept any number of args.
However, when doing shell completion for such programs, within the
__complete code this very __complete command makes it that the program
suddenly has a sub-command, and the call to Find() -> legacyArgs() will
then return an error if there are more than one argument on the
command-line being completed.
To avoid this, we first remove the __complete command in such a case so
as to get back to having no sub-commands.
Signed-off-by: Marc Khouzam <marc.khouzam@montreal.ca>
When a command has set DisableFlagParsing=true, it means Cobra should
not be handling flags for that command but should let the command
handle them itself. In fact, Cobra normally won't have been told at all
about flags for this command.
Not knowing about the flags of the command also implies that Cobra
cannot perform flag completion as it does not have the necessary info.
This commit still tries to do flag name completion, but when
DisableFlagParsing==true, it continues on so that ValidArgsFunction will
be called; this allows the program to handle completion for its own
flags when DisableFlagParsing==true.
Signed-off-by: Marc Khouzam <marc.khouzam@montreal.ca>
* Fix flag completion
The flag completion functions should not be stored in the root cmd.
There is no requirement that the root cmd should be the same when
`RegisterFlagCompletionFunc` was called. Storing the flags there does
not work when you add the the flags to your cmd struct before you add the
cmd to the parent/root cmd. The flags can no longer be found in the rigth
place when the completion command is called and thus the flag completion
does not work.
Also #1423 claims that this would be thread safe but we still have a map
which will fail when accessed concurrently. To truly fix this issue use a
RWMutex.
Fixes#1437Fixes#1320
Signed-off-by: Paul Holzinger <pholzing@redhat.com>
* Fix trailing whitespaces in fish comp scripts
Signed-off-by: Paul Holzinger <pholzing@redhat.com>
zsh is now the default on Mac OS, but the $_fpath version of the installation instructions are likely to put the completion in a strange location that the user might not expect (e.g. an oh-my-zsh plugin's function directory). So, since Mac OS seems to (as far as I can tell) provide a stable location, this PR recommends using that path instead.
If the interspersed option is set false and one arg is already set all
following arguments are counted as arg and not parsed as flags. Because
of that we should not offer flag completion. The same applies to arguments
followed after `--`.
Signed-off-by: Paul Holzinger <paul.holzinger@web.de>
* Bash completion v2
This v2 version of bash completion is based on Go completions.
It also supports descriptions like the other shells.
Signed-off-by: Marc Khouzam <marc.khouzam@montreal.ca>
* Only consider matching completions for formatting
Signed-off-by: Marc Khouzam <marc.khouzam@montreal.ca>
* Use bash compV2 for the default completion command
Signed-off-by: Marc Khouzam <marc.khouzam@montreal.ca>
* Update comments that still referred to bash completion
Signed-off-by: Marc Khouzam <marc.khouzam@montreal.ca>
Fixes#1211
When handling ShellCompDirectiveNoSpace we must still properly handle
descriptions. To do so we cannot simply use 'compadd', but must use
zsh's '_describe' function.
Also, when handling ShellCompDirectiveNoSpace we cannot assume that
only a single completion will be given to the script. In fact,
ValidArgsFunction can return multiple completions, even if they don't
match the 'toComplete' argument prefix. Therefore, we cannot use the
number of completions received in the completion script to determine
if we should activate the "no space" directive. Instead, we can leave
it all to the '_describe' function.
Fixes#1212
When handling ShellCompDirectiveNoFileComp we cannot base ourself on
the script receiving no valid completion. In fact,
ValidArgsFunction can return multiple completions, even if they don't
match the 'toComplete' argument prefix at all. Therefore, we cannot use
the number of completions received by the completion script to determine
if we should activate the "no file comp" directive. Instead, we can
check if the '_describe' function has found any completions.
Finally, it is important for the script to return the return code of the
called zsh functions (_describe, _arguments). This tells zsh if
completions were found or not, which if not, will trigger different
matching attempts, such as matching what the user typed with the the
content of possible completions (instead of just as the prefix).
Signed-off-by: Marc Khouzam <marc.khouzam@montreal.ca>
Flag definitions like `-asd` are not handled correctly by
the custom completion logic. They should be treated as
multiple flags. For details refer to #1257.
Fixes#1257
Signed-off-by: Paul Holzinger <paul.holzinger@web.de>
Make it easier for programs to provide shell completion by creating
the 'completion' command automatically.
If a 'completion' command is already provided by the program, Cobra
will use that one instead.
Signed-off-by: Marc Khouzam <marc.khouzam@montreal.ca>