Skip to content

Commit b8067c0

Browse files
authored
feat: improve positional arg usage errors (coder#225)
1 parent 288197a commit b8067c0

File tree

9 files changed

+46
-14
lines changed

9 files changed

+46
-14
lines changed

internal/cmd/cmd.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ package cmd
44
import (
55
"os"
66

7+
"cdr.dev/coder-cli/internal/x/xcobra"
78
"github.com/spf13/cobra"
89
"github.com/spf13/cobra/doc"
910
)
@@ -45,8 +46,8 @@ func genDocsCmd(rootCmd *cobra.Command) *cobra.Command {
4546
return &cobra.Command{
4647
Use: "gen-docs [dir_path]",
4748
Short: "Generate a markdown documentation tree for the root command.",
49+
Args: xcobra.ExactArgs(1),
4850
Example: "coder gen-docs ./docs",
49-
Args: cobra.ExactArgs(1),
5051
Hidden: true,
5152
RunE: func(_ *cobra.Command, args []string) error {
5253
return doc.GenMarkdownTree(rootCmd, args[0])

internal/cmd/envs.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"os"
88

99
"cdr.dev/coder-cli/coder-sdk"
10+
"cdr.dev/coder-cli/internal/x/xcobra"
1011
"cdr.dev/coder-cli/pkg/clog"
1112
"cdr.dev/coder-cli/pkg/tablewriter"
1213

@@ -159,7 +160,7 @@ func createEnvCmd() *cobra.Command {
159160
cmd := &cobra.Command{
160161
Use: "create [environment_name]",
161162
Short: "create a new environment.",
162-
Args: cobra.ExactArgs(1),
163+
Args: xcobra.ExactArgs(1),
163164
Long: "Create a new Coder environment.",
164165
Example: `# create a new environment using default resource amounts
165166
coder envs create my-new-env --image ubuntu
@@ -267,7 +268,7 @@ func editEnvCmd() *cobra.Command {
267268
cmd := &cobra.Command{
268269
Use: "edit",
269270
Short: "edit an existing environment and initiate a rebuild.",
270-
Args: cobra.ExactArgs(1),
271+
Args: xcobra.ExactArgs(1),
271272
Long: "Edit an existing environment and initate a rebuild.",
272273
Example: `coder envs edit back-end-env --cpu 4
273274

internal/cmd/login.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"cdr.dev/coder-cli/internal/config"
1313
"cdr.dev/coder-cli/internal/loginsrv"
1414
"cdr.dev/coder-cli/internal/version"
15+
"cdr.dev/coder-cli/internal/x/xcobra"
1516
"cdr.dev/coder-cli/pkg/clog"
1617
"github.com/pkg/browser"
1718
"github.com/spf13/cobra"
@@ -23,7 +24,7 @@ func loginCmd() *cobra.Command {
2324
return &cobra.Command{
2425
Use: "login [Coder Enterprise URL eg. https://my.coder.domain/]",
2526
Short: "Authenticate this client for future operations",
26-
Args: cobra.ExactArgs(1),
27+
Args: xcobra.ExactArgs(1),
2728
RunE: func(cmd *cobra.Command, args []string) error {
2829
// Pull the URL from the args and do some sanity check.
2930
rawURL := args[0]

internal/cmd/rebuild.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"time"
99

1010
"cdr.dev/coder-cli/coder-sdk"
11+
"cdr.dev/coder-cli/internal/x/xcobra"
1112
"cdr.dev/coder-cli/pkg/clog"
1213
"github.com/briandowns/spinner"
1314
"github.com/fatih/color"
@@ -24,7 +25,7 @@ func rebuildEnvCommand() *cobra.Command {
2425
cmd := &cobra.Command{
2526
Use: "rebuild [environment_name]",
2627
Short: "rebuild a Coder environment",
27-
Args: cobra.ExactArgs(1),
28+
Args: xcobra.ExactArgs(1),
2829
Example: `coder envs rebuild front-end-env --follow
2930
coder envs rebuild backend-env --force`,
3031
RunE: func(cmd *cobra.Command, args []string) error {
@@ -144,7 +145,7 @@ func watchBuildLogCommand() *cobra.Command {
144145
Use: "watch-build [environment_name]",
145146
Example: "coder envs watch-build front-end-env",
146147
Short: "trail the build log of a Coder environment",
147-
Args: cobra.ExactArgs(1),
148+
Args: xcobra.ExactArgs(1),
148149
RunE: func(cmd *cobra.Command, args []string) error {
149150
ctx := cmd.Context()
150151
client, err := newClient(ctx)

internal/cmd/sync.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010

1111
"cdr.dev/coder-cli/coder-sdk"
1212
"cdr.dev/coder-cli/internal/sync"
13+
"cdr.dev/coder-cli/internal/x/xcobra"
1314
"cdr.dev/coder-cli/pkg/clog"
1415
"github.com/spf13/cobra"
1516
"golang.org/x/xerrors"
@@ -20,7 +21,7 @@ func syncCmd() *cobra.Command {
2021
cmd := &cobra.Command{
2122
Use: "sync [local directory] [<env name>:<remote directory>]",
2223
Short: "Establish a one way directory sync to a Coder environment",
23-
Args: cobra.ExactArgs(2),
24+
Args: xcobra.ExactArgs(2),
2425
RunE: makeRunSync(&init),
2526
}
2627
cmd.Flags().BoolVar(&init, "init", false, "do initial transfer and exit")

internal/cmd/tags.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"os"
66

77
"cdr.dev/coder-cli/coder-sdk"
8+
"cdr.dev/coder-cli/internal/x/xcobra"
89
"cdr.dev/coder-cli/pkg/clog"
910
"cdr.dev/coder-cli/pkg/tablewriter"
1011
"github.com/spf13/cobra"
@@ -37,7 +38,7 @@ func tagsCreateCmd() *cobra.Command {
3738
Short: "add an image tag",
3839
Long: "allow users to create environments with this image tag",
3940
Example: `coder tags create latest --image ubuntu --org default`,
40-
Args: cobra.ExactArgs(1),
41+
Args: xcobra.ExactArgs(1),
4142
RunE: func(cmd *cobra.Command, args []string) error {
4243
ctx := cmd.Context()
4344
client, err := newClient(ctx)
@@ -139,7 +140,7 @@ func tagsRmCmd() *cobra.Command {
139140
Use: "rm [tag]",
140141
Short: "remove an image tag",
141142
Example: `coder tags rm latest --image ubuntu --org default`,
142-
Args: cobra.ExactArgs(1),
143+
Args: xcobra.ExactArgs(1),
143144
RunE: func(cmd *cobra.Command, args []string) error {
144145
ctx := cmd.Context()
145146
client, err := newClient(ctx)

internal/cmd/tokens.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"fmt"
55

66
"cdr.dev/coder-cli/coder-sdk"
7+
"cdr.dev/coder-cli/internal/x/xcobra"
78
"cdr.dev/coder-cli/pkg/tablewriter"
89
"github.com/spf13/cobra"
910
)
@@ -55,7 +56,7 @@ func createTokensCmd() *cobra.Command {
5556
return &cobra.Command{
5657
Use: "create [token_name]",
5758
Short: "create generates a new API token and prints it to stdout",
58-
Args: cobra.ExactArgs(1),
59+
Args: xcobra.ExactArgs(1),
5960
RunE: func(cmd *cobra.Command, args []string) error {
6061
ctx := cmd.Context()
6162
client, err := newClient(ctx)
@@ -78,7 +79,7 @@ func rmTokenCmd() *cobra.Command {
7879
return &cobra.Command{
7980
Use: "rm [token_id]",
8081
Short: "remove an API token by its unique ID",
81-
Args: cobra.ExactArgs(1),
82+
Args: xcobra.ExactArgs(1),
8283
RunE: func(cmd *cobra.Command, args []string) error {
8384
ctx := cmd.Context()
8485
client, err := newClient(ctx)
@@ -97,7 +98,7 @@ func regenTokenCmd() *cobra.Command {
9798
return &cobra.Command{
9899
Use: "regen [token_id]",
99100
Short: "regenerate an API token by its unique ID and print the new token to stdout",
100-
Args: cobra.ExactArgs(1),
101+
Args: xcobra.ExactArgs(1),
101102
RunE: func(cmd *cobra.Command, args []string) error {
102103
ctx := cmd.Context()
103104
client, err := newClient(ctx)

internal/cmd/urls.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
"golang.org/x/xerrors"
1414

1515
"cdr.dev/coder-cli/coder-sdk"
16+
"cdr.dev/coder-cli/internal/x/xcobra"
1617
"cdr.dev/coder-cli/pkg/clog"
1718
"cdr.dev/coder-cli/pkg/tablewriter"
1819
)
@@ -26,7 +27,7 @@ func urlCmd() *cobra.Command {
2627
lsCmd := &cobra.Command{
2728
Use: "ls [environment_name]",
2829
Short: "List all DevURLs for an environment",
29-
Args: cobra.ExactArgs(1),
30+
Args: xcobra.ExactArgs(1),
3031
ValidArgsFunction: getEnvsForCompletion(coder.Me),
3132
RunE: listDevURLsCmd(&outputFmt),
3233
}
@@ -126,7 +127,7 @@ func createDevURLCmd() *cobra.Command {
126127
Use: "create [env_name] [port]",
127128
Short: "Create a new devurl for an environment",
128129
Aliases: []string{"edit"},
129-
Args: cobra.ExactArgs(2),
130+
Args: xcobra.ExactArgs(2),
130131
// Run creates or updates a devURL
131132
RunE: func(cmd *cobra.Command, args []string) error {
132133
var (

internal/x/xcobra/cobra.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// Package xcobra wraps the cobra package to provide richer functionality.
2+
package xcobra
3+
4+
import (
5+
"fmt"
6+
7+
"cdr.dev/coder-cli/pkg/clog"
8+
"github.com/spf13/cobra"
9+
)
10+
11+
// ExactArgs returns an error if there are not exactly n args.
12+
func ExactArgs(n int) cobra.PositionalArgs {
13+
return func(cmd *cobra.Command, args []string) error {
14+
if len(args) != n {
15+
return clog.Error(
16+
fmt.Sprintf("accepts %d arg(s), received %d", n, len(args)),
17+
clog.Bold("usage: ")+cmd.UseLine(),
18+
clog.BlankLine,
19+
clog.Tipf("use \"--help\" for more info"),
20+
)
21+
}
22+
return nil
23+
}
24+
}

0 commit comments

Comments
 (0)