Skip to content

Commit bbfc2f1

Browse files
committed
feat: shell auto completion, new command version, completion
1 parent 90d6dcf commit bbfc2f1

File tree

8 files changed

+156
-21
lines changed

8 files changed

+156
-21
lines changed

go.mod

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,8 @@ require (
3232
github.com/russross/blackfriday/v2 v2.1.0 // indirect
3333
github.com/stevenle/topsort v0.2.0 // indirect
3434
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect
35-
golang.org/x/mod v0.17.0 // indirect
3635
golang.org/x/sync v0.8.0 // indirect
3736
golang.org/x/sys v0.20.0 // indirect
38-
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect
3937
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
4038
gopkg.in/yaml.v2 v2.4.0 // indirect
4139
)

go.sum

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3
88
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
99
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
1010
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
11-
github.com/ekristen/libnuke v0.18.0 h1:sF533oSET50FjgIkYV72rvgNzCzUR/AH2tQeKVim31g=
12-
github.com/ekristen/libnuke v0.18.0/go.mod h1:riI1tjCf6r+et/9oUBd1vQeFmn2Sn6UeFUR0nWkMeYw=
1311
github.com/ekristen/libnuke v0.19.0 h1:pXVxPlbKfYbP1iSwsNu67MQ8HNvZPEZIeKiyw/k8FWg=
1412
github.com/ekristen/libnuke v0.19.0/go.mod h1:riI1tjCf6r+et/9oUBd1vQeFmn2Sn6UeFUR0nWkMeYw=
1513
github.com/fatih/color v1.17.0 h1:GlRw1BRJxkpqUCBKzKOw098ed57fEsKeNjpTe3cSjK4=
@@ -56,8 +54,6 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
5654
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
5755
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
5856
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
59-
github.com/urfave/cli/v2 v2.27.3 h1:/POWahRmdh7uztQ3CYnaDddk0Rm90PyOgIxgW2rr41M=
60-
github.com/urfave/cli/v2 v2.27.3/go.mod h1:m4QzxcD2qpra4z7WhzEGn74WZLViBnMpb1ToCAKdGRQ=
6157
github.com/urfave/cli/v2 v2.27.4 h1:o1owoI+02Eb+K107p27wEX9Bb8eqIoZCfLXloLUSWJ8=
6258
github.com/urfave/cli/v2 v2.27.4/go.mod h1:m4QzxcD2qpra4z7WhzEGn74WZLViBnMpb1ToCAKdGRQ=
6359
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4=
@@ -70,15 +66,11 @@ go.uber.org/ratelimit v0.3.1/go.mod h1:6euWsTB6U/Nb3X++xEUXA8ciPJvr19Q/0h1+oDcJh
7066
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
7167
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
7268
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
73-
golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA=
74-
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
7569
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
7670
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
7771
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
7872
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
7973
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
80-
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
81-
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
8274
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
8375
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
8476
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -94,17 +86,11 @@ golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
9486
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
9587
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
9688
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
97-
golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
98-
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
99-
golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc=
100-
golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
10189
golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224=
10290
golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
10391
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
10492
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
10593
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
106-
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg=
107-
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
10894
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
10995
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
11096
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=

main.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,11 @@ import (
99
"github.com/ekristen/aws-nuke/v3/pkg/common"
1010

1111
_ "github.com/ekristen/aws-nuke/v3/pkg/commands/account"
12+
_ "github.com/ekristen/aws-nuke/v3/pkg/commands/completion"
1213
_ "github.com/ekristen/aws-nuke/v3/pkg/commands/config"
1314
_ "github.com/ekristen/aws-nuke/v3/pkg/commands/list"
1415
_ "github.com/ekristen/aws-nuke/v3/pkg/commands/nuke"
16+
_ "github.com/ekristen/aws-nuke/v3/pkg/commands/version"
1517

1618
_ "github.com/ekristen/aws-nuke/v3/resources"
1719
)
@@ -43,6 +45,8 @@ func main() {
4345
logrus.Fatalf("Command %s not found.", command)
4446
}
4547

48+
app.EnableBashCompletion = true
49+
4650
if err := app.Run(os.Args); err != nil {
4751
logrus.Fatal(err)
4852
}

