mirror of
https://github.com/spf13/cobra
synced 2025-04-30 10:37:16 +00:00
150 lines
6.3 KiB
Markdown
150 lines
6.3 KiB
Markdown
---
|
|
weight: 11
|
|
---
|
|
|
|
## Bash completions
|
|
|
|
#### Dependencies
|
|
|
|
The bash completion script generated by Cobra requires the `bash_completion` package. You should update the help text of your completion command to show how to install the `bash_completion` package ([Kubectl docs](https://kubernetes.io/docs/tasks/tools/install-kubectl/#enabling-shell-autocompletion))
|
|
|
|
#### Aliases
|
|
|
|
You can also configure `bash` aliases for your program and they will also support completions.
|
|
|
|
```bash
|
|
alias aliasname=origcommand
|
|
complete -o default -F __start_origcommand aliasname
|
|
|
|
# and now when you run `aliasname` completion will make
|
|
# suggestions as it did for `origcommand`.
|
|
|
|
$ aliasname <tab><tab>
|
|
completion firstcommand secondcommand
|
|
```
|
|
#### Bash legacy dynamic completions
|
|
|
|
For backward compatibility, Cobra still supports its bash legacy dynamic completion solution.
|
|
Please refer to [Bash Completions](bash.md) for details.
|
|
|
|
### Bash completion V2
|
|
|
|
Cobra provides two versions for bash completion. The original bash completion (which started it all!) can be used by calling
|
|
`GenBashCompletion()` or `GenBashCompletionFile()`.
|
|
|
|
A new V2 bash completion version is also available. This version can be used by calling `GenBashCompletionV2()` or
|
|
`GenBashCompletionFileV2()`. The V2 version does **not** support the legacy dynamic completion
|
|
(see [Bash Completions](bash.md)) but instead works only with the Go dynamic completion
|
|
solution described in this document.
|
|
Unless your program already uses the legacy dynamic completion solution, it is recommended that you use the bash
|
|
completion V2 solution which provides the following extra features:
|
|
- Supports completion descriptions (like the other shells)
|
|
- Small completion script of less than 300 lines (v1 generates scripts of thousands of lines; `kubectl` for example has a bash v1 completion script of over 13K lines)
|
|
- Streamlined user experience thanks to a completion behavior aligned with the other shells
|
|
|
|
`Bash` completion V2 supports descriptions for completions. When calling `GenBashCompletionV2()` or `GenBashCompletionFileV2()`
|
|
you must provide these functions with a parameter indicating if the completions should be annotated with a description; Cobra
|
|
will provide the description automatically based on usage information. You can choose to make this option configurable by
|
|
your users.
|
|
|
|
```
|
|
# With descriptions
|
|
$ helm s[tab][tab]
|
|
search (search for a keyword in charts) status (display the status of the named release)
|
|
show (show information of a chart)
|
|
|
|
# Without descriptions
|
|
$ helm s[tab][tab]
|
|
search show status
|
|
```
|
|
**Note**: Cobra's default `completion` command uses bash completion V2. If for some reason you need to use bash completion V1, you will need to implement your own `completion` command.
|
|
|
|
### Bash legacy dynamic completions
|
|
|
|
For backward compatibility, Cobra still supports its legacy dynamic completion solution (described below). Unlike the `ValidArgsFunction` solution, the legacy solution will only work for Bash shell-completion and not for other shells. This legacy solution can be used along-side `ValidArgsFunction` and `RegisterFlagCompletionFunc()`, as long as both solutions are not used for the same command. This provides a path to gradually migrate from the legacy solution to the new solution.
|
|
|
|
**Note**: Cobra's default `completion` command uses bash completion V2. If you are currently using Cobra's legacy dynamic completion solution, you should not use the default `completion` command but continue using your own.
|
|
|
|
The legacy solution allows you to inject bash functions into the bash completion script. Those bash functions are responsible for providing the completion choices for your own completions.
|
|
|
|
Some code that works in kubernetes:
|
|
|
|
```bash
|
|
const (
|
|
bash_completion_func = `__kubectl_parse_get()
|
|
{
|
|
local kubectl_output out
|
|
if kubectl_output=$(kubectl get --no-headers "$1" 2>/dev/null); then
|
|
out=($(echo "${kubectl_output}" | awk '{print $1}'))
|
|
COMPREPLY=( $( compgen -W "${out[*]}" -- "$cur" ) )
|
|
fi
|
|
}
|
|
|
|
__kubectl_get_resource()
|
|
{
|
|
if [[ ${#nouns[@]} -eq 0 ]]; then
|
|
return 1
|
|
fi
|
|
__kubectl_parse_get ${nouns[${#nouns[@]} -1]}
|
|
if [[ $? -eq 0 ]]; then
|
|
return 0
|
|
fi
|
|
}
|
|
|
|
__kubectl_custom_func() {
|
|
case ${last_command} in
|
|
kubectl_get | kubectl_describe | kubectl_delete | kubectl_stop)
|
|
__kubectl_get_resource
|
|
return
|
|
;;
|
|
*)
|
|
;;
|
|
esac
|
|
}
|
|
`)
|
|
```
|
|
|
|
And then I set that in my command definition:
|
|
|
|
```go
|
|
cmds := &cobra.Command{
|
|
Use: "kubectl",
|
|
Short: "kubectl controls the Kubernetes cluster manager",
|
|
Long: `kubectl controls the Kubernetes cluster manager.
|
|
|
|
Find more information at https://github.com/GoogleCloudPlatform/kubernetes.`,
|
|
Run: runHelp,
|
|
BashCompletionFunction: bash_completion_func,
|
|
}
|
|
```
|
|
|
|
The `BashCompletionFunction` option is really only valid/useful on the root command. Doing the above will cause `__kubectl_custom_func()` (`__<command-use>_custom_func()`) to be called when the built in processor was unable to find a solution. In the case of kubernetes a valid command might look something like `kubectl get pod [mypod]`. If you type `kubectl get pod [tab][tab]` the `__kubectl_customc_func()` will run because the cobra.Command only understood "kubectl" and "get." `__kubectl_custom_func()` will see that the cobra.Command is "kubectl_get" and will thus call another helper `__kubectl_get_resource()`. `__kubectl_get_resource` will look at the 'nouns' collected. In our example the only noun will be `pod`. So it will call `__kubectl_parse_get pod`. `__kubectl_parse_get` will actually call out to kubernetes and get any pods. It will then set `COMPREPLY` to valid pods!
|
|
|
|
Similarly, for flags:
|
|
|
|
```go
|
|
annotation := make(map[string][]string)
|
|
annotation[cobra.BashCompCustom] = []string{"__kubectl_get_namespaces"}
|
|
|
|
flag := &pflag.Flag{
|
|
Name: "namespace",
|
|
Usage: usage,
|
|
Annotations: annotation,
|
|
}
|
|
cmd.Flags().AddFlag(flag)
|
|
```
|
|
|
|
In addition add the `__kubectl_get_namespaces` implementation in the `BashCompletionFunction`
|
|
value, e.g.:
|
|
|
|
```bash
|
|
__kubectl_get_namespaces()
|
|
{
|
|
local template
|
|
template="{{ range .items }}{{ .metadata.name }} {{ end }}"
|
|
local kubectl_out
|
|
if kubectl_out=$(kubectl get -o template --template="${template}" namespace 2>/dev/null); then
|
|
COMPREPLY=( $( compgen -W "${kubectl_out}[*]" -- "$cur" ) )
|
|
fi
|
|
}
|
|
```
|