Skip to content

Commit 86adf7a

Browse files
chore(cli): re-order CLI create command
Relates to coder/internal#893 Instead of `coder task create <template> --input <input>`, it is now `coder task create <input> --template <template>`. If there is only one AI task template on the deployment, the `--template` parameter can be omitted.
1 parent 3470632 commit 86adf7a

File tree

2 files changed

+55
-25
lines changed

2 files changed

+55
-25
lines changed

cli/exp_taskcreate.go renamed to cli/exp_task_create.go

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package cli
22

33
import (
44
"fmt"
5-
"strings"
65

76
"github.com/google/uuid"
87
"golang.org/x/xerrors"
@@ -24,24 +23,25 @@ func (r *RootCmd) taskCreate() *serpent.Command {
2423
)
2524

2625
cmd := &serpent.Command{
27-
Use: "create [template]",
26+
Use: "create [input]",
2827
Short: "Create an experimental task",
2928
Middleware: serpent.Chain(
3029
serpent.RequireRangeArgs(0, 1),
3130
r.InitClient(client),
3231
),
3332
Options: serpent.OptionSet{
3433
{
35-
Flag: "input",
36-
Env: "CODER_TASK_INPUT",
37-
Value: serpent.StringOf(&taskInput),
38-
Required: true,
34+
Flag: "input",
35+
Env: "CODER_TASK_INPUT",
36+
Value: serpent.StringOf(&taskInput),
3937
},
4038
{
39+
Flag: "template",
4140
Env: "CODER_TASK_TEMPLATE_NAME",
4241
Value: serpent.StringOf(&templateName),
4342
},
4443
{
44+
Flag: "template-version",
4545
Env: "CODER_TASK_TEMPLATE_VERSION",
4646
Value: serpent.StringOf(&templateVersionName),
4747
},
@@ -67,20 +67,21 @@ func (r *RootCmd) taskCreate() *serpent.Command {
6767
}
6868

6969
if len(inv.Args) > 0 {
70-
templateName, templateVersionName, _ = strings.Cut(inv.Args[0], "@")
70+
taskInput = inv.Args[0]
7171
}
7272

7373
if templateName == "" {
74-
return xerrors.Errorf("template name not provided")
75-
}
76-
77-
if templateVersionName != "" {
78-
templateVersion, err := client.TemplateVersionByOrganizationAndName(ctx, organization.ID, templateName, templateVersionName)
74+
templates, err := client.Templates(ctx, codersdk.TemplateFilter{SearchQuery: "has-ai-task:true", OrganizationID: organization.ID})
7975
if err != nil {
80-
return xerrors.Errorf("get template version: %w", err)
76+
return xerrors.Errorf("list templates: %w", err)
8177
}
8278

83-
templateVersionID = templateVersion.ID
79+
if len(templates) == 1 {
80+
templateName = templates[0].Name
81+
templateVersionID = templates[0].ActiveVersionID
82+
} else {
83+
return xerrors.Errorf("template name not provided")
84+
}
8485
} else {
8586
template, err := client.TemplateByName(ctx, organization.ID, templateName)
8687
if err != nil {
@@ -90,6 +91,15 @@ func (r *RootCmd) taskCreate() *serpent.Command {
9091
templateVersionID = template.ActiveVersionID
9192
}
9293

94+
if templateVersionName != "" {
95+
templateVersion, err := client.TemplateVersionByOrganizationAndName(ctx, organization.ID, templateName, templateVersionName)
96+
if err != nil {
97+
return xerrors.Errorf("get template version: %w", err)
98+
}
99+
100+
templateVersionID = templateVersion.ID
101+
}
102+
93103
if presetName != PresetNone {
94104
templatePresets, err := client.TemplateVersionPresets(ctx, templateVersionID)
95105
if err != nil {

cli/exp_taskcreate_test.go renamed to cli/exp_task_create_test.go

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,14 @@ func TestTaskCreate(t *testing.T) {
6060
Name: presetName,
6161
},
6262
})
63+
case "/api/v2/templates":
64+
httpapi.Write(ctx, w, http.StatusOK, []codersdk.Template{
65+
{
66+
ID: templateID,
67+
Name: templateName,
68+
ActiveVersionID: templateVersionID,
69+
},
70+
})
6371
case "/api/experimental/tasks/me":
6472
var req codersdk.CreateTaskRequest
6573
if !httpapi.Read(ctx, w, r, &req) {
@@ -93,22 +101,29 @@ func TestTaskCreate(t *testing.T) {
93101
handler func(t *testing.T, ctx context.Context) http.HandlerFunc
94102
}{
95103
{
96-
args: []string{"my-template@my-template-version", "--input", "my custom prompt", "--org", organizationID.String()},
104+
args: []string{"my custom prompt"},
105+
expectOutput: fmt.Sprintf("The task %s has been created at %s!", cliui.Keyword("task-wild-goldfish-27"), cliui.Timestamp(taskCreatedAt)),
106+
handler: func(t *testing.T, ctx context.Context) http.HandlerFunc {
107+
return templateAndVersionFoundHandler(t, ctx, organizationID, "my-template", "my-template-version", "", "my custom prompt")
108+
},
109+
},
110+
{
111+
args: []string{"my custom prompt", "--template", "my-template", "--template-version", "my-template-version", "--org", organizationID.String()},
97112
expectOutput: fmt.Sprintf("The task %s has been created at %s!", cliui.Keyword("task-wild-goldfish-27"), cliui.Timestamp(taskCreatedAt)),
98113
handler: func(t *testing.T, ctx context.Context) http.HandlerFunc {
99114
return templateAndVersionFoundHandler(t, ctx, organizationID, "my-template", "my-template-version", "", "my custom prompt")
100115
},
101116
},
102117
{
103-
args: []string{"my-template", "--input", "my custom prompt", "--org", organizationID.String()},
118+
args: []string{"my custom prompt", "--template", "my-template", "--org", organizationID.String()},
104119
env: []string{"CODER_TASK_TEMPLATE_VERSION=my-template-version"},
105120
expectOutput: fmt.Sprintf("The task %s has been created at %s!", cliui.Keyword("task-wild-goldfish-27"), cliui.Timestamp(taskCreatedAt)),
106121
handler: func(t *testing.T, ctx context.Context) http.HandlerFunc {
107122
return templateAndVersionFoundHandler(t, ctx, organizationID, "my-template", "my-template-version", "", "my custom prompt")
108123
},
109124
},
110125
{
111-
args: []string{"--input", "my custom prompt", "--org", organizationID.String()},
126+
args: []string{"my custom prompt", "--org", organizationID.String()},
112127
env: []string{"CODER_TASK_TEMPLATE_NAME=my-template", "CODER_TASK_TEMPLATE_VERSION=my-template-version"},
113128
expectOutput: fmt.Sprintf("The task %s has been created at %s!", cliui.Keyword("task-wild-goldfish-27"), cliui.Timestamp(taskCreatedAt)),
114129
handler: func(t *testing.T, ctx context.Context) http.HandlerFunc {
@@ -123,36 +138,36 @@ func TestTaskCreate(t *testing.T) {
123138
},
124139
},
125140
{
126-
args: []string{"my-template", "--input", "my custom prompt", "--org", organizationID.String()},
141+
args: []string{"my custom prompt", "--template", "my-template", "--org", organizationID.String()},
127142
expectOutput: fmt.Sprintf("The task %s has been created at %s!", cliui.Keyword("task-wild-goldfish-27"), cliui.Timestamp(taskCreatedAt)),
128143
handler: func(t *testing.T, ctx context.Context) http.HandlerFunc {
129144
return templateAndVersionFoundHandler(t, ctx, organizationID, "my-template", "", "", "my custom prompt")
130145
},
131146
},
132147
{
133-
args: []string{"my-template", "--input", "my custom prompt", "--preset", "my-preset", "--org", organizationID.String()},
148+
args: []string{"my custom prompt", "--template", "my-template", "--preset", "my-preset", "--org", organizationID.String()},
134149
expectOutput: fmt.Sprintf("The task %s has been created at %s!", cliui.Keyword("task-wild-goldfish-27"), cliui.Timestamp(taskCreatedAt)),
135150
handler: func(t *testing.T, ctx context.Context) http.HandlerFunc {
136151
return templateAndVersionFoundHandler(t, ctx, organizationID, "my-template", "", "my-preset", "my custom prompt")
137152
},
138153
},
139154
{
140-
args: []string{"my-template", "--input", "my custom prompt"},
155+
args: []string{"my custom prompt", "--template", "my-template"},
141156
env: []string{"CODER_TASK_PRESET_NAME=my-preset"},
142157
expectOutput: fmt.Sprintf("The task %s has been created at %s!", cliui.Keyword("task-wild-goldfish-27"), cliui.Timestamp(taskCreatedAt)),
143158
handler: func(t *testing.T, ctx context.Context) http.HandlerFunc {
144159
return templateAndVersionFoundHandler(t, ctx, organizationID, "my-template", "", "my-preset", "my custom prompt")
145160
},
146161
},
147162
{
148-
args: []string{"my-template", "--input", "my custom prompt", "--preset", "not-real-preset"},
163+
args: []string{"my custom prompt", "--template", "my-template", "--preset", "not-real-preset"},
149164
expectError: `preset "not-real-preset" not found`,
150165
handler: func(t *testing.T, ctx context.Context) http.HandlerFunc {
151166
return templateAndVersionFoundHandler(t, ctx, organizationID, "my-template", "", "my-preset", "my custom prompt")
152167
},
153168
},
154169
{
155-
args: []string{"my-template@not-real-template-version", "--input", "my custom prompt"},
170+
args: []string{"my custom prompt", "--template", "my-template", "--template-version", "not-real-template-version"},
156171
expectError: httpapi.ResourceNotFoundResponse.Message,
157172
handler: func(t *testing.T, ctx context.Context) http.HandlerFunc {
158173
return func(w http.ResponseWriter, r *http.Request) {
@@ -163,6 +178,11 @@ func TestTaskCreate(t *testing.T) {
163178
ID: organizationID,
164179
}},
165180
})
181+
case fmt.Sprintf("/api/v2/organizations/%s/templates/my-template", organizationID):
182+
httpapi.Write(ctx, w, http.StatusOK, codersdk.Template{
183+
ID: templateID,
184+
ActiveVersionID: templateVersionID,
185+
})
166186
case fmt.Sprintf("/api/v2/organizations/%s/templates/my-template/versions/not-real-template-version", organizationID):
167187
httpapi.ResourceNotFound(w)
168188
default:
@@ -172,7 +192,7 @@ func TestTaskCreate(t *testing.T) {
172192
},
173193
},
174194
{
175-
args: []string{"not-real-template", "--input", "my custom prompt", "--org", organizationID.String()},
195+
args: []string{"my custom prompt", "--template", "not-real-template", "--org", organizationID.String()},
176196
expectError: httpapi.ResourceNotFoundResponse.Message,
177197
handler: func(t *testing.T, ctx context.Context) http.HandlerFunc {
178198
return func(w http.ResponseWriter, r *http.Request) {
@@ -192,7 +212,7 @@ func TestTaskCreate(t *testing.T) {
192212
},
193213
},
194214
{
195-
args: []string{"template-in-different-org", "--input", "my-custom-prompt", "--org", anotherOrganizationID.String()},
215+
args: []string{"my-custom-prompt", "--template", "template-in-different-org", "--org", anotherOrganizationID.String()},
196216
expectError: httpapi.ResourceNotFoundResponse.Message,
197217
handler: func(t *testing.T, ctx context.Context) http.HandlerFunc {
198218
return func(w http.ResponseWriter, r *http.Request) {
@@ -212,7 +232,7 @@ func TestTaskCreate(t *testing.T) {
212232
},
213233
},
214234
{
215-
args: []string{"no-org", "--input", "my-custom-prompt"},
235+
args: []string{"no-org-prompt"},
216236
expectError: "Must select an organization with --org=<org_name>",
217237
handler: func(t *testing.T, ctx context.Context) http.HandlerFunc {
218238
return func(w http.ResponseWriter, r *http.Request) {

0 commit comments

Comments
 (0)