Skip to content

Commit 10c538d

Browse files
committed
feat: add 'list' flag to create command
1 parent 9250b37 commit 10c538d

3 files changed

Lines changed: 83 additions & 0 deletions

File tree

cmd/project/create.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import (
3232
var createTemplateURLFlag string
3333
var createGitBranchFlag string
3434
var createAppNameFlag string
35+
var createListFlag bool
3536

3637
// Handle to client's create function used for testing
3738
// TODO - Find best practice, such as using an Interface and Struct to create a client
@@ -77,6 +78,7 @@ name your app 'agent' (not create an AI Agent), use the --name flag instead.`,
7778
cmd.Flags().StringVarP(&createTemplateURLFlag, "template", "t", "", "template URL for your app")
7879
cmd.Flags().StringVarP(&createGitBranchFlag, "branch", "b", "", "name of git branch to checkout")
7980
cmd.Flags().StringVarP(&createAppNameFlag, "name", "n", "", "name for your app (overrides the name argument)")
81+
cmd.Flags().BoolVar(&createListFlag, "list", false, "list available app templates")
8082

8183
return cmd
8284
}
@@ -121,6 +123,11 @@ func runCreateCommand(clients *shared.ClientFactory, cmd *cobra.Command, args []
121123
appNameArg = createAppNameFlag
122124
}
123125

126+
// List templates and exit early if the --list flag is set
127+
if createListFlag {
128+
return listTemplates(ctx, clients, categoryShortcut)
129+
}
130+
124131
// Collect the template URL or select a starting template
125132
template, err := promptTemplateSelection(cmd, clients, categoryShortcut)
126133
if err != nil {

cmd/project/create_template.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
package project
1616

1717
import (
18+
"context"
1819
"fmt"
1920
"strings"
2021
"time"
@@ -240,6 +241,41 @@ func confirmExternalTemplateSelection(cmd *cobra.Command, clients *shared.Client
240241
return true, nil
241242
}
242243

244+
// listTemplates prints available templates for the create command
245+
func listTemplates(ctx context.Context, clients *shared.ClientFactory, categoryShortcut string) error {
246+
type categoryInfo struct {
247+
id string
248+
name string
249+
}
250+
251+
var categories []categoryInfo
252+
if categoryShortcut == "agent" {
253+
categories = []categoryInfo{
254+
{id: "slack-cli#ai-apps", name: "AI Agent apps"},
255+
}
256+
} else {
257+
categories = []categoryInfo{
258+
{id: "slack-cli#getting-started", name: "Getting started"},
259+
{id: "slack-cli#ai-apps", name: "AI Agent apps"},
260+
{id: "slack-cli#automation-apps", name: "Automation apps"},
261+
}
262+
}
263+
264+
for _, category := range categories {
265+
templates := getSelectionOptions(clients, category.id)
266+
secondary := make([]string, len(templates))
267+
for i, tmpl := range templates {
268+
secondary[i] = tmpl.Repository
269+
}
270+
clients.IO.PrintInfo(ctx, false, style.Sectionf(style.TextSection{
271+
Text: style.Bold(category.name),
272+
Secondary: secondary,
273+
}))
274+
}
275+
276+
return nil
277+
}
278+
243279
// getSelectionTemplate returns a custom formatted template used for selecting a
244280
// project template during creation
245281
func getSelectionTemplate(clients *shared.ClientFactory) string {

cmd/project/create_test.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,46 @@ func TestCreateCommand(t *testing.T) {
320320
cm.IO.AssertNotCalled(t, "SelectPrompt", mock.Anything, "Select an app:", mock.Anything, mock.Anything)
321321
},
322322
},
323+
"lists all templates with --list flag": {
324+
CmdArgs: []string{"--list"},
325+
Setup: func(t *testing.T, ctx context.Context, cm *shared.ClientsMock, cf *shared.ClientFactory) {
326+
createClientMock = new(CreateClientMock)
327+
CreateFunc = createClientMock.Create
328+
},
329+
ExpectedOutputs: []string{
330+
"Getting started",
331+
"AI Agent apps",
332+
"Automation apps",
333+
"slack-samples/bolt-js-starter-template",
334+
"slack-samples/bolt-python-starter-template",
335+
"slack-samples/bolt-js-assistant-template",
336+
"slack-samples/bolt-python-assistant-template",
337+
"slack-samples/bolt-js-custom-function-template",
338+
"slack-samples/bolt-python-custom-function-template",
339+
"slack-samples/deno-starter-template",
340+
},
341+
ExpectedAsserts: func(t *testing.T, ctx context.Context, cm *shared.ClientsMock) {
342+
createClientMock.AssertNotCalled(t, "Create", mock.Anything, mock.Anything, mock.Anything, mock.Anything)
343+
},
344+
},
345+
"lists agent templates with agent --list flag": {
346+
CmdArgs: []string{"agent", "--list"},
347+
Setup: func(t *testing.T, ctx context.Context, cm *shared.ClientsMock, cf *shared.ClientFactory) {
348+
createClientMock = new(CreateClientMock)
349+
CreateFunc = createClientMock.Create
350+
},
351+
ExpectedOutputs: []string{
352+
"AI Agent apps",
353+
"slack-samples/bolt-js-assistant-template",
354+
"slack-samples/bolt-python-assistant-template",
355+
},
356+
ExpectedAsserts: func(t *testing.T, ctx context.Context, cm *shared.ClientsMock) {
357+
createClientMock.AssertNotCalled(t, "Create", mock.Anything, mock.Anything, mock.Anything, mock.Anything)
358+
output := cm.GetCombinedOutput()
359+
assert.NotContains(t, output, "Getting started")
360+
assert.NotContains(t, output, "Automation apps")
361+
},
362+
},
323363
}, func(cf *shared.ClientFactory) *cobra.Command {
324364
return NewCreateCommand(cf)
325365
})

0 commit comments

Comments
 (0)