diff --git a/cmd/feedback/feedback.go b/cmd/feedback/feedback.go index 3eb6b349..229c0821 100644 --- a/cmd/feedback/feedback.go +++ b/cmd/feedback/feedback.go @@ -377,6 +377,7 @@ func chooseSurveyPrompt(ctx context.Context, clients *shared.ClientFactory, surv selection, err := clients.IO.SelectPrompt(ctx, msg, surveyPromptOptions, iostreams.SelectPromptConfig{ Flag: clients.Config.Flags.Lookup("name"), + Required: true, PageSize: 4, Description: func(value string, index int) string { if index < len(surveyNames) { diff --git a/cmd/project/create_samples.go b/cmd/project/create_samples.go index e21b1dbd..782443ba 100644 --- a/cmd/project/create_samples.go +++ b/cmd/project/create_samples.go @@ -24,6 +24,8 @@ import ( "github.com/slackapi/slack-cli/internal/iostreams" "github.com/slackapi/slack-cli/internal/pkg/create" "github.com/slackapi/slack-cli/internal/shared" + "github.com/slackapi/slack-cli/internal/style" + "github.com/spf13/pflag" ) //go:embed samples.tmpl @@ -36,13 +38,57 @@ func PromptSampleSelection(ctx context.Context, clients *shared.ClientFactory, s return "", err } - projectType := "deno" - filteredRepos := filterRepos(sampleRepos, projectType) + projectTypes := []string{} + selection, err := clients.IO.SelectPrompt(ctx, "Select a language:", + []string{ + fmt.Sprintf("Bolt for JavaScript %s", style.Secondary("Node.js")), + fmt.Sprintf("Bolt for Python %s", style.Secondary("Python")), + fmt.Sprintf("Deno Slack SDK %s", style.Secondary("Deno")), + }, + iostreams.SelectPromptConfig{ + Flags: []*pflag.Flag{ + clients.Config.Flags.Lookup("language"), + clients.Config.Flags.Lookup("template"), // Skip filtering with a template + }, + Required: false, + }, + ) + if err != nil { + return "", err + } else if selection.Prompt { + switch selection.Index { + case 0: + projectTypes = []string{"bolt-js", "bolt-ts"} + case 1: + projectTypes = []string{"bolt-python"} + case 2: + projectTypes = []string{"deno"} + } + } else if selection.Flag { + switch strings.ToLower(strings.TrimSpace(selection.Option)) { + case "node": + projectTypes = []string{"bolt-js", "bolt-ts"} + case "python": + projectTypes = []string{"bolt-python"} + case "deno": + projectTypes = []string{"deno"} + default: + projectTypes = []string{selection.Option} + } + } + + filteredRepos := []create.GithubRepo{} + if len(projectTypes) <= 0 { + filteredRepos = sampleRepos + } + for _, language := range projectTypes { + filteredRepos = append(filteredRepos, filterRepos(sampleRepos, language)...) + } sortedRepos := sortRepos(filteredRepos) selectOptions := createSelectOptions(sortedRepos) var selectedTemplate string - selection, err := clients.IO.SelectPrompt(ctx, "Select a sample to build upon:", selectOptions, iostreams.SelectPromptConfig{ + selection, err = clients.IO.SelectPrompt(ctx, "Select a sample to build upon:", selectOptions, iostreams.SelectPromptConfig{ Description: func(value string, index int) string { return sortedRepos[index].Description + "\n https://github.com/" + sortedRepos[index].FullName }, diff --git a/cmd/project/create_samples_test.go b/cmd/project/create_samples_test.go index 14a5fe37..00ad29ad 100644 --- a/cmd/project/create_samples_test.go +++ b/cmd/project/create_samples_test.go @@ -109,6 +109,16 @@ func TestSamples_PromptSampleSelection(t *testing.T) { res := w.Result() sampler.On("Do", mock.Anything).Return(res, nil) clientsMock := shared.NewClientsMock() + clientsMock.IO.On( + "SelectPrompt", + mock.Anything, + "Select a language:", + mock.Anything, + mock.Anything, + ).Return(iostreams.SelectPromptResponse{ + Index: 2, + Prompt: true, + }, nil) clientsMock.IO.On( "SelectPrompt", mock.Anything, diff --git a/cmd/project/samples.go b/cmd/project/samples.go index d84325a6..8889f7dc 100644 --- a/cmd/project/samples.go +++ b/cmd/project/samples.go @@ -26,6 +26,7 @@ import ( // Flags var samplesTemplateURLFlag string var samplesGitBranchFlag string +var samplesLanguageFlag string func NewSamplesCommand(clients *shared.ClientFactory) *cobra.Command { cmd := &cobra.Command{ @@ -45,6 +46,7 @@ func NewSamplesCommand(clients *shared.ClientFactory) *cobra.Command { cmd.Flags().StringVarP(&samplesTemplateURLFlag, "template", "t", "", "template URL for your app") cmd.Flags().StringVarP(&samplesGitBranchFlag, "branch", "b", "", "name of git branch to checkout") + cmd.Flags().StringVar(&samplesLanguageFlag, "language", "", "runtime for the app framework\n ex: \"deno\", \"node\", \"python\"") return cmd } diff --git a/cmd/project/samples_test.go b/cmd/project/samples_test.go index 0bc7e96d..6ca46558 100644 --- a/cmd/project/samples_test.go +++ b/cmd/project/samples_test.go @@ -47,6 +47,14 @@ func TestSamplesCommand(t *testing.T) { } return repos, nil } + cm.IO.On("SelectPrompt", mock.Anything, "Select a language:", mock.Anything, mock.Anything). + Return( + iostreams.SelectPromptResponse{ + Index: 2, + Prompt: true, + }, + nil, + ) cm.IO.On("SelectPrompt", mock.Anything, "Select a sample to build upon:", mock.Anything, mock.Anything). Return( iostreams.SelectPromptResponse{ diff --git a/internal/iostreams/survey.go b/internal/iostreams/survey.go index 22477afa..5a094ab1 100644 --- a/internal/iostreams/survey.go +++ b/internal/iostreams/survey.go @@ -447,7 +447,11 @@ func (io *IOStreams) SelectPrompt(ctx context.Context, msg string, options []str return SelectPromptResponse{}, slackerror.New(slackerror.ErrMissingOptions) } if !io.IsTTY() { - return SelectPromptResponse{}, errInteractivityFlags(cfg) + if cfg.IsRequired() { + return SelectPromptResponse{}, errInteractivityFlags(cfg) + } else { + return SelectPromptResponse{}, nil + } } defaultSelectTemplate := survey.SelectQuestionTemplate @@ -491,6 +495,9 @@ func (io *IOStreams) retrieveFlagValue(flagset []*pflag.Flag) (*pflag.Flag, erro return nil, nil } for _, opt := range flagset { + if opt == nil { + continue + } if !opt.Changed { continue } else if flag != nil {