feat(cmd): Subcommands for the completion command

Making each shell a subcommand of the 'completion' has multiple
advantages:
- simplifies the code,
- allows to have different flags for each shell,
  for example, a future `--no-descriptions` flag for fish only,
- allows to tailor the help text per shell.

Signed-off-by: Marc Khouzam <marc.khouzam@montreal.ca>
pull/8314/head
Marc Khouzam 4 years ago
parent a28d695c43
commit f7c882d55e

@ -21,61 +21,70 @@ import (
"os"
"path/filepath"
"github.com/pkg/errors"
"github.com/spf13/cobra"
"helm.sh/helm/v3/cmd/helm/require"
)
const completionDesc = `
Generate autocompletions script for Helm for the specified shell (bash or zsh).
Generate autocompletions script for Helm for the specified shell.
`
const bashCompDesc = `
Generate the autocompletion script for Helm for the bash shell.
This command can generate shell autocompletions. e.g.
To load completions in your current shell session:
$ source <(helm completion bash)
$ helm completion bash
To load completions for every new session, execute once:
Linux:
$ helm completion bash > /etc/bash_completion.d/helm
MacOS:
$ helm completion bash > /usr/local/etc/bash_completion.d/helm
`
Can be sourced as such
const zshCompDesc = `
Generate the autocompletion script for Helm for the zsh shell.
$ source <(helm completion bash)
`
To load completions in your current shell session:
$ source <(helm completion zsh)
var (
completionShells = map[string]func(out io.Writer, cmd *cobra.Command) error{
"bash": runCompletionBash,
"zsh": runCompletionZsh,
}
)
To load completions for every new session, execute once:
$ helm completion zsh > "${fpath[1]}/_helm"
`
func newCompletionCmd(out io.Writer) *cobra.Command {
shells := []string{}
for s := range completionShells {
shells = append(shells, s)
}
cmd := &cobra.Command{
Use: "completion SHELL",
Short: "generate autocompletions script for the specified shell (bash or zsh)",
Use: "completion",
Short: "generate autocompletions script for the specified shell",
Long: completionDesc,
Args: require.NoArgs,
}
bash := &cobra.Command{
Use: "bash",
Short: "generate autocompletions script for bash",
Long: bashCompDesc,
Args: require.NoArgs,
DisableFlagsInUseLine: true,
RunE: func(cmd *cobra.Command, args []string) error {
return runCompletion(out, cmd, args)
return runCompletionBash(out, cmd)
},
ValidArgs: shells,
}
return cmd
}
func runCompletion(out io.Writer, cmd *cobra.Command, args []string) error {
if len(args) == 0 {
return errors.New("shell not specified")
}
if len(args) > 1 {
return errors.New("too many arguments, expected only the shell type")
}
run, found := completionShells[args[0]]
if !found {
return errors.Errorf("unsupported shell type %q", args[0])
zsh := &cobra.Command{
Use: "zsh",
Short: "generate autocompletions script for zsh",
Long: zshCompDesc,
Args: require.NoArgs,
DisableFlagsInUseLine: true,
RunE: func(cmd *cobra.Command, args []string) error {
return runCompletionZsh(out, cmd)
},
}
return run(out, cmd)
cmd.AddCommand(bash, zsh)
return cmd
}
func runCompletionBash(out io.Writer, cmd *cobra.Command) error {

@ -105,7 +105,8 @@ func loadPlugins(baseCmd *cobra.Command, out io.Writer) {
// We only do this when necessary (for the "completion" and "__complete" commands) to avoid the
// risk of a rogue plugin affecting Helm's normal behavior.
subCmd, _, err := baseCmd.Find(os.Args[1:])
if (err == nil && (subCmd.Name() == "completion" || subCmd.Name() == cobra.ShellCompRequestCmd)) ||
if (err == nil &&
((subCmd.HasParent() && subCmd.Parent().Name() == "completion") || subCmd.Name() == cobra.ShellCompRequestCmd)) ||
/* for the tests */ subCmd == baseCmd.Root() {
loadCompletionForPlugin(c, plug)
}

Loading…
Cancel
Save