Skip to content

Commit 944dbfa

Browse files
authored
Merge branch 'main' into cj/template-ttl-default
2 parents b94a3ee + 92ebdae commit 944dbfa

File tree

110 files changed

+3573
-1719
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

110 files changed

+3573
-1719
lines changed

.github/CODEOWNERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
site/ @coder/frontend
2+
docs/ @ammario @jsjoeio

.github/workflows/coder.yaml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -369,7 +369,8 @@ jobs:
369369
./scripts/build_go_matrix.sh \
370370
--output ./dist/ \
371371
--package-linux \
372-
linux:amd64
372+
linux:amd64 \
373+
windows:amd64
373374
374375
- name: Install Release
375376
run: |
@@ -387,6 +388,7 @@ jobs:
387388
name: coder
388389
path: |
389390
./dist/*.zip
391+
./dist/*.exe
390392
./dist/*.tar.gz
391393
./dist/*.apk
392394
./dist/*.deb

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ test-postgres: test-clean test-postgres-docker
175175
DB=ci DB_FROM=$(shell go run scripts/migrate-ci/main.go) gotestsum --junitfile="gotests.xml" --packages="./..." -- \
176176
-covermode=atomic -coverprofile="gotests.coverage" -timeout=30m \
177177
-coverpkg=./...,github.com/coder/coder/codersdk \
178-
-count=2 -race -failfast
178+
-count=1 -race -failfast
179179
.PHONY: test-postgres
180180

181181
test-postgres-docker:

agent/reaper/reaper_stub.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,6 @@ func IsInitProcess() bool {
77
return false
88
}
99

10-
func ForkReap(opt ...Option) error {
10+
func ForkReap(_ ...Option) error {
1111
return nil
1212
}

cli/cliflag/cliflag.go

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ func StringArrayVarP(flagset *pflag.FlagSet, ptr *[]string, name string, shortha
4747
def = strings.Split(val, ",")
4848
}
4949
}
50-
flagset.StringArrayVarP(ptr, name, shorthand, def, usage)
50+
flagset.StringArrayVarP(ptr, name, shorthand, def, fmtUsage(usage, env))
5151
}
5252

5353
// Uint8VarP sets a uint8 flag on the given flag set.
@@ -102,9 +102,14 @@ func DurationVarP(flagset *pflag.FlagSet, ptr *time.Duration, name string, short
102102
}
103103

104104
func fmtUsage(u string, env string) string {
105-
if env == "" {
106-
return fmt.Sprintf("%s.", u)
105+
if env != "" {
106+
// Avoid double dotting.
107+
dot := "."
108+
if strings.HasSuffix(u, ".") {
109+
dot = ""
110+
}
111+
u = fmt.Sprintf("%s%s\nConsumes $%s", u, dot, env)
107112
}
108113

109-
return fmt.Sprintf("%s - consumes $%s.", u, env)
114+
return u
110115
}

cli/cliflag/cliflag_test.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ func TestCliflag(t *testing.T) {
2424
require.NoError(t, err)
2525
require.Equal(t, def, got)
2626
require.Contains(t, flagset.FlagUsages(), usage)
27-
require.Contains(t, flagset.FlagUsages(), fmt.Sprintf(" - consumes $%s", env))
27+
require.Contains(t, flagset.FlagUsages(), fmt.Sprintf("Consumes $%s", env))
2828
})
2929

3030
t.Run("StringEnvVar", func(t *testing.T) {
@@ -48,7 +48,7 @@ func TestCliflag(t *testing.T) {
4848
require.NoError(t, err)
4949
require.Equal(t, def, got)
5050
require.Contains(t, flagset.FlagUsages(), usage)
51-
require.Contains(t, flagset.FlagUsages(), fmt.Sprintf(" - consumes $%s", env))
51+
require.Contains(t, flagset.FlagUsages(), fmt.Sprintf("Consumes $%s", env))
5252
})
5353

5454
t.Run("StringVarPEnvVar", func(t *testing.T) {
@@ -74,7 +74,7 @@ func TestCliflag(t *testing.T) {
7474
require.NoError(t, err)
7575
require.Equal(t, def, got)
7676
require.Contains(t, flagset.FlagUsages(), usage)
77-
require.NotContains(t, flagset.FlagUsages(), " - consumes")
77+
require.NotContains(t, flagset.FlagUsages(), "Consumes")
7878
})
7979

8080
t.Run("StringArrayDefault", func(t *testing.T) {
@@ -117,7 +117,7 @@ func TestCliflag(t *testing.T) {
117117
require.NoError(t, err)
118118
require.Equal(t, uint8(def), got)
119119
require.Contains(t, flagset.FlagUsages(), usage)
120-
require.Contains(t, flagset.FlagUsages(), fmt.Sprintf(" - consumes $%s", env))
120+
require.Contains(t, flagset.FlagUsages(), fmt.Sprintf("Consumes $%s", env))
121121
})
122122

123123
t.Run("IntEnvVar", func(t *testing.T) {
@@ -156,7 +156,7 @@ func TestCliflag(t *testing.T) {
156156
require.NoError(t, err)
157157
require.Equal(t, def, got)
158158
require.Contains(t, flagset.FlagUsages(), usage)
159-
require.Contains(t, flagset.FlagUsages(), fmt.Sprintf(" - consumes $%s", env))
159+
require.Contains(t, flagset.FlagUsages(), fmt.Sprintf("Consumes $%s", env))
160160
})
161161

162162
t.Run("BoolEnvVar", func(t *testing.T) {
@@ -195,7 +195,7 @@ func TestCliflag(t *testing.T) {
195195
require.NoError(t, err)
196196
require.Equal(t, def, got)
197197
require.Contains(t, flagset.FlagUsages(), usage)
198-
require.Contains(t, flagset.FlagUsages(), fmt.Sprintf(" - consumes $%s", env))
198+
require.Contains(t, flagset.FlagUsages(), fmt.Sprintf("Consumes $%s", env))
199199
})
200200

201201
t.Run("DurationEnvVar", func(t *testing.T) {

cli/cliui/cliui.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ var Styles = struct {
2626
Checkmark,
2727
Code,
2828
Crossmark,
29+
DateTimeStamp,
2930
Error,
3031
Field,
3132
Keyword,
@@ -42,6 +43,7 @@ var Styles = struct {
4243
Checkmark: defaultStyles.Checkmark,
4344
Code: defaultStyles.Code,
4445
Crossmark: defaultStyles.Error.Copy().SetString("✘"),
46+
DateTimeStamp: defaultStyles.LabelDim,
4547
Error: defaultStyles.Error,
4648
Field: defaultStyles.Code.Copy().Foreground(lipgloss.AdaptiveColor{Light: "#000000", Dark: "#FFFFFF"}),
4749
Keyword: defaultStyles.Keyword,

cli/cliui/parameter.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ func ParameterSchema(cmd *cobra.Command, parameterSchema codersdk.ParameterSchem
4747
value, err = Prompt(cmd, PromptOptions{
4848
Text: Styles.Bold.Render(text),
4949
})
50+
value = strings.TrimSpace(value)
5051
}
5152
if err != nil {
5253
return "", err

cli/configssh.go

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -141,15 +141,16 @@ func configSSH() *cobra.Command {
141141
Annotations: workspaceCommand,
142142
Use: "config-ssh",
143143
Short: "Populate your SSH config with Host entries for all of your workspaces",
144-
Example: `
145-
- You can use -o (or --ssh-option) so set SSH options to be used for all your
146-
workspaces.
147-
148-
` + cliui.Styles.Code.Render("$ coder config-ssh -o ForwardAgent=yes") + `
149-
150-
- You can use --dry-run (or -n) to see the changes that would be made.
151-
152-
` + cliui.Styles.Code.Render("$ coder config-ssh --dry-run"),
144+
Example: formatExamples(
145+
example{
146+
Description: "You can use -o (or --ssh-option) so set SSH options to be used for all your workspaces",
147+
Command: "coder config-ssh -o ForwardAgent=yes",
148+
},
149+
example{
150+
Description: "You can use --dry-run (or -n) to see the changes that would be made",
151+
Command: "coder config-ssh --dry-run",
152+
},
153+
),
153154
RunE: func(cmd *cobra.Command, args []string) error {
154155
client, err := createClient(cmd)
155156
if err != nil {

cli/create.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ func create() *cobra.Command {
155155
return err
156156
}
157157

158-
_, _ = fmt.Fprintf(cmd.OutOrStdout(), "\nThe %s workspace has been created!\n", cliui.Styles.Keyword.Render(workspace.Name))
158+
_, _ = fmt.Fprintf(cmd.OutOrStdout(), "\nThe %s workspace has been created at %s!\n", cliui.Styles.Keyword.Render(workspace.Name), cliui.Styles.DateTimeStamp.Render(time.Now().Format(time.Stamp)))
159159
return nil
160160
},
161161
}

cli/delete.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ func deleteWorkspace() *cobra.Command {
4848
return err
4949
}
5050

51-
_, _ = fmt.Fprintf(cmd.OutOrStdout(), "\nThe %s workspace has been deleted!\n", cliui.Styles.Keyword.Render(workspace.Name))
51+
_, _ = fmt.Fprintf(cmd.OutOrStdout(), "\nThe %s workspace has been deleted at %s!\n", cliui.Styles.Keyword.Render(workspace.Name), cliui.Styles.DateTimeStamp.Render(time.Now().Format(time.Stamp)))
5252
return nil
5353
},
5454
}

cli/dotfiles.go

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,17 @@ import (
1818
)
1919

2020
func dotfiles() *cobra.Command {
21-
var (
22-
symlinkDir string
23-
)
21+
var symlinkDir string
2422
cmd := &cobra.Command{
25-
Use: "dotfiles [git_repo_url]",
26-
Args: cobra.ExactArgs(1),
27-
Short: "Checkout and install a dotfiles repository.",
28-
Example: "coder dotfiles [-y] git@github.com:example/dotfiles.git",
23+
Use: "dotfiles [git_repo_url]",
24+
Args: cobra.ExactArgs(1),
25+
Short: "Check out and install a dotfiles repository.",
26+
Example: formatExamples(
27+
example{
28+
Description: "Check out and install a dotfiles repository without prompts",
29+
Command: "coder dotfiles --yes git@github.com:example/dotfiles.git",
30+
},
31+
),
2932
RunE: func(cmd *cobra.Command, args []string) error {
3033
var (
3134
dotfilesRepoDir = "dotfiles"

cli/list.go

Lines changed: 1 addition & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -58,33 +58,7 @@ func list() *cobra.Command {
5858

5959
now := time.Now()
6060
for _, workspace := range workspaces {
61-
status := ""
62-
inProgress := false
63-
if workspace.LatestBuild.Job.Status == codersdk.ProvisionerJobRunning ||
64-
workspace.LatestBuild.Job.Status == codersdk.ProvisionerJobCanceling {
65-
inProgress = true
66-
}
67-
68-
switch workspace.LatestBuild.Transition {
69-
case codersdk.WorkspaceTransitionStart:
70-
status = "Running"
71-
if inProgress {
72-
status = "Starting"
73-
}
74-
case codersdk.WorkspaceTransitionStop:
75-
status = "Stopped"
76-
if inProgress {
77-
status = "Stopping"
78-
}
79-
case codersdk.WorkspaceTransitionDelete:
80-
status = "Deleted"
81-
if inProgress {
82-
status = "Deleting"
83-
}
84-
}
85-
if workspace.LatestBuild.Job.Status == codersdk.ProvisionerJobFailed {
86-
status = "Failed"
87-
}
61+
status := codersdk.WorkspaceDisplayStatus(workspace.LatestBuild.Job.Status, workspace.LatestBuild.Transition)
8862

8963
lastBuilt := time.Now().UTC().Sub(workspace.LatestBuild.Job.CreatedAt).Truncate(time.Second)
9064
autostartDisplay := "-"

cli/list_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ func TestList(t *testing.T) {
3737
close(done)
3838
}()
3939
pty.ExpectMatch(workspace.Name)
40-
pty.ExpectMatch("Running")
40+
pty.ExpectMatch("Started")
4141
cancelFunc()
4242
<-done
4343
})

cli/login.go

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -131,26 +131,29 @@ func login() *cobra.Command {
131131
}
132132

133133
if password == "" {
134-
password, err = cliui.Prompt(cmd, cliui.PromptOptions{
135-
Text: "Enter a " + cliui.Styles.Field.Render("password") + ":",
136-
Secret: true,
137-
Validate: cliui.ValidateNotEmpty,
138-
})
139-
if err != nil {
140-
return xerrors.Errorf("specify password prompt: %w", err)
141-
}
142-
_, err = cliui.Prompt(cmd, cliui.PromptOptions{
143-
Text: "Confirm " + cliui.Styles.Field.Render("password") + ":",
144-
Secret: true,
145-
Validate: func(s string) error {
146-
if s != password {
147-
return xerrors.Errorf("Passwords do not match")
148-
}
149-
return nil
150-
},
151-
})
152-
if err != nil {
153-
return xerrors.Errorf("confirm password prompt: %w", err)
134+
var matching bool
135+
136+
for !matching {
137+
password, err = cliui.Prompt(cmd, cliui.PromptOptions{
138+
Text: "Enter a " + cliui.Styles.Field.Render("password") + ":",
139+
Secret: true,
140+
Validate: cliui.ValidateNotEmpty,
141+
})
142+
if err != nil {
143+
return xerrors.Errorf("specify password prompt: %w", err)
144+
}
145+
confirm, err := cliui.Prompt(cmd, cliui.PromptOptions{
146+
Text: "Confirm " + cliui.Styles.Field.Render("password") + ":",
147+
Secret: true,
148+
})
149+
if err != nil {
150+
return xerrors.Errorf("confirm password prompt: %w", err)
151+
}
152+
153+
matching = confirm == password
154+
if !matching {
155+
_, _ = fmt.Fprintln(cmd.OutOrStdout(), cliui.Styles.Error.Render("Passwords do not match"))
156+
}
154157
}
155158
}
156159

cli/login_test.go

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"github.com/stretchr/testify/require"
99

1010
"github.com/coder/coder/cli/clitest"
11+
"github.com/coder/coder/cli/cliui"
1112
"github.com/coder/coder/coderd/coderdtest"
1213
"github.com/coder/coder/pty/ptytest"
1314
)
@@ -92,7 +93,7 @@ func TestLogin(t *testing.T) {
9293
go func() {
9394
defer close(doneChan)
9495
err := root.ExecuteContext(ctx)
95-
assert.ErrorIs(t, err, context.Canceled)
96+
assert.NoError(t, err)
9697
}()
9798

9899
matches := []string{
@@ -108,9 +109,15 @@ func TestLogin(t *testing.T) {
108109
pty.ExpectMatch(match)
109110
pty.WriteLine(value)
110111
}
112+
113+
// Validate that we reprompt for matching passwords.
111114
pty.ExpectMatch("Passwords do not match")
112-
pty.ExpectMatch("password") // Re-prompt password.
113-
cancel()
115+
pty.ExpectMatch("Enter a " + cliui.Styles.Field.Render("password"))
116+
117+
pty.WriteLine("pass")
118+
pty.ExpectMatch("Confirm")
119+
pty.WriteLine("pass")
120+
pty.ExpectMatch("Welcome to Coder")
114121
<-doneChan
115122
})
116123

cli/logout.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ func logout() *cobra.Command {
2626
config := createConfig(cmd)
2727

2828
_, err = cliui.Prompt(cmd, cliui.PromptOptions{
29-
Text: "Are you sure you want to logout?",
29+
Text: "Are you sure you want to log out?",
3030
IsConfirm: true,
3131
Default: "yes",
3232
})

cli/logout_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ func TestLogout(t *testing.T) {
4141
assert.NoFileExists(t, string(config.Session()))
4242
}()
4343

44-
pty.ExpectMatch("Are you sure you want to logout?")
44+
pty.ExpectMatch("Are you sure you want to log out?")
4545
pty.WriteLine("yes")
4646
pty.ExpectMatch("You are no longer logged in. You can log in using 'coder login <url>'.")
4747
<-logoutChan
@@ -186,7 +186,7 @@ func TestLogout(t *testing.T) {
186186
assert.Regexp(t, errRegex, err.Error())
187187
}()
188188

189-
pty.ExpectMatch("Are you sure you want to logout?")
189+
pty.ExpectMatch("Are you sure you want to log out?")
190190
pty.WriteLine("yes")
191191
<-logoutChan
192192
})

cli/parameters.go

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

1111
func parameters() *cobra.Command {
1212
cmd := &cobra.Command{
13-
Short: "List parameters for a given scope",
14-
Example: "coder parameters list workspace my-workspace",
15-
Use: "parameters",
13+
Short: "List parameters for a given scope",
14+
Example: formatExamples(
15+
example{
16+
Command: "coder parameters list workspace my-workspace",
17+
},
18+
),
19+
Use: "parameters",
1620
// Currently hidden as this shows parameter values, not parameter
1721
// schemes. Until we have a good way to distinguish the two, it's better
1822
// not to add confusion or lock ourselves into a certain api.

0 commit comments

Comments
 (0)