diff --git a/cli/create.go b/cli/create.go index 4e0e47b43eaa4..3f52e59e8ad90 100644 --- a/cli/create.go +++ b/cli/create.go @@ -472,7 +472,12 @@ func promptPresetSelection(inv *serpent.Invocation, presets []codersdk.Preset) ( var presetOptions []string for _, preset := range presets { - option := preset.Name + var option string + if preset.Description == "" { + option = preset.Name + } else { + option = fmt.Sprintf("%s: %s", preset.Name, preset.Description) + } presetOptions = append(presetOptions, option) presetMap[option] = &preset } diff --git a/cli/create_test.go b/cli/create_test.go index 9db2e328c6ce9..dd26e450d3916 100644 --- a/cli/create_test.go +++ b/cli/create_test.go @@ -882,7 +882,8 @@ func TestCreateWithPreset(t *testing.T) { // Given: a template and a template version with two presets preset := proto.Preset{ - Name: "preset-test", + Name: "preset-test", + Description: "Preset Test.", Parameters: []*proto.PresetParameter{ {Name: firstParameterName, Value: secondOptionalParameterValue}, {Name: thirdParameterName, Value: thirdParameterValue}, diff --git a/cli/templatepresets.go b/cli/templatepresets.go index ab0d49725b99a..240abec313a16 100644 --- a/cli/templatepresets.go +++ b/cli/templatepresets.go @@ -41,12 +41,13 @@ func (r *RootCmd) templatePresets() *serpent.Command { func (r *RootCmd) templatePresetsList() *serpent.Command { defaultColumns := []string{ "name", + "description", "parameters", "default", "desired prebuild instances", } formatter := cliui.NewOutputFormatter( - cliui.TableFormat([]templatePresetRow{}, defaultColumns), + cliui.TableFormat([]TemplatePresetRow{}, defaultColumns), cliui.JSONFormat(), ) client := new(codersdk.Client) @@ -108,10 +109,13 @@ func (r *RootCmd) templatePresetsList() *serpent.Command { return nil } - cliui.Infof( - inv.Stdout, - "Showing presets for template %q and template version %q.\n", template.Name, version.Name, - ) + // Only display info message for table output + if formatter.FormatID() == "table" { + cliui.Infof( + inv.Stdout, + "Showing presets for template %q and template version %q.\n", template.Name, version.Name, + ) + } rows := templatePresetsToRows(presets...) out, err := formatter.Format(inv.Context(), rows) if err != nil { @@ -128,12 +132,13 @@ func (r *RootCmd) templatePresetsList() *serpent.Command { return cmd } -type templatePresetRow struct { - // For json format: +type TemplatePresetRow struct { + // For json format TemplatePreset codersdk.Preset `table:"-"` // For table format: Name string `json:"-" table:"name,default_sort"` + Description string `json:"-" table:"description"` Parameters string `json:"-" table:"parameters"` Default bool `json:"-" table:"default"` DesiredPrebuildInstances string `json:"-" table:"desired prebuild instances"` @@ -149,15 +154,19 @@ func formatPresetParameters(params []codersdk.PresetParameter) string { // templatePresetsToRows converts a list of presets to a list of rows // for outputting. -func templatePresetsToRows(presets ...codersdk.Preset) []templatePresetRow { - rows := make([]templatePresetRow, len(presets)) +func templatePresetsToRows(presets ...codersdk.Preset) []TemplatePresetRow { + rows := make([]TemplatePresetRow, len(presets)) for i, preset := range presets { prebuildInstances := "-" if preset.DesiredPrebuildInstances != nil { prebuildInstances = strconv.Itoa(*preset.DesiredPrebuildInstances) } - rows[i] = templatePresetRow{ + rows[i] = TemplatePresetRow{ + // For json format + TemplatePreset: preset, + // For table format Name: preset.Name, + Description: preset.Description, Parameters: formatPresetParameters(preset.Parameters), Default: preset.Default, DesiredPrebuildInstances: prebuildInstances, diff --git a/cli/templatepresets_test.go b/cli/templatepresets_test.go index 47d34af2dcf2d..3a8c8c39f0211 100644 --- a/cli/templatepresets_test.go +++ b/cli/templatepresets_test.go @@ -1,11 +1,14 @@ package cli_test import ( + "bytes" + "encoding/json" "fmt" "testing" "github.com/stretchr/testify/require" + "github.com/coder/coder/v2/cli" "github.com/coder/coder/v2/cli/clitest" "github.com/coder/coder/v2/coderd/coderdtest" "github.com/coder/coder/v2/codersdk" @@ -84,8 +87,9 @@ func TestTemplatePresets(t *testing.T) { }, }, { - Name: "preset-prebuilds", - Parameters: []*proto.PresetParameter{}, + Name: "preset-prebuilds", + Description: "Preset without parameters and 2 prebuild instances.", + Parameters: []*proto.PresetParameter{}, Prebuild: &proto.Prebuild{ Instances: 2, }, @@ -117,7 +121,7 @@ func TestTemplatePresets(t *testing.T) { pty.ExpectRegexMatch(`preset-default\s+k1=v2\s+true\s+0`) // The parameter order is not guaranteed in the output, so we match both possible orders pty.ExpectRegexMatch(`preset-multiple-params\s+(k1=v1,k2=v2)|(k2=v2,k1=v1)\s+false\s+-`) - pty.ExpectRegexMatch(`preset-prebuilds\s+\s+false\s+2`) + pty.ExpectRegexMatch(`preset-prebuilds\s+Preset without parameters and 2 prebuild instances.\s+\s+false\s+2`) }) t.Run("ListsPresetsForSpecifiedTemplateVersion", func(t *testing.T) { @@ -158,8 +162,9 @@ func TestTemplatePresets(t *testing.T) { }, }, { - Name: "preset-prebuilds", - Parameters: []*proto.PresetParameter{}, + Name: "preset-prebuilds", + Description: "Preset without parameters and 2 prebuild instances.", + Parameters: []*proto.PresetParameter{}, Prebuild: &proto.Prebuild{ Instances: 2, }, @@ -208,7 +213,69 @@ func TestTemplatePresets(t *testing.T) { pty.ExpectRegexMatch(`preset-default\s+k1=v2\s+true\s+0`) // The parameter order is not guaranteed in the output, so we match both possible orders pty.ExpectRegexMatch(`preset-multiple-params\s+(k1=v1,k2=v2)|(k2=v2,k1=v1)\s+false\s+-`) - pty.ExpectRegexMatch(`preset-prebuilds\s+\s+false\s+2`) + pty.ExpectRegexMatch(`preset-prebuilds\s+Preset without parameters and 2 prebuild instances.\s+\s+false\s+2`) + }) + + t.Run("ListsPresetsJSON", func(t *testing.T) { + t.Parallel() + + client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true}) + owner := coderdtest.CreateFirstUser(t, client) + member, _ := coderdtest.CreateAnotherUser(t, client, owner.OrganizationID) + + // Given: an active template version that includes presets + preset := proto.Preset{ + Name: "preset-default", + Description: "Preset with parameters and 2 prebuild instances.", + Icon: "/emojis/1f60e.png", + Default: true, + Parameters: []*proto.PresetParameter{ + { + Name: "k1", + Value: "v2", + }, + }, + Prebuild: &proto.Prebuild{ + Instances: 2, + }, + } + + version := coderdtest.CreateTemplateVersion(t, client, owner.OrganizationID, templateWithPresets([]*proto.Preset{&preset})) + _ = coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID) + template := coderdtest.CreateTemplate(t, client, owner.OrganizationID, version.ID) + require.Equal(t, version.ID, template.ActiveVersionID) + + // When: listing presets for that template + inv, root := clitest.New(t, "templates", "presets", "list", template.Name, "-o", "json") + clitest.SetupConfig(t, member, root) + + buf := bytes.NewBuffer(nil) + inv.Stdout = buf + doneChan := make(chan struct{}) + var runErr error + go func() { + defer close(doneChan) + runErr = inv.Run() + }() + + <-doneChan + require.NoError(t, runErr) + + // Should: return the active version's preset + var jsonPresets []cli.TemplatePresetRow + err := json.Unmarshal(buf.Bytes(), &jsonPresets) + require.NoError(t, err, "unmarshal JSON output") + require.Len(t, jsonPresets, 1) + + jsonPreset := jsonPresets[0].TemplatePreset + require.Equal(t, preset.Name, jsonPreset.Name) + require.Equal(t, preset.Description, jsonPreset.Description) + require.Equal(t, preset.Icon, jsonPreset.Icon) + require.Equal(t, preset.Default, jsonPreset.Default) + require.Equal(t, len(preset.Parameters), len(jsonPreset.Parameters)) + require.Equal(t, preset.Parameters[0].Name, jsonPreset.Parameters[0].Name) + require.Equal(t, preset.Parameters[0].Value, jsonPreset.Parameters[0].Value) + require.Equal(t, int(preset.Prebuild.Instances), *jsonPreset.DesiredPrebuildInstances) }) } diff --git a/cli/testdata/coder_templates_presets_list_--help.golden b/cli/testdata/coder_templates_presets_list_--help.golden index 81445df03cc97..e64ef1ee36e96 100644 --- a/cli/testdata/coder_templates_presets_list_--help.golden +++ b/cli/testdata/coder_templates_presets_list_--help.golden @@ -10,7 +10,7 @@ OPTIONS: -O, --org string, $CODER_ORGANIZATION Select which organization (uuid or name) to use. - -c, --column [name|parameters|default|desired prebuild instances] (default: name,parameters,default,desired prebuild instances) + -c, --column [name|description|parameters|default|desired prebuild instances] (default: name,description,parameters,default,desired prebuild instances) Columns to display in table output. -o, --output table|json (default: table) diff --git a/docs/reference/cli/templates_presets_list.md b/docs/reference/cli/templates_presets_list.md index 69dd12faadc7b..5c2d26859f018 100644 --- a/docs/reference/cli/templates_presets_list.md +++ b/docs/reference/cli/templates_presets_list.md @@ -30,10 +30,10 @@ Select which organization (uuid or name) to use. ### -c, --column -| | | -|---------|----------------------------------------------------------------------| -| Type | [name\|parameters\|default\|desired prebuild instances] | -| Default | name,parameters,default,desired prebuild instances | +| | | +|---------|-----------------------------------------------------------------------------------| +| Type | [name\|description\|parameters\|default\|desired prebuild instances] | +| Default | name,description,parameters,default,desired prebuild instances | Columns to display in table output. 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