Skip to content

Commit 9015a46

Browse files
committed
pkg/completion: add common completion command
Add the completion command to pkg/completion, this would allow podman, buildah and skopeo to use the same command instead of having to duplicate the logic. The code is mostly copied from podman/cmd/podman/completion. I have modified it a little to make it more generic. Signed-off-by: Paul Holzinger <[email protected]>
1 parent 5895cde commit 9015a46

File tree

1 file changed

+96
-0
lines changed

1 file changed

+96
-0
lines changed

pkg/completion/command.go

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
package completion
2+
3+
import (
4+
"fmt"
5+
"io"
6+
"os"
7+
"strings"
8+
9+
"github.com/spf13/cobra"
10+
)
11+
12+
const (
13+
completionDescription = `Generate shell autocompletions.
14+
Valid arguments are bash, zsh, fish and powershell.`
15+
16+
bash = "bash"
17+
zsh = "zsh"
18+
fish = "fish"
19+
powershell = "powershell"
20+
)
21+
22+
var (
23+
file string
24+
noDesc bool
25+
shells = []string{bash, zsh, fish, powershell}
26+
)
27+
28+
// AddCompletionCommand adds the completion command to the given command which should be the root command.
29+
// This command can be used the generate the cobra shell completion scripts for bash, zsh, fish and powershell.
30+
func AddCompletionCommand(rootCmd *cobra.Command) {
31+
completionCmd := &cobra.Command{
32+
Use: fmt.Sprintf("completion [options] {%s}", strings.Join(shells, "|")),
33+
Short: "Generate shell autocompletions",
34+
Long: completionDescription,
35+
ValidArgs: shells,
36+
Args: cobra.ExactValidArgs(1),
37+
RunE: completion,
38+
Example: fmt.Sprintf(`%[1]s completion bash
39+
%[1]s completion zsh -f _%[1]s
40+
%[1]s completion fish --no-desc`, rootCmd.Name()),
41+
// don't show this command to users
42+
Hidden: true,
43+
}
44+
45+
flags := completionCmd.Flags()
46+
fileFlagName := "file"
47+
flags.StringVarP(&file, fileFlagName, "f", "", "Output the completion to file rather than stdout.")
48+
_ = completionCmd.RegisterFlagCompletionFunc(fileFlagName, AutocompleteDefault)
49+
50+
flags.BoolVar(&noDesc, "no-desc", false, "Don't include descriptions in the completion output.")
51+
52+
rootCmd.AddCommand(completionCmd)
53+
}
54+
55+
func completion(cmd *cobra.Command, args []string) error {
56+
var w io.Writer
57+
58+
if file != "" {
59+
file, err := os.Create(file)
60+
if err != nil {
61+
return err
62+
}
63+
defer file.Close()
64+
w = file
65+
} else {
66+
w = os.Stdout
67+
}
68+
69+
var err error
70+
switch args[0] {
71+
case bash:
72+
err = cmd.Root().GenBashCompletionV2(w, !noDesc)
73+
case zsh:
74+
if noDesc {
75+
err = cmd.Root().GenZshCompletionNoDesc(w)
76+
} else {
77+
err = cmd.Root().GenZshCompletion(w)
78+
}
79+
case fish:
80+
err = cmd.Root().GenFishCompletion(w, !noDesc)
81+
case powershell:
82+
if noDesc {
83+
err = cmd.Root().GenPowerShellCompletion(w)
84+
} else {
85+
err = cmd.Root().GenPowerShellCompletionWithDesc(w)
86+
}
87+
}
88+
if err != nil {
89+
return err
90+
}
91+
92+
_, err = io.WriteString(w, fmt.Sprintf(
93+
"# This file is generated with %q; DO NOT EDIT!\n", cmd.CommandPath(),
94+
))
95+
return err
96+
}

0 commit comments

Comments
 (0)