Skip to content

Commit f6d0cff

Browse files
Merge pull request #21 from mia-platform/issue-10
Add completion for fish, bash and zsh
2 parents f44c8bd + a441099 commit f6d0cff

File tree

7 files changed

+187
-6
lines changed

7 files changed

+187
-6
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,6 @@
1616

1717
# Build output directory
1818
execs/*
19+
20+
# Program binary
21+
miactl

README.md

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,77 @@ miactl help
4141
```
4242

4343

44+
## Enabling shell autocompletion
45+
46+
miactl provides autocompletion support for Bash, Zsh and Fish, which can save you a lot of typing.
47+
48+
### Bash
49+
50+
Completion could be generate running the `miactl completion bash` command.
51+
In order to make this completion work, you should have [bash completion](https://github.com/scop/bash-completion)
52+
correctly installed.
53+
54+
Warning: there are two versions of `bash-completion`, v1 and v2. V1 is for Bash 3.2 (which is the default on macOS), and v2 is for Bash 4.1+. The miactl completion script requires `bash-completion` v2 and Bash 4.1+.
55+
56+
**For linux:**
57+
58+
You could install `bash-completion` running `apt-get install bash-completion`.
59+
60+
The above command create `/usr/share/bash-completion/bash_completion`, which is the main script of bash completion.
61+
Try to run the command `type _init_completion`. If the command succeeds, you're already seet. Otherwise add to the `~/.bashrc` file:
62+
63+
```sh
64+
source /usr/share/bash-completion/bash_completion
65+
```
66+
67+
After the correct installation if bash completion, you could make the completion works running:
68+
```sh
69+
miactl completion bash >/etc/bash_completion.d/miactl
70+
```
71+
72+
**For osx:**
73+
74+
Check the bash version running `echo $BASH_VERSION`. If the version is less than 4.1, you should install a new bash version with Homebrew running
75+
76+
```sh
77+
brew install bash
78+
```
79+
80+
Reload your shell and run the command `echo $BASH_VERSION` to verify the bash version.
81+
82+
Once installed the correct bash version, you should install `bash-completion` to v2. To check if it is already installed, run `type _init_completion`. If not, you can install it with Homebrew
83+
84+
```sh
85+
brew install bash-completion@2
86+
````
87+
88+
And add in your `~/.bashrc` file:
89+
```sh
90+
export BASH_COMPLETION_COMPAT_DIR="/usr/local/etc/bash_completion.d"
91+
[[ -r "/usr/local/etc/profile.d/bash_completion.sh" ]] && . "/usr/local/etc/profile.d/bash_completion.sh"
92+
```
93+
94+
After the correct installation if bash completion, you could make the completion works running:
95+
```sh
96+
miactl completion bash >/etc/bash_completion.d/miactl
97+
```
98+
99+
### Fish
100+
101+
Completion could be generate running the `miactl completion fish` command.
102+
103+
In order to make this completion work, you should run:
104+
```sh
105+
miactl completion fish >~/.config/fish/completions/miactl.fish
106+
```
107+
108+
### Zsh
109+
110+
Completion could be generate running the `miactl completion zsh` command
111+
112+
The generated completion script should be put somewhere in your $fpath named _miactl.
113+
114+
44115
[github-actions]: https://github.com/mia-platform/miactl/actions
45116
[github-actions-svg]: https://github.com/mia-platform/miactl/workflows/Test%20and%20build/badge.svg
46117
[godoc-svg]: https://godoc.org/github.com/mia-platform/miactl?status.svg

cmd/completion.go

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package cmd
2+
3+
import (
4+
"github.com/spf13/cobra"
5+
)
6+
7+
// completionCmd represents the completion command
8+
func newCompletionCmd(rootCmd *cobra.Command) *cobra.Command {
9+
longUsage := `To load completion run
10+
11+
For bash:
12+
13+
miactl completion bash >/etc/bash_completion.d/miactl
14+
15+
To configure your bash shell to load completions for each session add to your bashrc, run
16+
17+
echo 'source <(miactl completion bash)' >>~/.bashrc
18+
19+
For fish:
20+
21+
miactl completion fish >~/.config/fish/completions/miactl.fish
22+
23+
For zsh:
24+
25+
To generate the completion script, run miactl completion zsh
26+
the generated completion script should be put somewhere in your $fpath named _miactl
27+
28+
---
29+
30+
After reloading your shell, miactl autocompletion should be working.
31+
`
32+
33+
validArgs := []string{"bash", "fish", "zsh"}
34+
35+
var completionCmd = &cobra.Command{
36+
Use: "completion",
37+
Short: "Generates bash completion scripts",
38+
Long: longUsage,
39+
ValidArgs: validArgs,
40+
Args: func(cmd *cobra.Command, args []string) error {
41+
return cobra.ExactValidArgs(1)(cmd, args)
42+
},
43+
Run: func(cmd *cobra.Command, args []string) {
44+
45+
shell := args[0]
46+
47+
switch shell {
48+
case "bash":
49+
rootCmd.GenBashCompletion(cmd.OutOrStdout())
50+
case "fish":
51+
rootCmd.GenFishCompletion(cmd.OutOrStdout(), true)
52+
case "zsh":
53+
rootCmd.GenZshCompletion(cmd.OutOrStdout())
54+
}
55+
},
56+
}
57+
58+
return completionCmd
59+
}

cmd/completion_test.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package cmd
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/require"
7+
)
8+
9+
func TestCompletion(t *testing.T) {
10+
t.Run("without correct args", func(t *testing.T) {
11+
out, err := executeCommand(NewRootCmd(), "completion", "not-correct-arg")
12+
expectedErrMessage := `invalid argument "not-correct-arg" for "miactl completion"`
13+
require.Contains(t, out, expectedErrMessage)
14+
require.EqualError(t, err, expectedErrMessage)
15+
})
16+
17+
t.Run("without args", func(t *testing.T) {
18+
out, err := executeCommand(NewRootCmd(), "completion")
19+
expectedErrMessage := `accepts 1 arg(s), received 0`
20+
require.Contains(t, out, expectedErrMessage)
21+
require.EqualError(t, err, expectedErrMessage)
22+
})
23+
24+
t.Run("with fish arg", func(t *testing.T) {
25+
out, err := executeCommand(NewRootCmd(), "completion", "fish")
26+
require.Nil(t, err)
27+
require.Contains(t, out, "# fish completion for miactl")
28+
})
29+
30+
t.Run("with bash arg", func(t *testing.T) {
31+
out, err := executeCommand(NewRootCmd(), "completion", "bash")
32+
require.Nil(t, err)
33+
require.Contains(t, out, "# bash completion for miactl")
34+
})
35+
36+
t.Run("with zsh arg", func(t *testing.T) {
37+
out, err := executeCommand(NewRootCmd(), "completion", "zsh")
38+
require.Nil(t, err)
39+
require.Contains(t, out, "#compdef _miactl miactl")
40+
})
41+
}

cmd/get.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,12 @@ import (
99
var validArgs = []string{"project", "projects"}
1010

1111
// NewGetCmd func creates a new command
12-
func NewGetCmd() *cobra.Command {
12+
func newGetCmd() *cobra.Command {
1313
return &cobra.Command{
1414
Use: "get",
1515
ValidArgs: validArgs,
1616
Args: func(cmd *cobra.Command, args []string) error {
17-
return cobra.OnlyValidArgs(cmd, args)
17+
return cobra.ExactValidArgs(1)(cmd, args)
1818
},
1919
RunE: func(cmd *cobra.Command, args []string) error {
2020
f, err := GetFactoryFromContext(cmd.Context(), opts)

cmd/get_test.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,14 @@ func TestGetCommandRenderAndReturnsError(t *testing.T) {
2222

2323
t.Run("without correct args", func(t *testing.T) {
2424
out, err := executeCommand(NewRootCmd(), "get", "not-correct-arg")
25-
expectedErrMessage := `invalid argument "not-correct-arg" for "miaplatformctl get"`
25+
expectedErrMessage := `invalid argument "not-correct-arg" for "miactl get"`
26+
require.Contains(t, out, expectedErrMessage)
27+
require.EqualError(t, err, expectedErrMessage)
28+
})
29+
30+
t.Run("without args", func(t *testing.T) {
31+
out, err := executeCommand(NewRootCmd(), "get")
32+
expectedErrMessage := `accepts 1 arg(s), received 0`
2633
require.Contains(t, out, expectedErrMessage)
2734
require.EqualError(t, err, expectedErrMessage)
2835
})

cmd/root.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,14 @@ var (
2020
// NewRootCmd creates a new root command
2121
func NewRootCmd() *cobra.Command {
2222
rootCmd := &cobra.Command{
23-
Use: "miaplatformctl",
24-
Aliases: []string{"miactl"},
23+
Use: "miactl",
2524
}
2625
setRootPersistentFlag(rootCmd)
2726

2827
// add sub command to root command
29-
rootCmd.AddCommand(NewGetCmd())
28+
rootCmd.AddCommand(newGetCmd())
3029

30+
rootCmd.AddCommand(newCompletionCmd(rootCmd))
3131
return rootCmd
3232
}
3333

0 commit comments

Comments
 (0)