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.