Skip to content

Commit c4e8925

Browse files
committed
44 problems left...
WOOOO
1 parent a678576 commit c4e8925

23 files changed

+283
-520
lines changed

cli/clitest/clitest.go

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ import (
2727
// New creates a CLI instance with a configuration pointed to a
2828
// temporary testing directory.
2929
func New(t *testing.T, args ...string) (*clibase.Invokation, config.Root) {
30-
return NewWithSubcommands(t, cli.AGPL(), args...)
30+
var root cli.RootCmd
31+
return NewWithSubcommands(t, cli.AGPL(&root), args...)
3132
}
3233

3334
type logWriter struct {
@@ -126,6 +127,25 @@ func Start(t *testing.T, inv *clibase.Invokation) {
126127
t.Helper()
127128

128129
closeCh := make(chan struct{})
130+
go func() {
131+
defer close(closeCh)
132+
err := <-StartErr(t, inv)
133+
if err != nil {
134+
assert.NoError(t, err)
135+
}
136+
}()
137+
138+
t.Cleanup(func() {
139+
<-closeCh
140+
})
141+
}
142+
143+
// StartErr runs the command in a goroutine but returns the error
144+
// instead of asserting it. This is useful for testing error cases.
145+
func StartErr(t *testing.T, inv *clibase.Invokation) <-chan error {
146+
t.Helper()
147+
148+
errCh := make(chan error, 1)
129149

130150
ctx := inv.Context()
131151

@@ -139,16 +159,14 @@ func Start(t *testing.T, inv *clibase.Invokation) {
139159

140160
go func() {
141161
defer cancel()
142-
defer close(closeCh)
143-
err := inv.Run()
144-
if ctx.Err() == nil {
145-
assert.NoError(t, err)
146-
}
162+
defer close(errCh)
163+
errCh <- inv.Run()
147164
}()
148165

149166
// Don't exit test routine until server is done.
150167
t.Cleanup(func() {
151168
cancel()
152-
<-closeCh
169+
<-errCh
153170
})
171+
return errCh
154172
}

cmd/cliui/main.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ func main() {
2727

2828
root.Children = append(root.Children, &clibase.Cmd{
2929
Use: "prompt",
30-
Handler: func(cmd *clibase.Cmd, args []string) error {
31-
_, err := cliui.Prompt(cmd, cliui.PromptOptions{
30+
Handler: func(inv *clibase.Invokation) error {
31+
_, err := cliui.Prompt(inv, cliui.PromptOptions{
3232
Text: "What is our " + cliui.Styles.Field.Render("company name") + "?",
3333
Default: "acme-corp",
3434
Validate: func(s string) error {
@@ -44,7 +44,7 @@ func main() {
4444
if err != nil {
4545
return err
4646
}
47-
_, err = cliui.Prompt(cmd, cliui.PromptOptions{
47+
_, err = cliui.Prompt(inv, cliui.PromptOptions{
4848
Text: "Do you want to accept?",
4949
Default: cliui.ConfirmYes,
5050
IsConfirm: true,
@@ -55,7 +55,7 @@ func main() {
5555
if err != nil {
5656
return err
5757
}
58-
_, err = cliui.Prompt(cmd, cliui.PromptOptions{
58+
_, err = cliui.Prompt(inv, cliui.PromptOptions{
5959
Text: "Enter password",
6060
Secret: true,
6161
})
@@ -70,7 +70,7 @@ func main() {
7070
Options: []string{"Tomato", "Banana", "Onion", "Grape", "Lemon"},
7171
Size: 3,
7272
})
73-
fmt.Printf("Selected: %q\n", value)
73+
_, _ = fmt.Printf("Selected: %q\n", value)
7474
return err
7575
},
7676
})
@@ -182,7 +182,7 @@ func main() {
182182
if err != nil {
183183
return err
184184
}
185-
fmt.Printf("Completed!\n")
185+
_, _ = fmt.Printf("Completed!\n")
186186
return nil
187187
},
188188
})

cmd/coder/main.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,6 @@ import (
77
)
88

99
func main() {
10-
cli.Main(cli.AGPL())
10+
var rootCmd cli.RootCmd
11+
cli.Main(cli.AGPL(&rootCmd))
1112
}

enterprise/cli/features.go

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import (
1010

1111
"golang.org/x/xerrors"
1212

13-
agpl "github.com/coder/coder/cli"
1413
"github.com/coder/coder/cli/clibase"
1514
"github.com/coder/coder/cli/cliui"
1615
"github.com/coder/coder/codersdk"
@@ -37,15 +36,15 @@ func (r *RootCmd) featuresList() *clibase.Cmd {
3736
columns []string
3837
outputFormat string
3938
)
39+
client := new(codersdk.Client)
4040

4141
cmd := &clibase.Cmd{
4242
Use: "list",
4343
Aliases: []string{"ls"},
44+
Middleware: clibase.Chain(
45+
r.UseClient(client),
46+
),
4447
Handler: func(inv *clibase.Invokation) error {
45-
client, err := agpl.CreateClient(cmd)
46-
if err != nil {
47-
return err
48-
}
4948
entitlements, err := client.Entitlements(inv.Context())
5049
var apiError *codersdk.Error
5150
if errors.As(err, &apiError) && apiError.StatusCode() == http.StatusNotFound {
@@ -82,10 +81,25 @@ func (r *RootCmd) featuresList() *clibase.Cmd {
8281
},
8382
}
8483

85-
cmd.Flags().StringArrayVarP(&columns, "column", "c", featureColumns,
86-
fmt.Sprintf("Specify a column to filter in the table. Available columns are: %s",
87-
strings.Join(featureColumns, ", ")))
88-
cmd.Flags().StringVarP(&outputFormat, "output", "o", "table", "Output format. Available formats are: table, json.")
84+
cmd.Options = clibase.OptionSet{
85+
{
86+
Flag: "column",
87+
FlagShorthand: "c",
88+
Description: fmt.Sprintf("Specify a column to filter in the table. Available columns are: %s",
89+
strings.Join(featureColumns, ", "),
90+
),
91+
Default: strings.Join(featureColumns, ","),
92+
Value: clibase.StringsOf(&columns),
93+
},
94+
{
95+
Flag: "output",
96+
FlagShorthand: "o",
97+
Description: "Output format. Available formats are: table, json.",
98+
Default: "table",
99+
Value: clibase.StringOf(&outputFormat),
100+
},
101+
}
102+
89103
return cmd
90104
}
91105

enterprise/cli/features_test.go

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,13 @@ func TestFeaturesList(t *testing.T) {
2222
t.Parallel()
2323
client := coderdenttest.New(t, nil)
2424
coderdtest.CreateFirstUser(t, client)
25-
inv, root := clitest.NewWithSubcommands(t, cli.EnterpriseSubcommands(), "features", "list")
26-
clitest.SetupConfig(t, client, root)
25+
var root cli.RootCmd
26+
inv, conf := clitest.NewWithSubcommands(t, root.EnterpriseSubcommands(), "features", "list")
27+
clitest.SetupConfig(t, client, conf)
2728
pty := ptytest.New(t)
2829
inv.Stdin = pty.Input()
2930
inv.Stdout = pty.Output()
30-
errC := make(chan error)
31-
go func() {
32-
errC <- inv.Run()
33-
}()
34-
require.NoError(t, <-errC)
31+
clitest.Start(t, inv)
3532
pty.ExpectMatch("user_limit")
3633
pty.ExpectMatch("not_entitled")
3734
})
@@ -40,8 +37,9 @@ func TestFeaturesList(t *testing.T) {
4037

4138
client := coderdenttest.New(t, nil)
4239
coderdtest.CreateFirstUser(t, client)
43-
inv, root := clitest.NewWithSubcommands(t, cli.EnterpriseSubcommands(), "features", "list", "-o", "json")
44-
clitest.SetupConfig(t, client, root)
40+
var root cli.RootCmd
41+
inv, conf := clitest.NewWithSubcommands(t, root.EnterpriseSubcommands(), "features", "list", "-o", "json")
42+
clitest.SetupConfig(t, client, conf)
4543
doneChan := make(chan struct{})
4644

4745
buf := bytes.NewBuffer(nil)

enterprise/cli/groupcreate.go

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,25 +7,23 @@ import (
77

88
agpl "github.com/coder/coder/cli"
99
"github.com/coder/coder/cli/clibase"
10-
"github.com/coder/coder/cli/cliflag"
1110
"github.com/coder/coder/cli/cliui"
1211
"github.com/coder/coder/codersdk"
1312
)
1413

1514
func (r *RootCmd) groupCreate() *clibase.Cmd {
1615
var avatarURL string
16+
client := new(codersdk.Client)
1717
cmd := &clibase.Cmd{
18-
Use: "create <name>",
19-
Short: "Create a user group",
20-
Middleware: clibase.RequireNArgs(1),
18+
Use: "create <name>",
19+
Short: "Create a user group",
20+
Middleware: clibase.Chain(
21+
clibase.RequireNArgs(1),
22+
r.UseClient(client),
23+
),
2124
Handler: func(inv *clibase.Invokation) error {
2225
ctx := inv.Context()
2326

24-
client, err := agpl.CreateClient(cmd)
25-
if err != nil {
26-
return xerrors.Errorf("create client: %w", err)
27-
}
28-
2927
org, err := agpl.CurrentOrganization(inv, client)
3028
if err != nil {
3129
return xerrors.Errorf("current organization: %w", err)
@@ -44,7 +42,15 @@ func (r *RootCmd) groupCreate() *clibase.Cmd {
4442
},
4543
}
4644

47-
cliflag.StringVarP(cmd.Flags(), &avatarURL, "avatar-url", "u", "CODER_AVATAR_URL", "", "set an avatar for a group")
45+
cmd.Options = clibase.OptionSet{
46+
{
47+
Flag: "avatar-url",
48+
Description: `set an avatar for a group`,
49+
FlagShorthand: "u",
50+
Env: "CODER_AVATAR_URL",
51+
Value: clibase.StringOf(&avatarURL),
52+
},
53+
}
4854

4955
return cmd
5056
}

enterprise/cli/groupcreate_test.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,15 @@ func TestCreateGroup(t *testing.T) {
3535
avatarURL = "https://example.com"
3636
)
3737

38-
inv, root := clitest.NewWithSubcommands(t, cli.EnterpriseSubcommands(), "groups",
38+
var root cli.RootCmd
39+
inv, conf := clitest.NewWithSubcommands(t, root.EnterpriseSubcommands(), "groups",
3940
"create", groupName,
4041
"--avatar-url", avatarURL,
4142
)
4243

4344
pty := ptytest.New(t)
4445
inv.Stdout = pty.Output()
45-
clitest.SetupConfig(t, client, root)
46+
clitest.SetupConfig(t, client, conf)
4647

4748
err := inv.Run()
4849
require.NoError(t, err)

enterprise/cli/groupdelete.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,24 +8,24 @@ import (
88
agpl "github.com/coder/coder/cli"
99
"github.com/coder/coder/cli/clibase"
1010
"github.com/coder/coder/cli/cliui"
11+
"github.com/coder/coder/codersdk"
1112
)
1213

1314
func (r *RootCmd) groupDelete() *clibase.Cmd {
15+
client := new(codersdk.Client)
1416
cmd := &clibase.Cmd{
15-
Use: "delete <name>",
16-
Short: "Delete a user group",
17-
Middleware: clibase.RequireNArgs(1),
17+
Use: "delete <name>",
18+
Short: "Delete a user group",
19+
Middleware: clibase.Chain(
20+
clibase.RequireNArgs(1),
21+
r.UseClient(client),
22+
),
1823
Handler: func(inv *clibase.Invokation) error {
1924
var (
2025
ctx = inv.Context()
2126
groupName = inv.Args[0]
2227
)
2328

24-
client, err := agpl.CreateClient(cmd)
25-
if err != nil {
26-
return xerrors.Errorf("create client: %w", err)
27-
}
28-
2929
org, err := agpl.CurrentOrganization(inv, client)
3030
if err != nil {
3131
return xerrors.Errorf("current organization: %w", err)

enterprise/cli/groupdelete_test.go

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,15 @@ func TestGroupDelete(t *testing.T) {
3838
})
3939
require.NoError(t, err)
4040

41-
inv, root := clitest.NewWithSubcommands(t, cli.EnterpriseSubcommands(),
41+
var root cli.RootCmd
42+
inv, conf := clitest.NewWithSubcommands(t, root.EnterpriseSubcommands(),
4243
"groups", "delete", group.Name,
4344
)
4445

4546
pty := ptytest.New(t)
4647

4748
inv.Stdout = pty.Output()
48-
clitest.SetupConfig(t, client, root)
49+
clitest.SetupConfig(t, client, conf)
4950

5051
err = inv.Run()
5152
require.NoError(t, err)
@@ -65,10 +66,11 @@ func TestGroupDelete(t *testing.T) {
6566
},
6667
})
6768

68-
inv, root := clitest.NewWithSubcommands(t, cli.EnterpriseSubcommands(),
69+
var root cli.RootCmd
70+
inv, conf := clitest.NewWithSubcommands(t, root.EnterpriseSubcommands(),
6971
"groups", "delete")
7072

71-
clitest.SetupConfig(t, client, root)
73+
clitest.SetupConfig(t, client, conf)
7274

7375
err := inv.Run()
7476
require.Error(t, err)

0 commit comments

Comments
 (0)