Browse Source

Merge pull request #2833 from yiannistri/feature/fluxctl-bash-completion

Add support for bash/zsh completion
Hidde Beydals 1 month ago
parent
commit
05ece2d5ce
No account linked to committer's email address
3 changed files with 95 additions and 1 deletions
  1. 54
    0
      cmd/fluxctl/completion_cmd.go
  2. 39
    0
      cmd/fluxctl/completion_cmd_test.go
  3. 2
    1
      cmd/fluxctl/root_cmd.go

+ 54
- 0
cmd/fluxctl/completion_cmd.go View File

@@ -0,0 +1,54 @@
1
+package main
2
+
3
+import (
4
+	"fmt"
5
+	"io"
6
+	"strings"
7
+
8
+	"github.com/spf13/cobra"
9
+)
10
+
11
+var (
12
+	completionShells = map[string]func(out io.Writer, cmd *cobra.Command) error{
13
+		"bash": runCompletionBash,
14
+		"zsh":  runCompletionZsh,
15
+	}
16
+)
17
+
18
+func newCompletionCommand() *cobra.Command {
19
+	shells := []string{}
20
+	for s := range completionShells {
21
+		shells = append(shells, s)
22
+	}
23
+
24
+	return &cobra.Command{
25
+		Use:                   "completion SHELL",
26
+		DisableFlagsInUseLine: true,
27
+		Short:                 "Output shell completion code for the specified shell (bash or zsh)",
28
+		RunE: func(cmd *cobra.Command, args []string) error {
29
+			if len(args) == 0 {
30
+				return newUsageError("please specify a shell")
31
+			}
32
+
33
+			if len(args) > 1 {
34
+				return newUsageError(fmt.Sprintf("please specify one of the following shells: %s", strings.Join(shells, " ")))
35
+			}
36
+
37
+			run, found := completionShells[args[0]]
38
+			if !found {
39
+				return newUsageError(fmt.Sprintf("unsupported shell type %q.", args[0]))
40
+			}
41
+
42
+			return run(cmd.OutOrStdout(), cmd.Parent())
43
+		},
44
+		ValidArgs: shells,
45
+	}
46
+}
47
+
48
+func runCompletionBash(out io.Writer, fluxctl *cobra.Command) error {
49
+	return fluxctl.GenBashCompletion(out)
50
+}
51
+
52
+func runCompletionZsh(out io.Writer, fluxctl *cobra.Command) error {
53
+	return fluxctl.GenZshCompletion(out)
54
+}

+ 39
- 0
cmd/fluxctl/completion_cmd_test.go View File

@@ -0,0 +1,39 @@
1
+package main
2
+
3
+import (
4
+	"fmt"
5
+	"testing"
6
+)
7
+
8
+func TestCompletionCommand_InputFailure(t *testing.T) {
9
+	for k, v := range [][]string{
10
+		{},
11
+		{"foo"},
12
+		{"bash", "zsh"},
13
+	} {
14
+		t.Run(fmt.Sprintf("%d", k), func(t *testing.T) {
15
+			cmd := newCompletionCommand()
16
+			cmd.SetArgs(v)
17
+			if err := cmd.Execute(); err == nil {
18
+				t.Fatalf("Expecting error: command is expecting either bash or zsh")
19
+			}
20
+		})
21
+	}
22
+}
23
+
24
+func TestCompletionCommand_Success(t *testing.T) {
25
+	for k, v := range [][]string{
26
+		{"bash"},
27
+		{"zsh"},
28
+	} {
29
+		t.Run(fmt.Sprintf("%d", k), func(t *testing.T) {
30
+			parentCmd := newRoot().Command()
31
+			cmd := newCompletionCommand()
32
+			parentCmd.AddCommand(cmd)
33
+			cmd.SetArgs(v)
34
+			if err := cmd.Execute(); err != nil {
35
+				t.Fatalf("Expecting nil, got error (%s)", err.Error())
36
+			}
37
+		})
38
+	}
39
+}

+ 2
- 1
cmd/fluxctl/root_cmd.go View File

@@ -97,6 +97,7 @@ func (opts *rootOpts) Command() *cobra.Command {
97 97
 		newIdentity(opts).Command(),
98 98
 		newSync(opts).Command(),
99 99
 		newInstall().Command(),
100
+		newCompletionCommand(),
100 101
 	)
101 102
 
102 103
 	return cmd
@@ -105,7 +106,7 @@ func (opts *rootOpts) Command() *cobra.Command {
105 106
 func (opts *rootOpts) PersistentPreRunE(cmd *cobra.Command, _ []string) error {
106 107
 	// skip port forward for certain commands
107 108
 	switch cmd.Use {
108
-	case "version":
109
+	case "version", "completion SHELL":
109 110
 		fallthrough
110 111
 	case "install":
111 112
 		return nil

Loading…
Cancel
Save