From 6133cf35a7cf7cdfd74734286763416ee314d2d2 Mon Sep 17 00:00:00 2001 From: Dean Sheather Date: Thu, 19 May 2022 08:02:17 +0000 Subject: [PATCH] feat: use and display default template values when creating wkspc. --- cli/cliui/parameter.go | 20 ++++++++++++++++-- cli/cliui/select.go | 11 +++++++++- cli/create_test.go | 46 ++++++++++++++++++++++++++++++++---------- cli/login.go | 2 +- 4 files changed, 64 insertions(+), 15 deletions(-) diff --git a/cli/cliui/parameter.go b/cli/cliui/parameter.go index 2859d2b24d6e8..6918cd4357b68 100644 --- a/cli/cliui/parameter.go +++ b/cli/cliui/parameter.go @@ -30,6 +30,7 @@ func ParameterSchema(cmd *cobra.Command, parameterSchema codersdk.TemplateVersio _, _ = fmt.Fprint(cmd.OutOrStdout(), "\033[1A") value, err = Select(cmd, SelectOptions{ Options: options, + Default: parameterSchema.DefaultSourceValue, HideSearch: true, }) if err == nil { @@ -37,9 +38,24 @@ func ParameterSchema(cmd *cobra.Command, parameterSchema codersdk.TemplateVersio _, _ = fmt.Fprintln(cmd.OutOrStdout(), " "+Styles.Prompt.String()+Styles.Field.Render(value)) } } else { + text := "Enter a value" + if parameterSchema.DefaultSourceValue != "" { + text += fmt.Sprintf(" (default: %q)", parameterSchema.DefaultSourceValue) + } + text += ":" + value, err = Prompt(cmd, PromptOptions{ - Text: Styles.Bold.Render("Enter a value:"), + Text: Styles.Bold.Render(text), }) } - return value, err + if err != nil { + return "", err + } + + // If they didn't specify anything, use the default value if set. + if len(options) == 0 && value == "" { + value = parameterSchema.DefaultSourceValue + } + + return value, nil } diff --git a/cli/cliui/select.go b/cli/cliui/select.go index 5b9f535049aa2..63fda4f87720d 100644 --- a/cli/cliui/select.go +++ b/cli/cliui/select.go @@ -35,7 +35,9 @@ func init() { } type SelectOptions struct { - Options []string + Options []string + // Default will be highlighted first if it's a valid option. + Default string Size int HideSearch bool } @@ -50,9 +52,16 @@ func Select(cmd *cobra.Command, opts SelectOptions) (string, error) { if flag.Lookup("test.v") != nil { return opts.Options[0], nil } + + var defaultOption interface{} + if opts.Default != "" { + defaultOption = opts.Default + } + var value string err := survey.AskOne(&survey.Select{ Options: opts.Options, + Default: defaultOption, PageSize: opts.Size, }, &value, survey.WithIcons(func(is *survey.IconSet) { is.Help.Text = "Type to search" diff --git a/cli/create_test.go b/cli/create_test.go index 447daf471fddd..b9746df993196 100644 --- a/cli/create_test.go +++ b/cli/create_test.go @@ -1,6 +1,7 @@ package cli_test import ( + "fmt" "testing" "github.com/stretchr/testify/require" @@ -44,6 +45,7 @@ func TestCreate(t *testing.T) { } <-doneChan }) + t.Run("CreateFromList", func(t *testing.T) { t.Parallel() client := coderdtest.New(t, nil) @@ -74,6 +76,7 @@ func TestCreate(t *testing.T) { } <-doneChan }) + t.Run("FromNothing", func(t *testing.T) { t.Parallel() client := coderdtest.New(t, nil) @@ -105,33 +108,52 @@ func TestCreate(t *testing.T) { } <-doneChan }) + t.Run("WithParameter", func(t *testing.T) { t.Parallel() client := coderdtest.New(t, nil) user := coderdtest.CreateFirstUser(t, client) coderdtest.NewProvisionerDaemon(t, client) + + defaultValue := "something" version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{ Parse: []*proto.Parse_Response{{ Type: &proto.Parse_Response_Complete{ Complete: &proto.Parse_Complete{ - ParameterSchemas: []*proto.ParameterSchema{{ - AllowOverrideSource: true, - Name: "region", - Description: "description", - DefaultSource: &proto.ParameterSource{ - Scheme: proto.ParameterSource_DATA, - Value: "something", + ParameterSchemas: []*proto.ParameterSchema{ + { + AllowOverrideSource: true, + Name: "region", + Description: "description 1", + DefaultSource: &proto.ParameterSource{ + Scheme: proto.ParameterSource_DATA, + Value: defaultValue, + }, + DefaultDestination: &proto.ParameterDestination{ + Scheme: proto.ParameterDestination_PROVISIONER_VARIABLE, + }, }, - DefaultDestination: &proto.ParameterDestination{ - Scheme: proto.ParameterDestination_PROVISIONER_VARIABLE, + { + AllowOverrideSource: true, + Name: "username", + Description: "description 2", + DefaultSource: &proto.ParameterSource{ + Scheme: proto.ParameterSource_DATA, + // No default value + Value: "", + }, + DefaultDestination: &proto.ParameterDestination{ + Scheme: proto.ParameterDestination_PROVISIONER_VARIABLE, + }, }, - }}, + }, }, }, }}, Provision: echo.ProvisionComplete, ProvisionDryRun: echo.ProvisionComplete, }) + coderdtest.AwaitTemplateVersionJob(t, client, version.ID) _ = coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID) cmd, root := clitest.New(t, "create", "") @@ -145,9 +167,11 @@ func TestCreate(t *testing.T) { err := cmd.Execute() require.NoError(t, err) }() + matches := []string{ "Specify a name", "my-workspace", - "Enter a value", "bananas", + fmt.Sprintf("Enter a value (default: %q):", defaultValue), "bingo", + "Enter a value:", "boingo", "Confirm create?", "yes", } for i := 0; i < len(matches); i += 2 { diff --git a/cli/login.go b/cli/login.go index d03fb65e892cc..f931952959324 100644 --- a/cli/login.go +++ b/cli/login.go @@ -164,7 +164,7 @@ func login() *cobra.Command { cliui.Styles.Paragraph.Render(fmt.Sprintf("Welcome to Coder, %s! You're authenticated.", cliui.Styles.Keyword.Render(username)))+"\n") _, _ = fmt.Fprintf(cmd.OutOrStdout(), - cliui.Styles.Paragraph.Render("Get started by creating a template: "+cliui.Styles.Code.Render("coder templates create"))+"\n") + cliui.Styles.Paragraph.Render("Get started by creating a template: "+cliui.Styles.Code.Render("coder templates init"))+"\n") return nil }