Skip to content

Commit 02f6203

Browse files
defelmnqmafredriEdwardAngertdefelmnq
authored
chore(cli): rename build options to ephemeral parameters in cli (coder#15030)
This PR aims to rename `build-option` to `ephemeral-parameters` based on coder#10488 conversation. `build-option` has been renamed `ephemeral-parameter` and can be used to define a value for an ephemeral parameter in the template. `build-options` has been renamed `prompt-ephemeral-parameters` and can be used to prompt the user to put values for the ephemeral parameters in the template. --------- Co-authored-by: Mathias Fredriksson <mafredri@gmail.com> Co-authored-by: EdwardAngert <17991901+EdwardAngert@users.noreply.github.com> Co-authored-by: defelmnq <yvincent@coder.com>
1 parent 512cbf1 commit 02f6203

16 files changed

+270
-58
lines changed

cli/create.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -370,8 +370,8 @@ type prepWorkspaceBuildArgs struct {
370370
LastBuildParameters []codersdk.WorkspaceBuildParameter
371371
SourceWorkspaceParameters []codersdk.WorkspaceBuildParameter
372372

373-
PromptBuildOptions bool
374-
BuildOptions []codersdk.WorkspaceBuildParameter
373+
PromptEphemeralParameters bool
374+
EphemeralParameters []codersdk.WorkspaceBuildParameter
375375

376376
PromptRichParameters bool
377377
RichParameters []codersdk.WorkspaceBuildParameter
@@ -405,8 +405,8 @@ func prepWorkspaceBuild(inv *serpent.Invocation, client *codersdk.Client, args p
405405
resolver := new(ParameterResolver).
406406
WithLastBuildParameters(args.LastBuildParameters).
407407
WithSourceWorkspaceParameters(args.SourceWorkspaceParameters).
408-
WithPromptBuildOptions(args.PromptBuildOptions).
409-
WithBuildOptions(args.BuildOptions).
408+
WithPromptEphemeralParameters(args.PromptEphemeralParameters).
409+
WithEphemeralParameters(args.EphemeralParameters).
410410
WithPromptRichParameters(args.PromptRichParameters).
411411
WithRichParameters(args.RichParameters).
412412
WithRichParametersFile(parameterFile).

cli/parameter.go

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,9 @@ import (
1515

1616
// workspaceParameterFlags are used by commands processing rich parameters and/or build options.
1717
type workspaceParameterFlags struct {
18-
promptBuildOptions bool
19-
buildOptions []string
18+
promptEphemeralParameters bool
19+
20+
ephemeralParameters []string
2021

2122
richParameterFile string
2223
richParameters []string
@@ -26,23 +27,39 @@ type workspaceParameterFlags struct {
2627
}
2728

2829
func (wpf *workspaceParameterFlags) allOptions() []serpent.Option {
29-
options := append(wpf.cliBuildOptions(), wpf.cliParameters()...)
30+
options := append(wpf.cliEphemeralParameters(), wpf.cliParameters()...)
3031
options = append(options, wpf.cliParameterDefaults()...)
3132
return append(options, wpf.alwaysPrompt())
3233
}
3334

34-
func (wpf *workspaceParameterFlags) cliBuildOptions() []serpent.Option {
35+
func (wpf *workspaceParameterFlags) cliEphemeralParameters() []serpent.Option {
3536
return serpent.OptionSet{
37+
// Deprecated - replaced with ephemeral-parameter
3638
{
3739
Flag: "build-option",
3840
Env: "CODER_BUILD_OPTION",
3941
Description: `Build option value in the format "name=value".`,
40-
Value: serpent.StringArrayOf(&wpf.buildOptions),
42+
UseInstead: []serpent.Option{{Flag: "ephemeral-parameter"}},
43+
Value: serpent.StringArrayOf(&wpf.ephemeralParameters),
4144
},
45+
// Deprecated - replaced with prompt-ephemeral-parameters
4246
{
4347
Flag: "build-options",
4448
Description: "Prompt for one-time build options defined with ephemeral parameters.",
45-
Value: serpent.BoolOf(&wpf.promptBuildOptions),
49+
UseInstead: []serpent.Option{{Flag: "prompt-ephemeral-parameters"}},
50+
Value: serpent.BoolOf(&wpf.promptEphemeralParameters),
51+
},
52+
{
53+
Flag: "ephemeral-parameter",
54+
Env: "CODER_EPHEMERAL_PARAMETER",
55+
Description: `Set the value of ephemeral parameters defined in the template. The format is "name=value".`,
56+
Value: serpent.StringArrayOf(&wpf.ephemeralParameters),
57+
},
58+
{
59+
Flag: "prompt-ephemeral-parameters",
60+
Env: "CODER_PROMPT_EPHEMERAL_PARAMETERS",
61+
Description: "Prompt to set values of ephemeral parameters defined in the template. If a value has been set via --ephemeral-parameter, it will not be prompted for.",
62+
Value: serpent.BoolOf(&wpf.promptEphemeralParameters),
4663
},
4764
}
4865
}

cli/parameterresolver.go

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,10 @@ type ParameterResolver struct {
2929
richParameters []codersdk.WorkspaceBuildParameter
3030
richParametersDefaults map[string]string
3131
richParametersFile map[string]string
32-
buildOptions []codersdk.WorkspaceBuildParameter
32+
ephemeralParameters []codersdk.WorkspaceBuildParameter
3333

34-
promptRichParameters bool
35-
promptBuildOptions bool
34+
promptRichParameters bool
35+
promptEphemeralParameters bool
3636
}
3737

3838
func (pr *ParameterResolver) WithLastBuildParameters(params []codersdk.WorkspaceBuildParameter) *ParameterResolver {
@@ -50,8 +50,8 @@ func (pr *ParameterResolver) WithRichParameters(params []codersdk.WorkspaceBuild
5050
return pr
5151
}
5252

53-
func (pr *ParameterResolver) WithBuildOptions(params []codersdk.WorkspaceBuildParameter) *ParameterResolver {
54-
pr.buildOptions = params
53+
func (pr *ParameterResolver) WithEphemeralParameters(params []codersdk.WorkspaceBuildParameter) *ParameterResolver {
54+
pr.ephemeralParameters = params
5555
return pr
5656
}
5757

@@ -75,8 +75,8 @@ func (pr *ParameterResolver) WithPromptRichParameters(promptRichParameters bool)
7575
return pr
7676
}
7777

78-
func (pr *ParameterResolver) WithPromptBuildOptions(promptBuildOptions bool) *ParameterResolver {
79-
pr.promptBuildOptions = promptBuildOptions
78+
func (pr *ParameterResolver) WithPromptEphemeralParameters(promptEphemeralParameters bool) *ParameterResolver {
79+
pr.promptEphemeralParameters = promptEphemeralParameters
8080
return pr
8181
}
8282

@@ -128,16 +128,16 @@ nextRichParameter:
128128
resolved = append(resolved, richParameter)
129129
}
130130

131-
nextBuildOption:
132-
for _, buildOption := range pr.buildOptions {
131+
nextEphemeralParameter:
132+
for _, ephemeralParameter := range pr.ephemeralParameters {
133133
for i, r := range resolved {
134-
if r.Name == buildOption.Name {
135-
resolved[i].Value = buildOption.Value
136-
continue nextBuildOption
134+
if r.Name == ephemeralParameter.Name {
135+
resolved[i].Value = ephemeralParameter.Value
136+
continue nextEphemeralParameter
137137
}
138138
}
139139

140-
resolved = append(resolved, buildOption)
140+
resolved = append(resolved, ephemeralParameter)
141141
}
142142
return resolved
143143
}
@@ -209,8 +209,8 @@ func (pr *ParameterResolver) verifyConstraints(resolved []codersdk.WorkspaceBuil
209209
return templateVersionParametersNotFound(r.Name, templateVersionParameters)
210210
}
211211

212-
if tvp.Ephemeral && !pr.promptBuildOptions && findWorkspaceBuildParameter(tvp.Name, pr.buildOptions) == nil {
213-
return xerrors.Errorf("ephemeral parameter %q can be used only with --build-options or --build-option flag", r.Name)
212+
if tvp.Ephemeral && !pr.promptEphemeralParameters && findWorkspaceBuildParameter(tvp.Name, pr.ephemeralParameters) == nil {
213+
return xerrors.Errorf("ephemeral parameter %q can be used only with --prompt-ephemeral-parameters or --ephemeral-parameter flag", r.Name)
214214
}
215215

216216
if !tvp.Mutable && action != WorkspaceCreate {
@@ -231,7 +231,7 @@ func (pr *ParameterResolver) resolveWithInput(resolved []codersdk.WorkspaceBuild
231231
firstTimeUse := pr.isFirstTimeUse(tvp.Name)
232232
promptParameterOption := pr.isLastBuildParameterInvalidOption(tvp)
233233

234-
if (tvp.Ephemeral && pr.promptBuildOptions) ||
234+
if (tvp.Ephemeral && pr.promptEphemeralParameters) ||
235235
(action == WorkspaceCreate && tvp.Required) ||
236236
(action == WorkspaceCreate && !tvp.Ephemeral) ||
237237
(action == WorkspaceUpdate && promptParameterOption) ||

cli/restart_test.go

Lines changed: 110 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,115 @@ func TestRestart(t *testing.T) {
6060
require.NoError(t, err, "execute failed")
6161
})
6262

63-
t.Run("BuildOptions", func(t *testing.T) {
63+
t.Run("PromptEphemeralParameters", func(t *testing.T) {
64+
t.Parallel()
65+
66+
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
67+
owner := coderdtest.CreateFirstUser(t, client)
68+
member, memberUser := coderdtest.CreateAnotherUser(t, client, owner.OrganizationID)
69+
version := coderdtest.CreateTemplateVersion(t, client, owner.OrganizationID, echoResponses)
70+
coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID)
71+
template := coderdtest.CreateTemplate(t, client, owner.OrganizationID, version.ID)
72+
workspace := coderdtest.CreateWorkspace(t, member, template.ID)
73+
coderdtest.AwaitWorkspaceBuildJobCompleted(t, client, workspace.LatestBuild.ID)
74+
75+
inv, root := clitest.New(t, "restart", workspace.Name, "--prompt-ephemeral-parameters")
76+
clitest.SetupConfig(t, member, root)
77+
doneChan := make(chan struct{})
78+
pty := ptytest.New(t).Attach(inv)
79+
go func() {
80+
defer close(doneChan)
81+
err := inv.Run()
82+
assert.NoError(t, err)
83+
}()
84+
85+
matches := []string{
86+
ephemeralParameterDescription, ephemeralParameterValue,
87+
"Restart workspace?", "yes",
88+
"Stopping workspace", "",
89+
"Starting workspace", "",
90+
"workspace has been restarted", "",
91+
}
92+
for i := 0; i < len(matches); i += 2 {
93+
match := matches[i]
94+
value := matches[i+1]
95+
pty.ExpectMatch(match)
96+
97+
if value != "" {
98+
pty.WriteLine(value)
99+
}
100+
}
101+
<-doneChan
102+
103+
// Verify if build option is set
104+
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitShort)
105+
defer cancel()
106+
107+
workspace, err := client.WorkspaceByOwnerAndName(ctx, memberUser.ID.String(), workspace.Name, codersdk.WorkspaceOptions{})
108+
require.NoError(t, err)
109+
actualParameters, err := client.WorkspaceBuildParameters(ctx, workspace.LatestBuild.ID)
110+
require.NoError(t, err)
111+
require.Contains(t, actualParameters, codersdk.WorkspaceBuildParameter{
112+
Name: ephemeralParameterName,
113+
Value: ephemeralParameterValue,
114+
})
115+
})
116+
117+
t.Run("EphemeralParameterFlags", func(t *testing.T) {
118+
t.Parallel()
119+
120+
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
121+
owner := coderdtest.CreateFirstUser(t, client)
122+
member, memberUser := coderdtest.CreateAnotherUser(t, client, owner.OrganizationID)
123+
version := coderdtest.CreateTemplateVersion(t, client, owner.OrganizationID, echoResponses)
124+
coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID)
125+
template := coderdtest.CreateTemplate(t, client, owner.OrganizationID, version.ID)
126+
workspace := coderdtest.CreateWorkspace(t, member, template.ID)
127+
coderdtest.AwaitWorkspaceBuildJobCompleted(t, client, workspace.LatestBuild.ID)
128+
129+
inv, root := clitest.New(t, "restart", workspace.Name,
130+
"--ephemeral-parameter", fmt.Sprintf("%s=%s", ephemeralParameterName, ephemeralParameterValue))
131+
clitest.SetupConfig(t, member, root)
132+
doneChan := make(chan struct{})
133+
pty := ptytest.New(t).Attach(inv)
134+
go func() {
135+
defer close(doneChan)
136+
err := inv.Run()
137+
assert.NoError(t, err)
138+
}()
139+
140+
matches := []string{
141+
"Restart workspace?", "yes",
142+
"Stopping workspace", "",
143+
"Starting workspace", "",
144+
"workspace has been restarted", "",
145+
}
146+
for i := 0; i < len(matches); i += 2 {
147+
match := matches[i]
148+
value := matches[i+1]
149+
pty.ExpectMatch(match)
150+
151+
if value != "" {
152+
pty.WriteLine(value)
153+
}
154+
}
155+
<-doneChan
156+
157+
// Verify if build option is set
158+
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitShort)
159+
defer cancel()
160+
161+
workspace, err := client.WorkspaceByOwnerAndName(ctx, memberUser.ID.String(), workspace.Name, codersdk.WorkspaceOptions{})
162+
require.NoError(t, err)
163+
actualParameters, err := client.WorkspaceBuildParameters(ctx, workspace.LatestBuild.ID)
164+
require.NoError(t, err)
165+
require.Contains(t, actualParameters, codersdk.WorkspaceBuildParameter{
166+
Name: ephemeralParameterName,
167+
Value: ephemeralParameterValue,
168+
})
169+
})
170+
171+
t.Run("with deprecated build-options flag", func(t *testing.T) {
64172
t.Parallel()
65173

66174
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
@@ -114,7 +222,7 @@ func TestRestart(t *testing.T) {
114222
})
115223
})
116224

117-
t.Run("BuildOptionFlags", func(t *testing.T) {
225+
t.Run("with deprecated build-option flag", func(t *testing.T) {
118226
t.Parallel()
119227

120228
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})

cli/start.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ func buildWorkspaceStartRequest(inv *serpent.Invocation, client *codersdk.Client
9696
return codersdk.CreateWorkspaceBuildRequest{}, err
9797
}
9898

99-
buildOptions, err := asWorkspaceBuildParameters(parameterFlags.buildOptions)
99+
ephemeralParameters, err := asWorkspaceBuildParameters(parameterFlags.ephemeralParameters)
100100
if err != nil {
101101
return codersdk.CreateWorkspaceBuildRequest{}, xerrors.Errorf("unable to parse build options: %w", err)
102102
}
@@ -117,12 +117,12 @@ func buildWorkspaceStartRequest(inv *serpent.Invocation, client *codersdk.Client
117117
NewWorkspaceName: workspace.Name,
118118
LastBuildParameters: lastBuildParameters,
119119

120-
PromptBuildOptions: parameterFlags.promptBuildOptions,
121-
BuildOptions: buildOptions,
122-
PromptRichParameters: parameterFlags.promptRichParameters,
123-
RichParameters: cliRichParameters,
124-
RichParameterFile: parameterFlags.richParameterFile,
125-
RichParameterDefaults: cliRichParameterDefaults,
120+
PromptEphemeralParameters: parameterFlags.promptEphemeralParameters,
121+
EphemeralParameters: ephemeralParameters,
122+
PromptRichParameters: parameterFlags.promptRichParameters,
123+
RichParameters: cliRichParameters,
124+
RichParameterFile: parameterFlags.richParameterFile,
125+
RichParameterDefaults: cliRichParameterDefaults,
126126
})
127127
if err != nil {
128128
return codersdk.CreateWorkspaceBuildRequest{}, err

cli/start_test.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ func TestStart(t *testing.T) {
115115
workspaceBuild := coderdtest.CreateWorkspaceBuild(t, client, workspace, database.WorkspaceTransitionStop)
116116
coderdtest.AwaitWorkspaceBuildJobCompleted(t, client, workspaceBuild.ID)
117117

118-
inv, root := clitest.New(t, "start", workspace.Name, "--build-options")
118+
inv, root := clitest.New(t, "start", workspace.Name, "--prompt-ephemeral-parameters")
119119
clitest.SetupConfig(t, member, root)
120120
doneChan := make(chan struct{})
121121
pty := ptytest.New(t).Attach(inv)
@@ -140,7 +140,7 @@ func TestStart(t *testing.T) {
140140
}
141141
<-doneChan
142142

143-
// Verify if build option is set
143+
// Verify if ephemeral parameter is set
144144
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitShort)
145145
defer cancel()
146146

@@ -154,7 +154,7 @@ func TestStart(t *testing.T) {
154154
})
155155
})
156156

157-
t.Run("BuildOptionFlags", func(t *testing.T) {
157+
t.Run("EphemeralParameterFlags", func(t *testing.T) {
158158
t.Parallel()
159159

160160
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
@@ -170,7 +170,7 @@ func TestStart(t *testing.T) {
170170
coderdtest.AwaitWorkspaceBuildJobCompleted(t, client, workspaceBuild.ID)
171171

172172
inv, root := clitest.New(t, "start", workspace.Name,
173-
"--build-option", fmt.Sprintf("%s=%s", ephemeralParameterName, ephemeralParameterValue))
173+
"--ephemeral-parameter", fmt.Sprintf("%s=%s", ephemeralParameterName, ephemeralParameterValue))
174174
clitest.SetupConfig(t, member, root)
175175
doneChan := make(chan struct{})
176176
pty := ptytest.New(t).Attach(inv)
@@ -183,7 +183,7 @@ func TestStart(t *testing.T) {
183183
pty.ExpectMatch("workspace has been started")
184184
<-doneChan
185185

186-
// Verify if build option is set
186+
// Verify if ephemeral parameter is set
187187
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitShort)
188188
defer cancel()
189189

cli/testdata/coder_restart_--help.golden

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,27 @@ OPTIONS:
1212

1313
--build-option string-array, $CODER_BUILD_OPTION
1414
Build option value in the format "name=value".
15+
DEPRECATED: Use --ephemeral-parameter instead.
1516

1617
--build-options bool
1718
Prompt for one-time build options defined with ephemeral parameters.
19+
DEPRECATED: Use --prompt-ephemeral-parameters instead.
20+
21+
--ephemeral-parameter string-array, $CODER_EPHEMERAL_PARAMETER
22+
Set the value of ephemeral parameters defined in the template. The
23+
format is "name=value".
1824

1925
--parameter string-array, $CODER_RICH_PARAMETER
2026
Rich parameter value in the format "name=value".
2127

2228
--parameter-default string-array, $CODER_RICH_PARAMETER_DEFAULT
2329
Rich parameter default values in the format "name=value".
2430

31+
--prompt-ephemeral-parameters bool, $CODER_PROMPT_EPHEMERAL_PARAMETERS
32+
Prompt to set values of ephemeral parameters defined in the template.
33+
If a value has been set via --ephemeral-parameter, it will not be
34+
prompted for.
35+
2536
--rich-parameter-file string, $CODER_RICH_PARAMETER_FILE
2637
Specify a file path with values for rich parameters defined in the
2738
template. The file should be in YAML format, containing key-value

0 commit comments

Comments
 (0)