From a44b1fc55735ed610e8a103c4c9faa97c3a32c12 Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Thu, 19 May 2022 10:28:05 -0500 Subject: [PATCH 01/15] feat: Add confirm prompts to some cli actions - Workspace start/stop - Add optional -y skip. Standardize -y flag across commands --- cli/cliui/prompt.go | 13 +++++++++++++ cli/create.go | 1 + cli/start.go | 12 +++++++++++- cli/stop.go | 12 +++++++++++- cli/templatecreate.go | 17 +++++++---------- 5 files changed, 43 insertions(+), 12 deletions(-) diff --git a/cli/cliui/prompt.go b/cli/cliui/prompt.go index ac39404e27d3f..16f0c438f4007 100644 --- a/cli/cliui/prompt.go +++ b/cli/cliui/prompt.go @@ -24,8 +24,21 @@ type PromptOptions struct { Validate func(string) error } +func AllowSkipPrompt(cmd *cobra.Command) { + cmd.Flags().BoolP("yes", "y", false, "Bypass prompts") +} + // Prompt asks the user for input. func Prompt(cmd *cobra.Command, opts PromptOptions) (string, error) { + // If the cmd has a "yes" flag for skipping confirm prompts, honor it. + // If it's not a "Confirm" prompt, then don't skip. As the default value of + // "yes" makes no sense. + if opts.IsConfirm && cmd.Flags().Lookup("yes") != nil { + if skip, _ := cmd.Flags().GetBool("yes"); skip { + return "yes", nil + } + } + _, _ = fmt.Fprint(cmd.OutOrStdout(), Styles.FocusedPrompt.String()+opts.Text+" ") if opts.IsConfirm { opts.Default = "yes" diff --git a/cli/create.go b/cli/create.go index aa6930e8151f6..6b73ec375b81a 100644 --- a/cli/create.go +++ b/cli/create.go @@ -194,6 +194,7 @@ func create() *cobra.Command { }, } + cliui.AllowSkipPrompt(cmd) cliflag.StringVarP(cmd.Flags(), &templateName, "template", "t", "CODER_TEMPLATE_NAME", "", "Specify a template name.") return cmd } diff --git a/cli/start.go b/cli/start.go index 223731045e38f..31a95188c583b 100644 --- a/cli/start.go +++ b/cli/start.go @@ -11,12 +11,20 @@ import ( ) func start() *cobra.Command { - return &cobra.Command{ + cmd := &cobra.Command{ Annotations: workspaceCommand, Use: "start ", Short: "Build a workspace with the start state", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { + _, err := cliui.Prompt(cmd, cliui.PromptOptions{ + Text: "Confirm start workspace?", + IsConfirm: true, + }) + if err != nil { + return err + } + client, err := createClient(cmd) if err != nil { return err @@ -39,4 +47,6 @@ func start() *cobra.Command { return cliui.WorkspaceBuild(cmd.Context(), cmd.OutOrStdout(), client, build.ID, before) }, } + cliui.AllowSkipPrompt(cmd) + return cmd } diff --git a/cli/stop.go b/cli/stop.go index 1125901608413..053cfb4689bb7 100644 --- a/cli/stop.go +++ b/cli/stop.go @@ -11,12 +11,20 @@ import ( ) func stop() *cobra.Command { - return &cobra.Command{ + cmd := &cobra.Command{ Annotations: workspaceCommand, Use: "stop ", Short: "Build a workspace with the stop state", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { + _, err := cliui.Prompt(cmd, cliui.PromptOptions{ + Text: "Confirm stop workspace?", + IsConfirm: true, + }) + if err != nil { + return err + } + client, err := createClient(cmd) if err != nil { return err @@ -39,4 +47,6 @@ func stop() *cobra.Command { return cliui.WorkspaceBuild(cmd.Context(), cmd.OutOrStdout(), client, build.ID, before) }, } + cliui.AllowSkipPrompt(cmd) + return cmd } diff --git a/cli/templatecreate.go b/cli/templatecreate.go index 0f6977a674a8e..9ff49dfa0ded7 100644 --- a/cli/templatecreate.go +++ b/cli/templatecreate.go @@ -21,7 +21,6 @@ import ( func templateCreate() *cobra.Command { var ( - yes bool directory string provisioner string ) @@ -84,14 +83,12 @@ func templateCreate() *cobra.Command { return err } - if !yes { - _, err = cliui.Prompt(cmd, cliui.PromptOptions{ - Text: "Confirm create?", - IsConfirm: true, - }) - if err != nil { - return err - } + _, err = cliui.Prompt(cmd, cliui.PromptOptions{ + Text: "Confirm create?", + IsConfirm: true, + }) + if err != nil { + return err } _, err = client.CreateTemplate(cmd.Context(), organization.ID, codersdk.CreateTemplateRequest{ @@ -121,7 +118,7 @@ func templateCreate() *cobra.Command { if err != nil { panic(err) } - cmd.Flags().BoolVarP(&yes, "yes", "y", false, "Bypass prompts") + cliui.AllowSkipPrompt(cmd) return cmd } From 664ea38f998bae1dabbd632255386b2d2d4fbd7d Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Thu, 19 May 2022 10:32:17 -0500 Subject: [PATCH 02/15] Add confirm prompt to delete workspace --- cli/delete.go | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/cli/delete.go b/cli/delete.go index 0f795c06c5435..8e2ce56b616d8 100644 --- a/cli/delete.go +++ b/cli/delete.go @@ -12,13 +12,21 @@ import ( // nolint func delete() *cobra.Command { - return &cobra.Command{ + cmd := &cobra.Command{ Annotations: workspaceCommand, Use: "delete ", Short: "Delete a workspace", Aliases: []string{"rm"}, Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { + _, err := cliui.Prompt(cmd, cliui.PromptOptions{ + Text: "Confirm delete workspace?", + IsConfirm: true, + }) + if err != nil { + return err + } + client, err := createClient(cmd) if err != nil { return err @@ -41,4 +49,6 @@ func delete() *cobra.Command { return cliui.WorkspaceBuild(cmd.Context(), cmd.OutOrStdout(), client, build.ID, before) }, } + cliui.AllowSkipPrompt(cmd) + return cmd } From 373cb23ae89644d05e273faf2b285c004578c02f Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Thu, 19 May 2022 11:32:33 -0500 Subject: [PATCH 03/15] Add unit test for prompt skipping --- cli/cliui/prompt_test.go | 50 +++++++++++++++++++++++++++++++++++----- 1 file changed, 44 insertions(+), 6 deletions(-) diff --git a/cli/cliui/prompt_test.go b/cli/cliui/prompt_test.go index 1926349c2d1fc..4d1b7370cf9fd 100644 --- a/cli/cliui/prompt_test.go +++ b/cli/cliui/prompt_test.go @@ -1,7 +1,9 @@ package cliui_test import ( + "bytes" "context" + "io" "os" "os/exec" "testing" @@ -24,7 +26,7 @@ func TestPrompt(t *testing.T) { go func() { resp, err := newPrompt(ptty, cliui.PromptOptions{ Text: "Example", - }) + }, nil) require.NoError(t, err) msgChan <- resp }() @@ -41,7 +43,7 @@ func TestPrompt(t *testing.T) { resp, err := newPrompt(ptty, cliui.PromptOptions{ Text: "Example", IsConfirm: true, - }) + }, nil) require.NoError(t, err) doneChan <- resp }() @@ -50,6 +52,37 @@ func TestPrompt(t *testing.T) { require.Equal(t, "yes", <-doneChan) }) + t.Run("Skip", func(t *testing.T) { + t.Parallel() + ptty := ptytest.New(t) + var buf bytes.Buffer + + // Copy all data written out to a buffer. When we close the ptty, we can + // no longer read from the ptty.Output(), but we can read what was + // written to the buffer. + go func() { + _, err := io.Copy(&buf, ptty.Output()) + require.NoError(t, err, "copy") + }() + + doneChan := make(chan string) + go func() { + resp, err := newPrompt(ptty, cliui.PromptOptions{ + Text: "ShouldNotSeeThis", + IsConfirm: true, + }, func(cmd *cobra.Command) { + cliui.AllowSkipPrompt(cmd) + cmd.SetArgs([]string{"-y"}) + }) + require.NoError(t, err) + doneChan <- resp + }() + + require.Equal(t, "yes", <-doneChan) + require.NoError(t, ptty.Close(), "close ptty") + require.Len(t, buf.Bytes(), 0, "expect no output") + }) + t.Run("JSON", func(t *testing.T) { t.Parallel() ptty := ptytest.New(t) @@ -57,7 +90,7 @@ func TestPrompt(t *testing.T) { go func() { resp, err := newPrompt(ptty, cliui.PromptOptions{ Text: "Example", - }) + }, nil) require.NoError(t, err) doneChan <- resp }() @@ -71,9 +104,10 @@ func TestPrompt(t *testing.T) { ptty := ptytest.New(t) doneChan := make(chan string) go func() { + resp, err := newPrompt(ptty, cliui.PromptOptions{ Text: "Example", - }) + }, nil) require.NoError(t, err) doneChan <- resp }() @@ -89,7 +123,7 @@ func TestPrompt(t *testing.T) { go func() { resp, err := newPrompt(ptty, cliui.PromptOptions{ Text: "Example", - }) + }, nil) require.NoError(t, err) doneChan <- resp }() @@ -101,7 +135,7 @@ func TestPrompt(t *testing.T) { }) } -func newPrompt(ptty *ptytest.PTY, opts cliui.PromptOptions) (string, error) { +func newPrompt(ptty *ptytest.PTY, opts cliui.PromptOptions, cmdOpt func(cmd *cobra.Command)) (string, error) { value := "" cmd := &cobra.Command{ RunE: func(cmd *cobra.Command, args []string) error { @@ -110,6 +144,10 @@ func newPrompt(ptty *ptytest.PTY, opts cliui.PromptOptions) (string, error) { return err }, } + // Optionally modify the cmd + if cmdOpt != nil { + cmdOpt(cmd) + } cmd.SetOutput(ptty.Output()) cmd.SetIn(ptty.Input()) return value, cmd.ExecuteContext(context.Background()) From 3b6cea6461684314fc947094a904288d8b682f75 Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Thu, 19 May 2022 14:06:25 -0500 Subject: [PATCH 04/15] Fix test flakes --- cli/cliui/prompt_test.go | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/cli/cliui/prompt_test.go b/cli/cliui/prompt_test.go index 4d1b7370cf9fd..4b83fe17449b5 100644 --- a/cli/cliui/prompt_test.go +++ b/cli/cliui/prompt_test.go @@ -53,16 +53,21 @@ func TestPrompt(t *testing.T) { }) t.Run("Skip", func(t *testing.T) { - t.Parallel() ptty := ptytest.New(t) var buf bytes.Buffer // Copy all data written out to a buffer. When we close the ptty, we can // no longer read from the ptty.Output(), but we can read what was // written to the buffer. + dataRead, doneReading := context.WithTimeout(context.Background(), time.Second*2) go func() { - _, err := io.Copy(&buf, ptty.Output()) - require.NoError(t, err, "copy") + // This will throw an error sometimes. The underlying ptty + // has its own cleanup routines in t.Cleanup. Instead of + // trying to control the close perfectly, just let the ptty + // double close. This error isn't important, we just + // want to know the ptty is done sending output. + _, _ = io.Copy(&buf, ptty.Output()) + doneReading() }() doneChan := make(chan string) @@ -79,10 +84,14 @@ func TestPrompt(t *testing.T) { }() require.Equal(t, "yes", <-doneChan) - require.NoError(t, ptty.Close(), "close ptty") + // Close the reader to end the io.Copy + require.NoError(t, ptty.Close(), "close eof reader") + // Wait for the IO copy to finish + <-dataRead.Done() + // Timeout error means the output was hanging + require.ErrorIs(t, dataRead.Err(), context.Canceled, "should be cancelled") require.Len(t, buf.Bytes(), 0, "expect no output") }) - t.Run("JSON", func(t *testing.T) { t.Parallel() ptty := ptytest.New(t) @@ -104,7 +113,6 @@ func TestPrompt(t *testing.T) { ptty := ptytest.New(t) doneChan := make(chan string) go func() { - resp, err := newPrompt(ptty, cliui.PromptOptions{ Text: "Example", }, nil) From 843dd21daeae7f693ed889e4831e848577f8bf45 Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Thu, 19 May 2022 14:08:54 -0500 Subject: [PATCH 05/15] Add skip test for workspace create --- cli/create_test.go | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/cli/create_test.go b/cli/create_test.go index b9746df993196..c8b416c8f84f3 100644 --- a/cli/create_test.go +++ b/cli/create_test.go @@ -46,7 +46,7 @@ func TestCreate(t *testing.T) { <-doneChan }) - t.Run("CreateFromList", func(t *testing.T) { + t.Run("CreateFromListWithSkip", func(t *testing.T) { t.Parallel() client := coderdtest.New(t, nil) user := coderdtest.CreateFirstUser(t, client) @@ -54,7 +54,7 @@ func TestCreate(t *testing.T) { version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil) coderdtest.AwaitTemplateVersionJob(t, client, version.ID) _ = coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID) - cmd, root := clitest.New(t, "create", "my-workspace") + cmd, root := clitest.New(t, "create", "my-workspace", "-y") clitest.SetupConfig(t, client, root) doneChan := make(chan struct{}) pty := ptytest.New(t) @@ -65,15 +65,7 @@ func TestCreate(t *testing.T) { err := cmd.Execute() require.NoError(t, err) }() - matches := []string{ - "Confirm create", "yes", - } - for i := 0; i < len(matches); i += 2 { - match := matches[i] - value := matches[i+1] - pty.ExpectMatch(match) - pty.WriteLine(value) - } + // No pty interaction needed since we use the -y skip prompt flag <-doneChan }) From 9c09a084761a0032fab977d40671e82cabc88f0e Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Thu, 19 May 2022 14:53:29 -0500 Subject: [PATCH 06/15] Make test parallel --- cli/cliui/prompt_test.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cli/cliui/prompt_test.go b/cli/cliui/prompt_test.go index 4b83fe17449b5..d61c7d2eaabbd 100644 --- a/cli/cliui/prompt_test.go +++ b/cli/cliui/prompt_test.go @@ -53,6 +53,7 @@ func TestPrompt(t *testing.T) { }) t.Run("Skip", func(t *testing.T) { + t.Parallel() ptty := ptytest.New(t) var buf bytes.Buffer @@ -89,7 +90,7 @@ func TestPrompt(t *testing.T) { // Wait for the IO copy to finish <-dataRead.Done() // Timeout error means the output was hanging - require.ErrorIs(t, dataRead.Err(), context.Canceled, "should be cancelled") + require.ErrorIs(t, dataRead.Err(), context.Canceled, "should be canceled") require.Len(t, buf.Bytes(), 0, "expect no output") }) t.Run("JSON", func(t *testing.T) { From 6a4682a4d92de301255b0ef83921bcef59b7c999 Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Fri, 20 May 2022 08:42:50 -0500 Subject: [PATCH 07/15] Allow -y to template update --- cli/templateupdate.go | 1 + 1 file changed, 1 insertion(+) diff --git a/cli/templateupdate.go b/cli/templateupdate.go index 70c2611cea687..32902aab3b518 100644 --- a/cli/templateupdate.go +++ b/cli/templateupdate.go @@ -108,6 +108,7 @@ func templateUpdate() *cobra.Command { currentDirectory, _ := os.Getwd() cmd.Flags().StringVarP(&directory, "directory", "d", currentDirectory, "Specify the directory to create from") cmd.Flags().StringVarP(&provisioner, "test.provisioner", "", "terraform", "Customize the provisioner backend") + cliui.AllowSkipPrompt(cmd) // This is for testing! err := cmd.Flags().MarkHidden("test.provisioner") if err != nil { From e334b22b452405e42c0d0a5e50550787125f2d11 Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Fri, 20 May 2022 09:14:09 -0500 Subject: [PATCH 08/15] Fix delete test --- cli/delete_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/delete_test.go b/cli/delete_test.go index f9e1102a0eb39..e7af61b40cd82 100644 --- a/cli/delete_test.go +++ b/cli/delete_test.go @@ -20,7 +20,7 @@ func TestDelete(t *testing.T) { template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID) workspace := coderdtest.CreateWorkspace(t, client, user.OrganizationID, template.ID) coderdtest.AwaitWorkspaceBuildJob(t, client, workspace.LatestBuild.ID) - cmd, root := clitest.New(t, "delete", workspace.Name) + cmd, root := clitest.New(t, "delete", workspace.Name, "-y") clitest.SetupConfig(t, client, root) doneChan := make(chan struct{}) pty := ptytest.New(t) From 2ecf6649e40ef8ba01868497baa7ded67c365a98 Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Fri, 20 May 2022 10:01:46 -0500 Subject: [PATCH 09/15] Do not use deprecated function --- cli/cliui/prompt_test.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cli/cliui/prompt_test.go b/cli/cliui/prompt_test.go index d61c7d2eaabbd..9c9167ad09708 100644 --- a/cli/cliui/prompt_test.go +++ b/cli/cliui/prompt_test.go @@ -157,7 +157,8 @@ func newPrompt(ptty *ptytest.PTY, opts cliui.PromptOptions, cmdOpt func(cmd *cob if cmdOpt != nil { cmdOpt(cmd) } - cmd.SetOutput(ptty.Output()) + cmd.SetOut(ptty.Output()) + cmd.SetErr(ptty.Output()) cmd.SetIn(ptty.Input()) return value, cmd.ExecuteContext(context.Background()) } From e1b6bfb7e46186d470cf56e9d807ab6dfe70dfc7 Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Fri, 20 May 2022 10:17:15 -0500 Subject: [PATCH 10/15] Add timeout to cmd execute --- cli/create_test.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/cli/create_test.go b/cli/create_test.go index 84117155d8fba..3d2790536f007 100644 --- a/cli/create_test.go +++ b/cli/create_test.go @@ -1,8 +1,10 @@ package cli_test import ( + "context" "fmt" "testing" + "time" "github.com/stretchr/testify/require" @@ -59,8 +61,10 @@ func TestCreate(t *testing.T) { cmd.SetIn(pty.Input()) cmd.SetOut(pty.Output()) go func() { + ctx, cancel := context.WithTimeout(context.Background(), time.Second*3) + defer cancel() defer close(doneChan) - err := cmd.Execute() + err := cmd.ExecuteContext(ctx) require.NoError(t, err) }() // No pty interaction needed since we use the -y skip prompt flag From 0101e6d1be728d5a0aad2e948127a47320a8f007 Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Fri, 20 May 2022 10:29:03 -0500 Subject: [PATCH 11/15] revert test back to pre-skip --- cli/create_test.go | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/cli/create_test.go b/cli/create_test.go index 3d2790536f007..46b84d0bdbb3d 100644 --- a/cli/create_test.go +++ b/cli/create_test.go @@ -54,7 +54,7 @@ func TestCreate(t *testing.T) { version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil) coderdtest.AwaitTemplateVersionJob(t, client, version.ID) _ = coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID) - cmd, root := clitest.New(t, "create", "my-workspace", "-y") + cmd, root := clitest.New(t, "create", "my-workspace") clitest.SetupConfig(t, client, root) doneChan := make(chan struct{}) pty := ptytest.New(t) @@ -67,7 +67,15 @@ func TestCreate(t *testing.T) { err := cmd.ExecuteContext(ctx) require.NoError(t, err) }() - // No pty interaction needed since we use the -y skip prompt flag + matches := []string{ + "Confirm create", "yes", + } + for i := 0; i < len(matches); i += 2 { + match := matches[i] + value := matches[i+1] + pty.ExpectMatch(match) + pty.WriteLine(value) + } <-doneChan }) From d31fbc26eb3b9efe6b1655351dae21f1b6097b31 Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Fri, 20 May 2022 10:30:37 -0500 Subject: [PATCH 12/15] Remove set input --- cli/create_test.go | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/cli/create_test.go b/cli/create_test.go index 46b84d0bdbb3d..61801025bb217 100644 --- a/cli/create_test.go +++ b/cli/create_test.go @@ -54,11 +54,10 @@ func TestCreate(t *testing.T) { version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil) coderdtest.AwaitTemplateVersionJob(t, client, version.ID) _ = coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID) - cmd, root := clitest.New(t, "create", "my-workspace") + cmd, root := clitest.New(t, "create", "my-workspace", "-y") clitest.SetupConfig(t, client, root) doneChan := make(chan struct{}) pty := ptytest.New(t) - cmd.SetIn(pty.Input()) cmd.SetOut(pty.Output()) go func() { ctx, cancel := context.WithTimeout(context.Background(), time.Second*3) @@ -67,15 +66,7 @@ func TestCreate(t *testing.T) { err := cmd.ExecuteContext(ctx) require.NoError(t, err) }() - matches := []string{ - "Confirm create", "yes", - } - for i := 0; i < len(matches); i += 2 { - match := matches[i] - value := matches[i+1] - pty.ExpectMatch(match) - pty.WriteLine(value) - } + // No pty interaction needed since we use the -y skip prompt flag <-doneChan }) From bed1d44600d34ad7080e3cbda0038ffd43993773 Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Fri, 20 May 2022 10:33:00 -0500 Subject: [PATCH 13/15] Do not use ptty --- cli/create_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cli/create_test.go b/cli/create_test.go index 61801025bb217..6ea66d1ac1524 100644 --- a/cli/create_test.go +++ b/cli/create_test.go @@ -57,8 +57,8 @@ func TestCreate(t *testing.T) { cmd, root := clitest.New(t, "create", "my-workspace", "-y") clitest.SetupConfig(t, client, root) doneChan := make(chan struct{}) - pty := ptytest.New(t) - cmd.SetOut(pty.Output()) + //var output bytes.Buffer + //cmd.SetOut(&output) go func() { ctx, cancel := context.WithTimeout(context.Background(), time.Second*3) defer cancel() From 9d527bd3cc058376d42f796b572b5b25c3d12c18 Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Fri, 20 May 2022 10:45:39 -0500 Subject: [PATCH 14/15] use ctx over don channel --- cli/create_test.go | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/cli/create_test.go b/cli/create_test.go index 6ea66d1ac1524..cd466cafa98a5 100644 --- a/cli/create_test.go +++ b/cli/create_test.go @@ -56,18 +56,15 @@ func TestCreate(t *testing.T) { _ = coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID) cmd, root := clitest.New(t, "create", "my-workspace", "-y") clitest.SetupConfig(t, client, root) - doneChan := make(chan struct{}) - //var output bytes.Buffer - //cmd.SetOut(&output) + cmdCtx, done := context.WithTimeout(context.Background(), time.Second*3) go func() { - ctx, cancel := context.WithTimeout(context.Background(), time.Second*3) - defer cancel() - defer close(doneChan) - err := cmd.ExecuteContext(ctx) + defer done() + err := cmd.ExecuteContext(cmdCtx) require.NoError(t, err) }() // No pty interaction needed since we use the -y skip prompt flag - <-doneChan + <-cmdCtx.Done() + require.ErrorIs(t, cmdCtx.Err(), context.Canceled) }) t.Run("FromNothing", func(t *testing.T) { From 7cdb06e68087f08724657a548e1a08d4eef7f4b9 Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Fri, 20 May 2022 10:47:59 -0500 Subject: [PATCH 15/15] Remove unused flag --- cli/templatecreate.go | 1 - 1 file changed, 1 deletion(-) diff --git a/cli/templatecreate.go b/cli/templatecreate.go index aa84a0129db56..06205aa008eb2 100644 --- a/cli/templatecreate.go +++ b/cli/templatecreate.go @@ -21,7 +21,6 @@ import ( func templateCreate() *cobra.Command { var ( - yes bool directory string provisioner string parameterFile string pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy