Skip to content

Commit 3baa7c3

Browse files
committed
Merge branch 'main' into testhelper
2 parents d39297d + 2321160 commit 3baa7c3

File tree

238 files changed

+7897
-5295
lines changed

Some content is hidden

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

238 files changed

+7897
-5295
lines changed

.github/workflows/ci.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -512,7 +512,7 @@ jobs:
512512
- name: Install node_modules
513513
run: ./scripts/yarn_install.sh
514514

515-
- run: yarn test:ci
515+
- run: yarn test:ci --max-workers ${{ steps.cpu-cores.outputs.count }}
516516
working-directory: site
517517

518518
- uses: codecov/codecov-action@v3

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ site/test-results/*
2727
site/e2e/test-results/*
2828
site/e2e/states/*.json
2929
site/playwright-report/*
30+
site/.swc
3031

3132
# Make target for updating golden files.
3233
cli/testdata/.gen-golden

.prettierignore

+1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ site/test-results/*
3030
site/e2e/test-results/*
3131
site/e2e/states/*.json
3232
site/playwright-report/*
33+
site/.swc
3334

3435
# Make target for updating golden files.
3536
cli/testdata/.gen-golden

.vscode/settings.json

+1
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@
136136
"thead",
137137
"tios",
138138
"tmpdir",
139+
"tokenconfig",
139140
"tparallel",
140141
"trialer",
141142
"trimprefix",

agent/agent.go

+7-3
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ type Options struct {
7878
EnvironmentVariables map[string]string
7979
Logger slog.Logger
8080
AgentPorts map[int]string
81+
SSHMaxTimeout time.Duration
8182
}
8283

8384
type Client interface {
@@ -126,6 +127,7 @@ func New(options Options) io.Closer {
126127
lifecycleReported: make(chan codersdk.WorkspaceAgentLifecycle, 1),
127128
ignorePorts: options.AgentPorts,
128129
connStatsChan: make(chan *agentsdk.Stats, 1),
130+
sshMaxTimeout: options.SSHMaxTimeout,
129131
}
130132
a.init(ctx)
131133
return a
@@ -153,9 +155,10 @@ type agent struct {
153155

154156
envVars map[string]string
155157
// metadata is atomic because values can change after reconnection.
156-
metadata atomic.Value
157-
sessionToken atomic.Pointer[string]
158-
sshServer *ssh.Server
158+
metadata atomic.Value
159+
sessionToken atomic.Pointer[string]
160+
sshServer *ssh.Server
161+
sshMaxTimeout time.Duration
159162

160163
lifecycleUpdate chan struct{}
161164
lifecycleReported chan codersdk.WorkspaceAgentLifecycle
@@ -780,6 +783,7 @@ func (a *agent) init(ctx context.Context) {
780783
_ = session.Exit(1)
781784
},
782785
},
786+
MaxTimeout: a.sshMaxTimeout,
783787
}
784788

785789
go a.runLoop(ctx)

cli/agent.go

+8-5
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,11 @@ import (
3131

3232
func workspaceAgent() *cobra.Command {
3333
var (
34-
auth string
35-
logDir string
36-
pprofAddress string
37-
noReap bool
34+
auth string
35+
logDir string
36+
pprofAddress string
37+
noReap bool
38+
sshMaxTimeout time.Duration
3839
)
3940
cmd := &cobra.Command{
4041
Use: "agent",
@@ -208,7 +209,8 @@ func workspaceAgent() *cobra.Command {
208209
EnvironmentVariables: map[string]string{
209210
"GIT_ASKPASS": executablePath,
210211
},
211-
AgentPorts: agentPorts,
212+
AgentPorts: agentPorts,
213+
SSHMaxTimeout: sshMaxTimeout,
212214
})
213215
<-ctx.Done()
214216
return closer.Close()
@@ -219,6 +221,7 @@ func workspaceAgent() *cobra.Command {
219221
cliflag.StringVarP(cmd.Flags(), &logDir, "log-dir", "", "CODER_AGENT_LOG_DIR", os.TempDir(), "Specify the location for the agent log files")
220222
cliflag.StringVarP(cmd.Flags(), &pprofAddress, "pprof-address", "", "CODER_AGENT_PPROF_ADDRESS", "127.0.0.1:6060", "The address to serve pprof.")
221223
cliflag.BoolVarP(cmd.Flags(), &noReap, "no-reap", "", "", false, "Do not start a process reaper.")
224+
cliflag.DurationVarP(cmd.Flags(), &sshMaxTimeout, "ssh-max-timeout", "", "CODER_AGENT_SSH_MAX_TIMEOUT", time.Duration(0), "Specify the max timeout for a SSH connection")
222225
return cmd
223226
}
224227

cli/cliui/parameter.go

+23-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package cliui
22

33
import (
4+
"encoding/json"
45
"fmt"
56
"strings"
67

@@ -69,7 +70,28 @@ func RichParameter(cmd *cobra.Command, templateVersionParameter codersdk.Templat
6970

7071
var err error
7172
var value string
72-
if len(templateVersionParameter.Options) > 0 {
73+
if templateVersionParameter.Type == "list(string)" {
74+
// Move the cursor up a single line for nicer display!
75+
_, _ = fmt.Fprint(cmd.OutOrStdout(), "\033[1A")
76+
77+
var options []string
78+
err = json.Unmarshal([]byte(templateVersionParameter.DefaultValue), &options)
79+
if err != nil {
80+
return "", err
81+
}
82+
83+
values, err := MultiSelect(cmd, options)
84+
if err == nil {
85+
v, err := json.Marshal(&values)
86+
if err != nil {
87+
return "", err
88+
}
89+
90+
_, _ = fmt.Fprintln(cmd.OutOrStdout())
91+
_, _ = fmt.Fprintln(cmd.OutOrStdout(), " "+Styles.Prompt.String()+Styles.Field.Render(strings.Join(values, ", ")))
92+
value = string(v)
93+
}
94+
} else if len(templateVersionParameter.Options) > 0 {
7395
// Move the cursor up a single line for nicer display!
7496
_, _ = fmt.Fprint(cmd.OutOrStdout(), "\033[1A")
7597
var richParameterOption *codersdk.TemplateVersionParameterOption

cli/cliui/select.go

+38
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,21 @@ func init() {
3535
{{- template "option" $.IterateOption $ix $option}}
3636
{{- end}}
3737
{{- end }}`
38+
39+
survey.MultiSelectQuestionTemplate = `
40+
{{- define "option"}}
41+
{{- if eq .SelectedIndex .CurrentIndex }}{{color .Config.Icons.SelectFocus.Format }}{{ .Config.Icons.SelectFocus.Text }}{{color "reset"}}{{else}} {{end}}
42+
{{- if index .Checked .CurrentOpt.Index }}{{color .Config.Icons.MarkedOption.Format }} {{ .Config.Icons.MarkedOption.Text }} {{else}}{{color .Config.Icons.UnmarkedOption.Format }} {{ .Config.Icons.UnmarkedOption.Text }} {{end}}
43+
{{- color "reset"}}
44+
{{- " "}}{{- .CurrentOpt.Value}}
45+
{{end}}
46+
{{- if .ShowHelp }}{{- color .Config.Icons.Help.Format }}{{ .Config.Icons.Help.Text }} {{ .Help }}{{color "reset"}}{{"\n"}}{{end}}
47+
{{- if not .ShowAnswer }}
48+
{{- "\n"}}
49+
{{- range $ix, $option := .PageEntries}}
50+
{{- template "option" $.IterateOption $ix $option}}
51+
{{- end}}
52+
{{- end}}`
3853
}
3954

4055
type SelectOptions struct {
@@ -118,6 +133,29 @@ func Select(cmd *cobra.Command, opts SelectOptions) (string, error) {
118133
return value, err
119134
}
120135

136+
func MultiSelect(cmd *cobra.Command, items []string) ([]string, error) {
137+
// Similar hack is applied to Select()
138+
if flag.Lookup("test.v") != nil {
139+
return items, nil
140+
}
141+
142+
prompt := &survey.MultiSelect{
143+
Options: items,
144+
Default: items,
145+
}
146+
147+
var values []string
148+
err := survey.AskOne(prompt, &values, survey.WithStdio(fileReadWriter{
149+
Reader: cmd.InOrStdin(),
150+
}, fileReadWriter{
151+
Writer: cmd.OutOrStdout(),
152+
}, cmd.OutOrStdout()))
153+
if errors.Is(err, terminal.InterruptErr) {
154+
return nil, Canceled
155+
}
156+
return values, err
157+
}
158+
121159
type fileReadWriter struct {
122160
io.Reader
123161
io.Writer

cli/cliui/select_test.go

+33
Original file line numberDiff line numberDiff line change
@@ -86,3 +86,36 @@ func newRichSelect(ptty *ptytest.PTY, opts cliui.RichSelectOptions) (string, err
8686
cmd.SetIn(ptty.Input())
8787
return value, cmd.ExecuteContext(context.Background())
8888
}
89+
90+
func TestMultiSelect(t *testing.T) {
91+
t.Parallel()
92+
t.Run("MultiSelect", func(t *testing.T) {
93+
items := []string{"aaa", "bbb", "ccc"}
94+
95+
t.Parallel()
96+
ptty := ptytest.New(t)
97+
msgChan := make(chan []string)
98+
go func() {
99+
resp, err := newMultiSelect(ptty, items)
100+
assert.NoError(t, err)
101+
msgChan <- resp
102+
}()
103+
require.Equal(t, items, <-msgChan)
104+
})
105+
}
106+
107+
func newMultiSelect(ptty *ptytest.PTY, items []string) ([]string, error) {
108+
var values []string
109+
cmd := &cobra.Command{
110+
RunE: func(cmd *cobra.Command, args []string) error {
111+
selectedItems, err := cliui.MultiSelect(cmd, items)
112+
if err == nil {
113+
values = selectedItems
114+
}
115+
return err
116+
},
117+
}
118+
cmd.SetOutput(ptty.Output())
119+
cmd.SetIn(ptty.Input())
120+
return values, cmd.ExecuteContext(context.Background())
121+
}

0 commit comments

Comments
 (0)