Skip to content

chore(cli): rename build options to ephemeral parameters in cli #15030

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 18 commits into from
Oct 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions cli/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -370,8 +370,8 @@ type prepWorkspaceBuildArgs struct {
LastBuildParameters []codersdk.WorkspaceBuildParameter
SourceWorkspaceParameters []codersdk.WorkspaceBuildParameter

PromptBuildOptions bool
BuildOptions []codersdk.WorkspaceBuildParameter
PromptEphemeralParameters bool
EphemeralParameters []codersdk.WorkspaceBuildParameter

PromptRichParameters bool
RichParameters []codersdk.WorkspaceBuildParameter
Expand Down Expand Up @@ -405,8 +405,8 @@ func prepWorkspaceBuild(inv *serpent.Invocation, client *codersdk.Client, args p
resolver := new(ParameterResolver).
WithLastBuildParameters(args.LastBuildParameters).
WithSourceWorkspaceParameters(args.SourceWorkspaceParameters).
WithPromptBuildOptions(args.PromptBuildOptions).
WithBuildOptions(args.BuildOptions).
WithPromptEphemeralParameters(args.PromptEphemeralParameters).
WithEphemeralParameters(args.EphemeralParameters).
WithPromptRichParameters(args.PromptRichParameters).
WithRichParameters(args.RichParameters).
WithRichParametersFile(parameterFile).
Expand Down
29 changes: 23 additions & 6 deletions cli/parameter.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@ import (

// workspaceParameterFlags are used by commands processing rich parameters and/or build options.
type workspaceParameterFlags struct {
promptBuildOptions bool
buildOptions []string
promptEphemeralParameters bool

ephemeralParameters []string

richParameterFile string
richParameters []string
Expand All @@ -26,23 +27,39 @@ type workspaceParameterFlags struct {
}

func (wpf *workspaceParameterFlags) allOptions() []serpent.Option {
options := append(wpf.cliBuildOptions(), wpf.cliParameters()...)
options := append(wpf.cliEphemeralParameters(), wpf.cliParameters()...)
options = append(options, wpf.cliParameterDefaults()...)
return append(options, wpf.alwaysPrompt())
}

func (wpf *workspaceParameterFlags) cliBuildOptions() []serpent.Option {
func (wpf *workspaceParameterFlags) cliEphemeralParameters() []serpent.Option {
return serpent.OptionSet{
// Deprecated - replaced with ephemeral-parameter
{
Flag: "build-option",
Env: "CODER_BUILD_OPTION",
Description: `Build option value in the format "name=value".`,
Value: serpent.StringArrayOf(&wpf.buildOptions),
UseInstead: []serpent.Option{{Flag: "ephemeral-parameter"}},
Value: serpent.StringArrayOf(&wpf.ephemeralParameters),
},
// Deprecated - replaced with prompt-ephemeral-parameters
{
Flag: "build-options",
Description: "Prompt for one-time build options defined with ephemeral parameters.",
Value: serpent.BoolOf(&wpf.promptBuildOptions),
UseInstead: []serpent.Option{{Flag: "prompt-ephemeral-parameters"}},
Value: serpent.BoolOf(&wpf.promptEphemeralParameters),
},
{
Flag: "ephemeral-parameter",
Env: "CODER_EPHEMERAL_PARAMETER",
Description: `Set the value of ephemeral parameters defined in the template. The format is "name=value".`,
Value: serpent.StringArrayOf(&wpf.ephemeralParameters),
},
{
Flag: "prompt-ephemeral-parameters",
Env: "CODER_PROMPT_EPHEMERAL_PARAMETERS",
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.",
Value: serpent.BoolOf(&wpf.promptEphemeralParameters),
},
}
}
Expand Down
32 changes: 16 additions & 16 deletions cli/parameterresolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,10 @@ type ParameterResolver struct {
richParameters []codersdk.WorkspaceBuildParameter
richParametersDefaults map[string]string
richParametersFile map[string]string
buildOptions []codersdk.WorkspaceBuildParameter
ephemeralParameters []codersdk.WorkspaceBuildParameter

promptRichParameters bool
promptBuildOptions bool
promptRichParameters bool
promptEphemeralParameters bool
}

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

func (pr *ParameterResolver) WithBuildOptions(params []codersdk.WorkspaceBuildParameter) *ParameterResolver {
pr.buildOptions = params
func (pr *ParameterResolver) WithEphemeralParameters(params []codersdk.WorkspaceBuildParameter) *ParameterResolver {
pr.ephemeralParameters = params
return pr
}

Expand All @@ -75,8 +75,8 @@ func (pr *ParameterResolver) WithPromptRichParameters(promptRichParameters bool)
return pr
}

func (pr *ParameterResolver) WithPromptBuildOptions(promptBuildOptions bool) *ParameterResolver {
pr.promptBuildOptions = promptBuildOptions
func (pr *ParameterResolver) WithPromptEphemeralParameters(promptEphemeralParameters bool) *ParameterResolver {
pr.promptEphemeralParameters = promptEphemeralParameters
return pr
}

Expand Down Expand Up @@ -128,16 +128,16 @@ nextRichParameter:
resolved = append(resolved, richParameter)
}

nextBuildOption:
for _, buildOption := range pr.buildOptions {
nextEphemeralParameter:
for _, ephemeralParameter := range pr.ephemeralParameters {
for i, r := range resolved {
if r.Name == buildOption.Name {
resolved[i].Value = buildOption.Value
continue nextBuildOption
if r.Name == ephemeralParameter.Name {
resolved[i].Value = ephemeralParameter.Value
continue nextEphemeralParameter
}
}

resolved = append(resolved, buildOption)
resolved = append(resolved, ephemeralParameter)
}
return resolved
}
Expand Down Expand Up @@ -209,8 +209,8 @@ func (pr *ParameterResolver) verifyConstraints(resolved []codersdk.WorkspaceBuil
return templateVersionParametersNotFound(r.Name, templateVersionParameters)
}

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

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

if (tvp.Ephemeral && pr.promptBuildOptions) ||
if (tvp.Ephemeral && pr.promptEphemeralParameters) ||
(action == WorkspaceCreate && tvp.Required) ||
(action == WorkspaceCreate && !tvp.Ephemeral) ||
(action == WorkspaceUpdate && promptParameterOption) ||
Expand Down
112 changes: 110 additions & 2 deletions cli/restart_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,115 @@ func TestRestart(t *testing.T) {
require.NoError(t, err, "execute failed")
})

t.Run("BuildOptions", func(t *testing.T) {
t.Run("PromptEphemeralParameters", func(t *testing.T) {
t.Parallel()

client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
owner := coderdtest.CreateFirstUser(t, client)
member, memberUser := coderdtest.CreateAnotherUser(t, client, owner.OrganizationID)
version := coderdtest.CreateTemplateVersion(t, client, owner.OrganizationID, echoResponses)
coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID)
template := coderdtest.CreateTemplate(t, client, owner.OrganizationID, version.ID)
workspace := coderdtest.CreateWorkspace(t, member, template.ID)
coderdtest.AwaitWorkspaceBuildJobCompleted(t, client, workspace.LatestBuild.ID)

inv, root := clitest.New(t, "restart", workspace.Name, "--prompt-ephemeral-parameters")
clitest.SetupConfig(t, member, root)
doneChan := make(chan struct{})
pty := ptytest.New(t).Attach(inv)
go func() {
defer close(doneChan)
err := inv.Run()
assert.NoError(t, err)
}()

matches := []string{
ephemeralParameterDescription, ephemeralParameterValue,
"Restart workspace?", "yes",
"Stopping workspace", "",
"Starting workspace", "",
"workspace has been restarted", "",
}
for i := 0; i < len(matches); i += 2 {
match := matches[i]
value := matches[i+1]
pty.ExpectMatch(match)

if value != "" {
pty.WriteLine(value)
}
}
<-doneChan

// Verify if build option is set
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitShort)
defer cancel()

workspace, err := client.WorkspaceByOwnerAndName(ctx, memberUser.ID.String(), workspace.Name, codersdk.WorkspaceOptions{})
require.NoError(t, err)
actualParameters, err := client.WorkspaceBuildParameters(ctx, workspace.LatestBuild.ID)
require.NoError(t, err)
require.Contains(t, actualParameters, codersdk.WorkspaceBuildParameter{
Name: ephemeralParameterName,
Value: ephemeralParameterValue,
})
})

t.Run("EphemeralParameterFlags", func(t *testing.T) {
t.Parallel()

client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
owner := coderdtest.CreateFirstUser(t, client)
member, memberUser := coderdtest.CreateAnotherUser(t, client, owner.OrganizationID)
version := coderdtest.CreateTemplateVersion(t, client, owner.OrganizationID, echoResponses)
coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID)
template := coderdtest.CreateTemplate(t, client, owner.OrganizationID, version.ID)
workspace := coderdtest.CreateWorkspace(t, member, template.ID)
coderdtest.AwaitWorkspaceBuildJobCompleted(t, client, workspace.LatestBuild.ID)

inv, root := clitest.New(t, "restart", workspace.Name,
"--ephemeral-parameter", fmt.Sprintf("%s=%s", ephemeralParameterName, ephemeralParameterValue))
clitest.SetupConfig(t, member, root)
doneChan := make(chan struct{})
pty := ptytest.New(t).Attach(inv)
go func() {
defer close(doneChan)
err := inv.Run()
assert.NoError(t, err)
}()

matches := []string{
"Restart workspace?", "yes",
"Stopping workspace", "",
"Starting workspace", "",
"workspace has been restarted", "",
}
for i := 0; i < len(matches); i += 2 {
match := matches[i]
value := matches[i+1]
pty.ExpectMatch(match)

if value != "" {
pty.WriteLine(value)
}
}
<-doneChan

// Verify if build option is set
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitShort)
defer cancel()

workspace, err := client.WorkspaceByOwnerAndName(ctx, memberUser.ID.String(), workspace.Name, codersdk.WorkspaceOptions{})
require.NoError(t, err)
actualParameters, err := client.WorkspaceBuildParameters(ctx, workspace.LatestBuild.ID)
require.NoError(t, err)
require.Contains(t, actualParameters, codersdk.WorkspaceBuildParameter{
Name: ephemeralParameterName,
Value: ephemeralParameterValue,
})
})

t.Run("with deprecated build-options flag", func(t *testing.T) {
t.Parallel()

client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
Expand Down Expand Up @@ -114,7 +222,7 @@ func TestRestart(t *testing.T) {
})
})

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

client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
Expand Down
14 changes: 7 additions & 7 deletions cli/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ func buildWorkspaceStartRequest(inv *serpent.Invocation, client *codersdk.Client
return codersdk.CreateWorkspaceBuildRequest{}, err
}

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

PromptBuildOptions: parameterFlags.promptBuildOptions,
BuildOptions: buildOptions,
PromptRichParameters: parameterFlags.promptRichParameters,
RichParameters: cliRichParameters,
RichParameterFile: parameterFlags.richParameterFile,
RichParameterDefaults: cliRichParameterDefaults,
PromptEphemeralParameters: parameterFlags.promptEphemeralParameters,
EphemeralParameters: ephemeralParameters,
PromptRichParameters: parameterFlags.promptRichParameters,
RichParameters: cliRichParameters,
RichParameterFile: parameterFlags.richParameterFile,
RichParameterDefaults: cliRichParameterDefaults,
})
if err != nil {
return codersdk.CreateWorkspaceBuildRequest{}, err
Expand Down
10 changes: 5 additions & 5 deletions cli/start_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ func TestStart(t *testing.T) {
workspaceBuild := coderdtest.CreateWorkspaceBuild(t, client, workspace, database.WorkspaceTransitionStop)
coderdtest.AwaitWorkspaceBuildJobCompleted(t, client, workspaceBuild.ID)

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

// Verify if build option is set
// Verify if ephemeral parameter is set
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitShort)
defer cancel()

Expand All @@ -154,7 +154,7 @@ func TestStart(t *testing.T) {
})
})

t.Run("BuildOptionFlags", func(t *testing.T) {
t.Run("EphemeralParameterFlags", func(t *testing.T) {
t.Parallel()

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

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

// Verify if build option is set
// Verify if ephemeral parameter is set
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitShort)
defer cancel()

Expand Down
11 changes: 11 additions & 0 deletions cli/testdata/coder_restart_--help.golden
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,27 @@ OPTIONS:

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

--build-options bool
Prompt for one-time build options defined with ephemeral parameters.
DEPRECATED: Use --prompt-ephemeral-parameters instead.

--ephemeral-parameter string-array, $CODER_EPHEMERAL_PARAMETER
Set the value of ephemeral parameters defined in the template. The
format is "name=value".

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

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

--prompt-ephemeral-parameters bool, $CODER_PROMPT_EPHEMERAL_PARAMETERS
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.

--rich-parameter-file string, $CODER_RICH_PARAMETER_FILE
Specify a file path with values for rich parameters defined in the
template. The file should be in YAML format, containing key-value
Expand Down
Loading
Loading