When creating a plugin without sub commands, the help text included the
command name (kubectl-plugin) instead of the display name (kubectl plugin):
Usage:
kubectl-plugin [flags]
The issue is that the usage line for this case does not use the
command path but the raw `Use` string, and this case was not tested.
Add a test for this case and fix UsageLine() to replace the command name
with the display name.
Tested using https://github.com/nirs/kubernetes/tree/sample-cli-plugin-help
When using `CommandDisplayNameAnnotation` we want to use it instead of
the command name in `--help` message or in the default help command.
With current code we get the wrong text in the --help usage text:
Flags:
-h, --help help for kubectl-plugin
And in the long description of the default help command:
$ kubectl cobraplugin help -h
Help provides help for any command in the application.
Simply type kubectl-plugin help [path to command] for full details.
The issue was hidden since the test checked only the Usage line.
Fixed by extracting a displayName() function and use it when creating
FlagSet and when formatting the default help flag usage and the help
command long description.
Enhance the TestPlugin to check all the lines including the command
name.
* Avoid redundant string splits
There likely isn't actually more than once to split in the source
strings in these cases, but avoid doing so anyway as we're only
interested in the first.
* Avoid redundant completion output target evaluations
The target is not to be changed while outputting completions, so resolve
it only once.
* Avoid redundant active help enablement evaluations
The enablement state is not to be changed during completion output, so
evaluate it only once.
* Preallocate some slices and maps with known size
* Avoid some unnecessary looping
* Use strings.Builder to construct suggestions
In the bash shell we used to print ActiveHelp messages on every
tab-press. In the example below, notice the "Command help" line which is
ActiveHelp:
bash-5.1$ tanzu context u[tab]
Command help: Configure and manage contexts for the Tanzu CLI
bash-5.1$ tanzu context u[tab]
Command help: Configure and manage contexts for the Tanzu CLI
bash-5.1$ tanzu context u
unset (Unset the active context so that it is not used by default.)
use (Set the context to be used by default)
bash-5.1$ tanzu context u
Above, on the first [tab] press, only the ActiveHelp is printed.
On the second [tab] press, the ActiveHelp is printed again, followed
by a re-print of the command-line, followed by the completions choices.
The separation between ActiveHelp and completion choices makes the
ActiveHelp harder to see. Furthermore, I find the double printing of the
ActiveHelp string to look bad.
Note that for zsh, the UX is different and that ActiveHelp messages are
printed at the same time as the completion choices.
This commit aligns the UX for ActiveHelp in bash with the one for zsh:
if there are other completions to be shown, the ActiveHelp messages are
printed at the same time.
New behaviour:
1- ActiveHelp is no longer printed on the first [tab] press. This is
better aligned with bash's standard approach.
2- ActiveHelp is printed on the second [tab] press, above the completion
choices, with a `--` delimiter.
3- If there are no completion choices, the `--` delimiter is omitted.
This behaviour is the same as what is done for zsh (except that for zsh
the first [tab] press immediately shows completion choices).
Below is the above example, but using this commit.
Notice the more concise and easier to read completion output:
bash-5.1$ tanzu context u[tab][tab]
Command help: Configure and manage contexts for the Tanzu CLI
--
unset (Unset the active context so that it is not used by default.)
use (Set the context to be used by default)
bash-5.1$ tanzu context u
Signed-off-by: Marc Khouzam <marc.khouzam@gmail.com>
The new API is simpler and matches the `c.RegisterFlagCompletionFunc()`
API. By removing the global function `GetFlagCompletion()` we are more
future proof if we ever move from a global map of flag completion
functions to something associated with the command.
The commit also makes this API work with persistent flags by using
`c.Flag(flagName)` instead of `c.Flags().Lookup(flagName)`.
The commit also adds unit tests.
Signed-off-by: Marc Khouzam <marc.khouzam@gmail.com>
In this case the executable is `kubectl-plugin`, but we run it as:
kubectl plugin
And the help text should reflect the actual usage of the command.
To create a plugin, add the cobra.CommandDisplayNameAnnotation:
rootCmd := &cobra.Command{
Use: "plugin",
Annotations: map[string]string{
cobra.CommandDisplayNameAnnotation: "kubectl plugin",
}
}
Internally this change modifies CommandPath() for the root command to
return the command display name instead of the command name. This is
used for error messages, help text generation, and completions.
CommandPath() is expected to have spaces and code using it already
handle spaces (e.g replacing with _), so hopefully this does not break
anything.
Fixes: #2017
Signed-off-by: Nir Soffer <nsoffer@redhat.com>
* Replace all non-alphanumerics in active help env var program prefix
There are other characters besides the dash that are fine in program
names, but are problematic in environment variable names. These include
(but are not limited to) period, space, and non-ASCII letters.
* Another change in docs to mention non-ASCII-alphanumeric instead of just dash
Fixes#2060
When a command sets `DisableFlagParsing = true` it requests the
responsibility of doing all the flag parsing. Therefore even the
`--help/-f/--version/-v` flags should not be automatically completed
by Cobra in such a case.
Without this change the `--help/-h/--version/-v` flags can end up being
completed twice for plugins: one time from cobra and one time from the
plugin (which has set `DisableFlagParsing = true`).
Signed-off-by: Marc Khouzam <marc.khouzam@gmail.com>
Currently, only one of the persistent pre-runs and post-runs is executed.
It is always the first one found in the parents chain, starting at this command.
Expected behavior is to execute all parents' persistent pre-runs and post-runs.
Dependent projects implemented various workarounds for this:
- manually building persistent hook chains (in every hook).
- applying some kind of monkey-patching on top of Cobra.
This change eliminates the necessity for such workarounds
by allowing to set a global variable EnableTraverseRunHooks.
Tickets:
- https://github.com/spf13/cobra/issues/216
- https://github.com/spf13/cobra/issues/252
Signed-off-by: Volodymyr Khoroz <volodymyr.khoroz@foundries.io>
This fixes an issue with program names that include a dot, in our case
`podman.exe`. This was caused by the change in commit 6ba7ebbc.
Fixes#1853
Signed-off-by: Paul Holzinger <pholzing@redhat.com>
Use temporary files instead of assuming the current directory is
writable. Also, if creating a temporary file still returns an error,
prevent the test from failing silently by replacing `log.Fatal` with
`t.Fatal`.
The use in generated bash completion files is getting flagged by
Lintian (the Debian package linting tool).
Signed-off-by: Taavi Väänänen <hi@taavi.wtf>