@@ -18,11 +18,12 @@ import (
18
18
19
19
func (r * RootCmd ) create () * clibase.Cmd {
20
20
var (
21
- richParameterFile string
22
- templateName string
23
- startAt string
24
- stopAfter time.Duration
25
- workspaceName string
21
+ templateName string
22
+ startAt string
23
+ stopAfter time.Duration
24
+ workspaceName string
25
+
26
+ parameterFlags workspaceParameterFlags
26
27
)
27
28
client := new (codersdk.Client )
28
29
cmd := & clibase.Cmd {
@@ -129,10 +130,18 @@ func (r *RootCmd) create() *clibase.Cmd {
129
130
schedSpec = ptr .Ref (sched .String ())
130
131
}
131
132
132
- buildParams , err := prepWorkspaceBuild (inv , client , prepWorkspaceBuildArgs {
133
- Template : template ,
134
- RichParameterFile : richParameterFile ,
135
- NewWorkspaceName : workspaceName ,
133
+ cliRichParameters , err := asWorkspaceBuildParameters (parameterFlags .richParameters )
134
+ if err != nil {
135
+ return xerrors .Errorf ("can't parse given parameter values: %w" , err )
136
+ }
137
+
138
+ richParameters , err := prepWorkspaceBuild (inv , client , prepWorkspaceBuildArgs {
139
+ Action : WorkspaceCreate ,
140
+ Template : template ,
141
+ NewWorkspaceName : workspaceName ,
142
+
143
+ RichParameterFile : parameterFlags .richParameterFile ,
144
+ RichParameters : cliRichParameters ,
136
145
})
137
146
if err != nil {
138
147
return xerrors .Errorf ("prepare build: %w" , err )
@@ -156,7 +165,7 @@ func (r *RootCmd) create() *clibase.Cmd {
156
165
Name : workspaceName ,
157
166
AutostartSchedule : schedSpec ,
158
167
TTLMillis : ttlMillis ,
159
- RichParameterValues : buildParams . richParameters ,
168
+ RichParameterValues : richParameters ,
160
169
})
161
170
if err != nil {
162
171
return xerrors .Errorf ("create workspace: %w" , err )
@@ -179,12 +188,6 @@ func (r *RootCmd) create() *clibase.Cmd {
179
188
Description : "Specify a template name." ,
180
189
Value : clibase .StringOf (& templateName ),
181
190
},
182
- clibase.Option {
183
- Flag : "rich-parameter-file" ,
184
- Env : "CODER_RICH_PARAMETER_FILE" ,
185
- Description : "Specify a file path with values for rich parameters defined in the template." ,
186
- Value : clibase .StringOf (& richParameterFile ),
187
- },
188
191
clibase.Option {
189
192
Flag : "start-at" ,
190
193
Env : "CODER_WORKSPACE_START_AT" ,
@@ -199,99 +202,59 @@ func (r *RootCmd) create() *clibase.Cmd {
199
202
},
200
203
cliui .SkipPromptOption (),
201
204
)
205
+ cmd .Options = append (cmd .Options , parameterFlags .cliParameters ()... )
202
206
return cmd
203
207
}
204
208
205
209
type prepWorkspaceBuildArgs struct {
206
- Template codersdk. Template
207
- ExistingRichParams [] codersdk.WorkspaceBuildParameter
208
- RichParameterFile string
209
- NewWorkspaceName string
210
-
211
- UpdateWorkspace bool
212
- BuildOptions bool
213
- WorkspaceID uuid. UUID
214
- }
210
+ Action WorkspaceCLIAction
211
+ Template codersdk.Template
212
+ NewWorkspaceName string
213
+ WorkspaceID uuid. UUID
214
+
215
+ LastBuildParameters []codersdk. WorkspaceBuildParameter
216
+
217
+ PromptBuildOptions bool
218
+ BuildOptions []codersdk. WorkspaceBuildParameter
215
219
216
- type buildParameters struct {
217
- // Rich parameters stores values for build parameters annotated with description, icon, type, etc.
218
- richParameters []codersdk. WorkspaceBuildParameter
220
+ PromptRichParameters bool
221
+ RichParameters []codersdk. WorkspaceBuildParameter
222
+ RichParameterFile string
219
223
}
220
224
221
225
// prepWorkspaceBuild will ensure a workspace build will succeed on the latest template version.
222
- // Any missing params will be prompted to the user. It supports legacy and rich parameters.
223
- func prepWorkspaceBuild (inv * clibase.Invocation , client * codersdk.Client , args prepWorkspaceBuildArgs ) (* buildParameters , error ) {
226
+ // Any missing params will be prompted to the user. It supports rich parameters.
227
+ func prepWorkspaceBuild (inv * clibase.Invocation , client * codersdk.Client , args prepWorkspaceBuildArgs ) ([]codersdk. WorkspaceBuildParameter , error ) {
224
228
ctx := inv .Context ()
225
229
226
230
templateVersion , err := client .TemplateVersion (ctx , args .Template .ActiveVersionID )
227
231
if err != nil {
228
- return nil , err
232
+ return nil , xerrors . Errorf ( "get template version: %w" , err )
229
233
}
230
234
231
- // Rich parameters
232
235
templateVersionParameters , err := client .TemplateVersionRichParameters (inv .Context (), templateVersion .ID )
233
236
if err != nil {
234
237
return nil , xerrors .Errorf ("get template version rich parameters: %w" , err )
235
238
}
236
239
237
- parameterMapFromFile := map [string ]string {}
238
- useParamFile := false
240
+ parameterFile := map [string ]string {}
239
241
if args .RichParameterFile != "" {
240
- useParamFile = true
241
- _ , _ = fmt .Fprintln (inv .Stdout , cliui .DefaultStyles .Paragraph .Render ("Attempting to read the variables from the rich parameter file." )+ "\r \n " )
242
- parameterMapFromFile , err = createParameterMapFromFile (args .RichParameterFile )
243
- if err != nil {
244
- return nil , err
245
- }
246
- }
247
- disclaimerPrinted := false
248
- richParameters := make ([]codersdk.WorkspaceBuildParameter , 0 )
249
- PromptRichParamLoop:
250
- for _ , templateVersionParameter := range templateVersionParameters {
251
- if ! args .BuildOptions && templateVersionParameter .Ephemeral {
252
- continue
253
- }
254
-
255
- if ! disclaimerPrinted {
256
- _ , _ = fmt .Fprintln (inv .Stdout , cliui .DefaultStyles .Paragraph .Render ("This template has customizable parameters. Values can be changed after create, but may have unintended side effects (like data loss)." )+ "\r \n " )
257
- disclaimerPrinted = true
258
- }
259
-
260
- // Param file is all or nothing
261
- if ! useParamFile && ! templateVersionParameter .Ephemeral {
262
- for _ , e := range args .ExistingRichParams {
263
- if e .Name == templateVersionParameter .Name {
264
- // If the param already exists, we do not need to prompt it again.
265
- // The workspace scope will reuse params for each build.
266
- continue PromptRichParamLoop
267
- }
268
- }
269
- }
270
-
271
- if args .UpdateWorkspace && ! templateVersionParameter .Mutable {
272
- // Check if the immutable parameter was used in the previous build. If so, then it isn't a fresh one
273
- // and the user should be warned.
274
- exists , err := workspaceBuildParameterExists (ctx , client , args .WorkspaceID , templateVersionParameter )
275
- if err != nil {
276
- return nil , err
277
- }
278
-
279
- if exists {
280
- _ , _ = fmt .Fprintln (inv .Stdout , cliui .DefaultStyles .Warn .Render (fmt .Sprintf (`Parameter %q is not mutable, so can't be customized after workspace creation.` , templateVersionParameter .Name )))
281
- continue
282
- }
283
- }
284
-
285
- parameterValue , err := getWorkspaceBuildParameterValueFromMapOrInput (inv , parameterMapFromFile , templateVersionParameter )
242
+ parameterFile , err = parseParameterMapFile (args .RichParameterFile )
286
243
if err != nil {
287
- return nil , err
244
+ return nil , xerrors . Errorf ( "can't parse parameter map file: %w" , err )
288
245
}
289
-
290
- richParameters = append (richParameters , * parameterValue )
291
246
}
292
247
293
- if disclaimerPrinted {
294
- _ , _ = fmt .Fprintln (inv .Stdout )
248
+ resolver := new (ParameterResolver ).
249
+ WithLastBuildParameters (args .LastBuildParameters ).
250
+ WithPromptBuildOptions (args .PromptBuildOptions ).
251
+ WithBuildOptions (args .BuildOptions ).
252
+ WithPromptRichParameters (args .PromptRichParameters ).
253
+ WithRichParameters (args .RichParameters ).
254
+ WithRichParametersFile (parameterFile )
255
+ buildParameters , err := resolver .Resolve (inv , args .Action , templateVersionParameters )
256
+ if err != nil {
257
+ return nil , err
295
258
}
296
259
297
260
err = cliui .GitAuth (ctx , inv .Stdout , cliui.GitAuthOptions {
@@ -306,7 +269,7 @@ PromptRichParamLoop:
306
269
// Run a dry-run with the given parameters to check correctness
307
270
dryRun , err := client .CreateTemplateVersionDryRun (inv .Context (), templateVersion .ID , codersdk.CreateTemplateVersionDryRunRequest {
308
271
WorkspaceName : args .NewWorkspaceName ,
309
- RichParameterValues : richParameters ,
272
+ RichParameterValues : buildParameters ,
310
273
})
311
274
if err != nil {
312
275
return nil , xerrors .Errorf ("begin workspace dry-run: %w" , err )
@@ -346,21 +309,5 @@ PromptRichParamLoop:
346
309
return nil , xerrors .Errorf ("get resources: %w" , err )
347
310
}
348
311
349
- return & buildParameters {
350
- richParameters : richParameters ,
351
- }, nil
352
- }
353
-
354
- func workspaceBuildParameterExists (ctx context.Context , client * codersdk.Client , workspaceID uuid.UUID , templateVersionParameter codersdk.TemplateVersionParameter ) (bool , error ) {
355
- lastBuildParameters , err := client .WorkspaceBuildParameters (ctx , workspaceID )
356
- if err != nil {
357
- return false , xerrors .Errorf ("can't fetch last workspace build parameters: %w" , err )
358
- }
359
-
360
- for _ , p := range lastBuildParameters {
361
- if p .Name == templateVersionParameter .Name {
362
- return true , nil
363
- }
364
- }
365
- return false , nil
312
+ return buildParameters , nil
366
313
}
0 commit comments