pkg/commands/completion/completion.go

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
package completion
2+
3+
import (
4+
"embed"
5+
"fmt"
6+
"os"
7+
"slices"
8+
"strings"
9+
10+
"github.com/urfave/cli/v2"
11+
12+
"github.com/ekristen/aws-nuke/v3/pkg/commands/global"
13+
"github.com/ekristen/aws-nuke/v3/pkg/common"
14+
)
15+
16+
//go:embed files/*
17+
var files embed.FS
18+
19+
func execute(c *cli.Context) error {
20+
var autocomplete []byte
21+
var err error
22+
switch c.String("shell") {
23+
case "bash":
24+
autocomplete, err = files.ReadFile("files/bash_autocomplete")
25+
case "zsh":
26+
autocomplete, err = files.ReadFile("files/zsh_autocomplete")
27+
}
28+
29+
if err != nil {
30+
return err
31+
}
32+
33+
fmt.Println(string(autocomplete))
34+
35+
return nil
36+
}
37+
38+
func init() {
39+
shellValue := "bash"
40+
shellActual := os.Getenv("SHELL")
41+
if strings.Contains(shellActual, "zsh") {
42+
shellValue = "zsh"
43+
}
44+
45+
flags := []cli.Flag{
46+
&cli.StringFlag{
47+
Name: "shell",
48+
Usage: "shell to generate completion script for",
49+
Value: shellValue,
50+
Action: func(c *cli.Context, val string) error {
51+
validShells := []string{"bash", "zsh"}
52+
if !slices.Contains(validShells, val) {
53+
return fmt.Errorf("unsupported shell %s", val)
54+
}
55+
56+
return nil
57+
},
58+
},
59+
}
60+
61+
cmd := &cli.Command{
62+
Name: "completion",
63+
Usage: "generate shell completion script",
64+
Description: "generate shell completion script",
65+
Flags: append(flags, global.Flags()...),
66+
Before: global.Before,
67+
Action: execute,
68+
}
69+
70+
common.RegisterCommand(cmd)
71+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#! /bin/bash
2+
3+
# Macs have bash3 for which the bash-completion package doesn't include
4+
# _init_completion. This is a minimal version of that function.
5+
_cli_init_completion() {
6+
COMPREPLY=()
7+
_get_comp_words_by_ref "$@" cur prev words cword
8+
}
9+
10+
_cli_bash_autocomplete() {
11+
if [[ "${COMP_WORDS[0]}" != "source" ]]; then
12+
local cur opts base words
13+
COMPREPLY=()
14+
cur="${COMP_WORDS[COMP_CWORD]}"
15+
if declare -F _init_completion >/dev/null 2>&1; then
16+
_init_completion -n "=:" || return
17+
else
18+
_cli_init_completion -n "=:" || return
19+
fi
20+
words=("${words[@]:0:$cword}")
21+
if [[ "$cur" == "-"* ]]; then
22+
requestComp="${words[*]} ${cur} --generate-bash-completion"
23+
else
24+
requestComp="${words[*]} --generate-bash-completion"
25+
fi
26+
opts=$(eval "${requestComp}" 2>/dev/null)
27+
COMPREPLY=($(compgen -W "${opts}" -- ${cur}))
28+
return 0
29+
fi
30+
}
31+
32+
complete -o bashdefault -o default -o nospace -F _cli_bash_autocomplete aws-nuke
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#compdef aws-nuke
2+
3+
_cli_zsh_autocomplete() {
4+
local -a opts
5+
local cur
6+
cur=${words[-1]}
7+
if [[ "$cur" == "-"* ]]; then
8+
opts=("${(@f)$(${words[@]:0:#words[@]-1} ${cur} --generate-bash-completion)}")
9+
else
10+
opts=("${(@f)$(${words[@]:0:#words[@]-1} --generate-bash-completion)}")
11+
fi
12+
13+
if [[ "${opts[1]}" != "" ]]; then
14+
_describe 'values' opts
15+
else
16+
_files
17+
fi
18+
}
19+
20+
compdef _cli_zsh_autocomplete aws-nuke

pkg/commands/version/version.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package version
2+
3+
import (
4+
"fmt"
5+
6+
"github.com/urfave/cli/v2"
7+
8+
"github.com/ekristen/aws-nuke/v3/pkg/commands/global"
9+
"github.com/ekristen/aws-nuke/v3/pkg/common"
10+
)
11+
12+
func execute(c *cli.Context) error {
13+
fmt.Println(common.AppVersion.Name, "version", common.AppVersion.Summary)
14+
15+
return nil
16+
}
17+
18+
func init() {
19+
cmd := &cli.Command{
20+
Name: "version",
21+
Usage: "displays the version",
22+
Description: "displays the version of aws-nuke",
23+
Flags: global.Flags(),
24+
Before: global.Before,
25+
Action: execute,
26+
}
27+
28+
common.RegisterCommand(cmd)
29+
}

pkg/common/commands.go

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,6 @@ import (
77

88
var commands []*cli.Command
99

10-
// Commander --
11-
type Commander interface {
12-
Execute(c *cli.Context)
13-
}
14-
1510
// RegisterCommand --
1611
func RegisterCommand(command *cli.Command) {
1712
logrus.Debugln("Registering", command.Name, "command...")

0 commit comments

Comments
 (0)