-
Notifications
You must be signed in to change notification settings - Fork 2.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: Marc Khouzam <marc.khouzam@montreal.ca>
- Loading branch information
1 parent
c1973d3
commit c47be85
Showing
10 changed files
with
330 additions
and
32 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,149 @@ | ||
# Active Help | ||
|
||
Active Help is a framework provided by Cobra which allows a program to define messages (hints, warnings, etc) that will be printed during program usage. It aims to make it easier for your users to learn how to use your program. If configured by the program, Active Help is printed when the user triggers shell completion. | ||
|
||
For example, | ||
``` | ||
bash-5.1$ helm repo add [tab] | ||
You must choose a name for the repo you are adding. | ||
bash-5.1$ bin/helm package [tab] | ||
Please specify the path to the chart to package | ||
bash-5.1$ bin/helm package [tab][tab] | ||
bin/ internal/ scripts/ pkg/ testdata/ | ||
``` | ||
## Supported shells | ||
|
||
Active Help is currently only supported for the following shells: | ||
- Bash (using [bash completion V2](shell_completions.md#bash-completion-v2) only) | ||
- Zsh | ||
|
||
## Adding Active Help messages | ||
|
||
As Active Help uses the shell completion system, the implementation of Active Help messages is done by enhancing custom dynamic completions. If you are not familiar with dynamic completions, please refer to [Shell Completions](shell_completions.md). | ||
|
||
Adding Active Help is done through the use of the `cobra.AppendActiveHelp(...)` function, where the program repeatedly adds Active Help messages to the list of completions. Keep reading for details. | ||
|
||
### Active Help for nouns | ||
|
||
Adding Active Help when completing a noun is done within the `ValidArgsFunction(...)` of a command. Please notice the use of `cobra.AppendActiveHelp(...)` in the following example: | ||
|
||
```go | ||
cmd := &cobra.Command{ | ||
Use: "add [NAME] [URL]", | ||
Short: "add a chart repository", | ||
Args: require.ExactArgs(2), | ||
RunE: func(cmd *cobra.Command, args []string) error { | ||
return addRepo(args) | ||
}, | ||
ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { | ||
var comps []string | ||
if len(args) == 0 { | ||
comps = cobra.AppendActiveHelp(comps, "You must choose a name for the repo you are adding") | ||
} else if len(args) == 1 { | ||
comps = cobra.AppendActiveHelp(comps, "You must specify the URL for the repo you are adding") | ||
} else { | ||
comps = cobra.AppendActiveHelp(comps, "This command does not take any more arguments") | ||
} | ||
return comps, cobra.ShellCompDirectiveNoFileComp | ||
}, | ||
} | ||
``` | ||
The example above defines the completions (none, in this specific example) as well as the Active Help messages for the `helm repo add` command. It yields the following behavior: | ||
``` | ||
bash-5.1$ helm repo add [tab] | ||
You must choose a name for the repo you are adding | ||
bash-5.1$ helm repo add grafana [tab] | ||
You must specify the URL for the repo you are adding | ||
bash-5.1$ helm repo add grafana https://grafana.github.io/helm-charts [tab] | ||
This command does not take any more arguments | ||
``` | ||
|
||
### Active Help for flags | ||
|
||
Providing Active Help for flags is done in the same fashion as for nouns, but using the completion function registered for the flag. For example: | ||
```go | ||
_ = cmd.RegisterFlagCompletionFunc("version", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { | ||
if len(args) != 2 { | ||
return cobra.AppendActiveHelp(nil, "You must first specify the chart to install before the --version flag can be completed"), cobra.ShellCompDirectiveNoFileComp | ||
} | ||
return compVersionFlag(args[1], toComplete) | ||
}) | ||
``` | ||
The example above prints an Active Help message when not enough information was given by the user to complete the `--version` flag. | ||
``` | ||
bash-5.1$ bin/helm install myrelease --version 2.0.[tab] | ||
You must first specify the chart to install before the --version flag can be completed | ||
bash-5.1$ bin/helm install myrelease bitnami/solr --version 2.0.[tab][tab] | ||
2.0.1 2.0.2 2.0.3 | ||
``` | ||
|
||
## User control of Active Help | ||
|
||
You may want to allow your users to disable Active Help or choose between different levels of Active Help. It is entirely up to the program to define the level of configurability of Active Help that it wants to offer. Implementing the configuration of Active Help through Cobra is done as follows: | ||
|
||
1. Allow a user to specify the Active Help configuration she wants. This would normally be done when the user requests the generation of the shell completion script | ||
1. Specify the Active Help configuration by setting the `rootCmd.ActiveHelpConfig` string before calling the Cobra API that generates the shell completion script | ||
1. When in `cmd.ValidArgsFunction(...)` or a flag's completion function, read the configuration from the `cmd.ActiveHelpConfig` field and select what Active Help messages should or should not be added | ||
|
||
For example, a program that uses a `completion` command to generate the shell completion script can add a flag `--activehelp-level` to that command. The user would then use that flag to choose an Active Help level: | ||
``` | ||
bash-5.1$ source <(helm completion bash --activehelp-level 1) | ||
``` | ||
The code to pass that information to Cobra would look something like: | ||
```go | ||
cmd.Root().ActiveHelpConfig = strconv.Itoa(activeHelpLevel) | ||
return cmd.Root().GenBashCompletionV2(out, true) | ||
``` | ||
This specified configuration will then be accessible whenever `cmd.ValidArgsFunction(...)` or a flag's completion function is called: | ||
```go | ||
ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { | ||
activeHelpLevel, err := strconv.Atoi(cmd.ActiveHelpConfig) | ||
if err != nil { | ||
activeHelpLevel = 2 // Highest level allowed by this program | ||
} | ||
|
||
var comps []string | ||
if len(args) == 0 { | ||
if activeHelpLevel > 0 { | ||
comps = cobra.AppendActiveHelp(comps, "You must choose a name for the repo you are adding") | ||
} | ||
} else if len(args) == 1 { | ||
if activeHelpLevel > 0 { | ||
comps = cobra.AppendActiveHelp(comps, "You must specify the URL for the repo you are adding") | ||
} | ||
} else { | ||
if activeHelpLevel > 1 { | ||
comps = cobra.AppendActiveHelp(comps, "This command does not take any more arguments") | ||
} | ||
} | ||
return comps, cobra.ShellCompDirectiveNoFileComp | ||
}, | ||
``` | ||
**Note**: If the string "0" is used for `cmd.Root().ActiveHelpConfig`, it will automatically be handled by Cobra and will completely disable all Active Help output (even if some output was specified by the program using the `cobra.AppendActiveHelp(...)` function). Using "0" can simplify your code in situations where you want to blindly disable Active Help. | ||
|
||
**Note**: Cobra transparently passes the `cmd.ActiveHelpConfig` string you specified back to your program when completion is invoked. You can therefore define any scheme you choose for your program; you are not limited to using integer levels for the configuration of Active Help. | ||
|
||
## Debugging Active Help | ||
|
||
Debugging your Active Help code is done in the same way as debugging the dynamic completion code, which is with Cobra's hidden `__complete` command. Please refer to [debugging shell completion](shell_completions.md#debugging) for details. | ||
|
||
When debugging with the `__complete` command, if you want to specify different Active Help configurations, you should use the `--__activeHelpCfg` flag (as is done by the generated completion scripts). For example, we can test deactivating some Active Help as shown below: | ||
``` | ||
$ bin/helm __complete --__activeHelpCfg=1 install wordpress bitnami/h<ENTER> | ||
bitnami/haproxy | ||
bitnami/harbor | ||
_activeHelp_ WARNING: cannot re-use a name that is still in use | ||
:0 | ||
Completion ended with directive: ShellCompDirectiveDefault | ||
$ bin/helm __complete --__activeHelpCfg=0 install wordpress bitnami/h<ENTER> | ||
bitnami/haproxy | ||
bitnami/harbor | ||
:0 | ||
Completion ended with directive: ShellCompDirectiveDefault | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.