Skip to content

Commit adbfd45

Browse files
committed
separate options for Up and Exec
1 parent cb275a2 commit adbfd45

File tree

5 files changed

+70
-55
lines changed

5 files changed

+70
-55
lines changed

agent/agentcontainers/acmock/acmock.go

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

agent/agentcontainers/api.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -684,7 +684,7 @@ func (api *API) recreateDevcontainer(dc codersdk.WorkspaceAgentDevcontainer, con
684684

685685
logger.Debug(ctx, "starting devcontainer recreation")
686686

687-
_, err = api.dccli.Up(ctx, dc.WorkspaceFolder, configPath, WithOutput(infoW, errW), WithRemoveExistingContainer())
687+
_, err = api.dccli.Up(ctx, dc.WorkspaceFolder, configPath, WithUpOutput(infoW, errW), WithRemoveExistingContainer())
688688
if err != nil {
689689
// No need to log if the API is closing (context canceled), as this
690690
// is expected behavior when the API is shutting down.

agent/agentcontainers/api_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ type fakeDevcontainerCLI struct {
6565
execErrC chan error // If set, send to return err, close to return execErr.
6666
}
6767

68-
func (f *fakeDevcontainerCLI) Up(ctx context.Context, _, _ string, _ ...agentcontainers.DevcontainerCLIOptions) (string, error) {
68+
func (f *fakeDevcontainerCLI) Up(ctx context.Context, _, _ string, _ ...agentcontainers.DevcontainerCLIUpOptions) (string, error) {
6969
if f.upErrC != nil {
7070
select {
7171
case <-ctx.Done():
@@ -79,7 +79,7 @@ func (f *fakeDevcontainerCLI) Up(ctx context.Context, _, _ string, _ ...agentcon
7979
return f.upID, f.upErr
8080
}
8181

82-
func (f *fakeDevcontainerCLI) Exec(ctx context.Context, _, _ string, _ string, _ []string, _ ...agentcontainers.DevcontainerCLIOptions) error {
82+
func (f *fakeDevcontainerCLI) Exec(ctx context.Context, _, _ string, _ string, _ []string, _ ...agentcontainers.DevcontainerCLIExecOptions) error {
8383
if f.execErrC != nil {
8484
select {
8585
case <-ctx.Done():

agent/agentcontainers/devcontainercli.go

Lines changed: 54 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -16,69 +16,84 @@ import (
1616

1717
// DevcontainerCLI is an interface for the devcontainer CLI.
1818
type DevcontainerCLI interface {
19-
Up(ctx context.Context, workspaceFolder, configPath string, opts ...DevcontainerCLIOptions) (id string, err error)
20-
Exec(ctx context.Context, workspaceFolder, configPath string, cmd string, cmdArgs []string, opts ...DevcontainerCLIOptions) error
19+
Up(ctx context.Context, workspaceFolder, configPath string, opts ...DevcontainerCLIUpOptions) (id string, err error)
20+
Exec(ctx context.Context, workspaceFolder, configPath string, cmd string, cmdArgs []string, opts ...DevcontainerCLIExecOptions) error
2121
}
2222

23-
// DevcontainerCLIOptions are options for the devcontainer CLI commands.
24-
type DevcontainerCLIOptions func(*devcontainerCLIUpConfig)
23+
// DevcontainerCLIUpOptions are options for the devcontainer CLI Up
24+
// command.
25+
type DevcontainerCLIUpOptions func(*devcontainerCLIUpConfig)
26+
27+
type devcontainerCLIUpConfig struct {
28+
args []string // Additional arguments for the Up command.
29+
stdout io.Writer
30+
stderr io.Writer
31+
}
2532

2633
// WithRemoveExistingContainer is an option to remove the existing
27-
// container. Can only be used with the Up command.
28-
func WithRemoveExistingContainer() DevcontainerCLIOptions {
34+
// container.
35+
func WithRemoveExistingContainer() DevcontainerCLIUpOptions {
2936
return func(o *devcontainerCLIUpConfig) {
30-
if o.command != "up" {
31-
panic("developer error: WithRemoveExistingContainer can only be used with the Up command")
32-
}
3337
o.args = append(o.args, "--remove-existing-container")
3438
}
3539
}
3640

37-
// WithOutput sets additional stdout and stderr writers for logs.
38-
func WithOutput(stdout, stderr io.Writer) DevcontainerCLIOptions {
41+
// WithUpOutput sets additional stdout and stderr writers for logs
42+
// during Up operations.
43+
func WithUpOutput(stdout, stderr io.Writer) DevcontainerCLIUpOptions {
3944
return func(o *devcontainerCLIUpConfig) {
4045
o.stdout = stdout
4146
o.stderr = stderr
4247
}
4348
}
4449

50+
// DevcontainerCLIExecOptions are options for the devcontainer CLI Exec
51+
// command.
52+
type DevcontainerCLIExecOptions func(*devcontainerCLIExecConfig)
53+
54+
type devcontainerCLIExecConfig struct {
55+
args []string // Additional arguments for the Exec command.
56+
stdout io.Writer
57+
stderr io.Writer
58+
}
59+
60+
// WithExecOutput sets additional stdout and stderr writers for logs
61+
// during Exec operations.
62+
func WithExecOutput(stdout, stderr io.Writer) DevcontainerCLIExecOptions {
63+
return func(o *devcontainerCLIExecConfig) {
64+
o.stdout = stdout
65+
o.stderr = stderr
66+
}
67+
}
68+
4569
// WithContainerID sets the container ID to target a specific container.
46-
// Can only be used with the Exec command.
47-
func WithContainerID(id string) DevcontainerCLIOptions {
48-
return func(o *devcontainerCLIUpConfig) {
49-
if o.command != "exec" {
50-
panic("developer error: WithContainerID can only be used with the Exec command")
51-
}
70+
func WithContainerID(id string) DevcontainerCLIExecOptions {
71+
return func(o *devcontainerCLIExecConfig) {
5272
o.args = append(o.args, "--container-id", id)
5373
}
5474
}
5575

5676
// WithRemoteEnv sets environment variables for the Exec command.
57-
// Can only be used with the Exec command.
58-
func WithRemoteEnv(env ...string) DevcontainerCLIOptions {
59-
return func(o *devcontainerCLIUpConfig) {
60-
if o.command != "exec" {
61-
panic("developer error: WithRemoteEnv can only be used with the Exec command")
62-
}
77+
func WithRemoteEnv(env ...string) DevcontainerCLIExecOptions {
78+
return func(o *devcontainerCLIExecConfig) {
6379
for _, e := range env {
6480
o.args = append(o.args, "--remote-env", e)
6581
}
6682
}
6783
}
6884

69-
type devcontainerCLIUpConfig struct {
70-
command string // The devcontainer CLI command to run, e.g. "up", "exec".
71-
removeExistingContainer bool
72-
args []string // Additional arguments for the command.
73-
stdout io.Writer
74-
stderr io.Writer
85+
func applyDevcontainerCLIUpOptions(opts []DevcontainerCLIUpOptions) devcontainerCLIUpConfig {
86+
conf := devcontainerCLIUpConfig{}
87+
for _, opt := range opts {
88+
if opt != nil {
89+
opt(&conf)
90+
}
91+
}
92+
return conf
7593
}
7694

77-
func applyDevcontainerCLIOptions(command string, opts []DevcontainerCLIOptions) devcontainerCLIUpConfig {
78-
conf := devcontainerCLIUpConfig{
79-
command: command,
80-
removeExistingContainer: false,
81-
}
95+
func applyDevcontainerCLIExecOptions(opts []DevcontainerCLIExecOptions) devcontainerCLIExecConfig {
96+
conf := devcontainerCLIExecConfig{}
8297
for _, opt := range opts {
8398
if opt != nil {
8499
opt(&conf)
@@ -101,9 +116,9 @@ func NewDevcontainerCLI(logger slog.Logger, execer agentexec.Execer) Devcontaine
101116
}
102117
}
103118

104-
func (d *devcontainerCLI) Up(ctx context.Context, workspaceFolder, configPath string, opts ...DevcontainerCLIOptions) (string, error) {
105-
conf := applyDevcontainerCLIOptions("up", opts)
106-
logger := d.logger.With(slog.F("workspace_folder", workspaceFolder), slog.F("config_path", configPath), slog.F("recreate", conf.removeExistingContainer))
119+
func (d *devcontainerCLI) Up(ctx context.Context, workspaceFolder, configPath string, opts ...DevcontainerCLIUpOptions) (string, error) {
120+
conf := applyDevcontainerCLIUpOptions(opts)
121+
logger := d.logger.With(slog.F("workspace_folder", workspaceFolder), slog.F("config_path", configPath))
107122

108123
args := []string{
109124
"up",
@@ -145,8 +160,8 @@ func (d *devcontainerCLI) Up(ctx context.Context, workspaceFolder, configPath st
145160
return result.ContainerID, nil
146161
}
147162

148-
func (d *devcontainerCLI) Exec(ctx context.Context, workspaceFolder, configPath string, cmd string, cmdArgs []string, opts ...DevcontainerCLIOptions) error {
149-
conf := applyDevcontainerCLIOptions("exec", opts)
163+
func (d *devcontainerCLI) Exec(ctx context.Context, workspaceFolder, configPath string, cmd string, cmdArgs []string, opts ...DevcontainerCLIExecOptions) error {
164+
conf := applyDevcontainerCLIExecOptions(opts)
150165
logger := d.logger.With(slog.F("workspace_folder", workspaceFolder), slog.F("config_path", configPath))
151166

152167
args := []string{"exec"}

agent/agentcontainers/devcontainercli_test.go

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ func TestDevcontainerCLI_ArgsAndParsing(t *testing.T) {
4242
logFile string
4343
workspace string
4444
config string
45-
opts []agentcontainers.DevcontainerCLIOptions
45+
opts []agentcontainers.DevcontainerCLIUpOptions
4646
wantArgs string
4747
wantError bool
4848
}{
@@ -93,7 +93,7 @@ func TestDevcontainerCLI_ArgsAndParsing(t *testing.T) {
9393
name: "with remove existing container",
9494
logFile: "up.log",
9595
workspace: "/test/workspace",
96-
opts: []agentcontainers.DevcontainerCLIOptions{
96+
opts: []agentcontainers.DevcontainerCLIUpOptions{
9797
agentcontainers.WithRemoveExistingContainer(),
9898
},
9999
wantArgs: "up --log-format json --workspace-folder /test/workspace --remove-existing-container",
@@ -136,7 +136,7 @@ func TestDevcontainerCLI_ArgsAndParsing(t *testing.T) {
136136
configPath string
137137
cmd string
138138
cmdArgs []string
139-
opts []agentcontainers.DevcontainerCLIOptions
139+
opts []agentcontainers.DevcontainerCLIExecOptions
140140
wantArgs string
141141
wantError bool
142142
}{
@@ -182,7 +182,7 @@ func TestDevcontainerCLI_ArgsAndParsing(t *testing.T) {
182182
configPath: "",
183183
cmd: "echo",
184184
cmdArgs: []string{"hello"},
185-
opts: []agentcontainers.DevcontainerCLIOptions{agentcontainers.WithContainerID("test-container-123")},
185+
opts: []agentcontainers.DevcontainerCLIExecOptions{agentcontainers.WithContainerID("test-container-123")},
186186
wantArgs: "exec --workspace-folder /test/workspace --container-id test-container-123 echo hello",
187187
wantError: false,
188188
},
@@ -192,7 +192,7 @@ func TestDevcontainerCLI_ArgsAndParsing(t *testing.T) {
192192
configPath: "/test/config.json",
193193
cmd: "bash",
194194
cmdArgs: []string{"-c", "ls -la"},
195-
opts: []agentcontainers.DevcontainerCLIOptions{agentcontainers.WithContainerID("my-container")},
195+
opts: []agentcontainers.DevcontainerCLIExecOptions{agentcontainers.WithContainerID("my-container")},
196196
wantArgs: "exec --workspace-folder /test/workspace --config /test/config.json --container-id my-container bash -c ls -la",
197197
wantError: false,
198198
},
@@ -202,7 +202,7 @@ func TestDevcontainerCLI_ArgsAndParsing(t *testing.T) {
202202
configPath: "",
203203
cmd: "cat",
204204
cmdArgs: []string{"/etc/hostname"},
205-
opts: []agentcontainers.DevcontainerCLIOptions{
205+
opts: []agentcontainers.DevcontainerCLIExecOptions{
206206
agentcontainers.WithContainerID("test-container-789"),
207207
},
208208
wantArgs: "exec --workspace-folder /test/workspace --container-id test-container-789 cat /etc/hostname",
@@ -235,7 +235,7 @@ func TestDevcontainerCLI_ArgsAndParsing(t *testing.T) {
235235
})
236236
}
237237

238-
// TestDevcontainerCLI_WithOutput tests that WithOutput captures CLI
238+
// TestDevcontainerCLI_WithOutput tests that WithUpOutput and WithExecOutput capture CLI
239239
// logs to provided writers.
240240
func TestDevcontainerCLI_WithOutput(t *testing.T) {
241241
t.Parallel()
@@ -262,9 +262,9 @@ func TestDevcontainerCLI_WithOutput(t *testing.T) {
262262
logger := slogtest.Make(t, &slogtest.Options{IgnoreErrors: true}).Leveled(slog.LevelDebug)
263263
dccli := agentcontainers.NewDevcontainerCLI(logger, testExecer)
264264

265-
// Call Up with WithOutput to capture CLI logs.
265+
// Call Up with WithUpOutput to capture CLI logs.
266266
ctx := testutil.Context(t, testutil.WaitMedium)
267-
containerID, err := dccli.Up(ctx, "/test/workspace", "", agentcontainers.WithOutput(outBuf, errBuf))
267+
containerID, err := dccli.Up(ctx, "/test/workspace", "", agentcontainers.WithUpOutput(outBuf, errBuf))
268268
require.NoError(t, err, "Up should succeed")
269269
require.NotEmpty(t, containerID, "expected non-empty container ID")
270270

@@ -303,11 +303,11 @@ func TestDevcontainerCLI_WithOutput(t *testing.T) {
303303
logger := slogtest.Make(t, &slogtest.Options{IgnoreErrors: true}).Leveled(slog.LevelDebug)
304304
dccli := agentcontainers.NewDevcontainerCLI(logger, testExecer)
305305

306-
// Call Exec with WithOutput and WithContainerID to capture any command output.
306+
// Call Exec with WithExecOutput and WithContainerID to capture any command output.
307307
ctx := testutil.Context(t, testutil.WaitMedium)
308308
err = dccli.Exec(ctx, "/test/workspace", "", "echo", []string{"hello"},
309309
agentcontainers.WithContainerID("test-container-456"),
310-
agentcontainers.WithOutput(outBuf, errBuf),
310+
agentcontainers.WithExecOutput(outBuf, errBuf),
311311
)
312312
require.NoError(t, err, "Exec should succeed")
313313

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy