From 6490f658de921f33e8b7b893f9a412325840b4f4 Mon Sep 17 00:00:00 2001 From: Amanda Lin Date: Tue, 5 Apr 2022 10:27:26 -0500 Subject: [PATCH 1/2] handle IdleTimeoutNotice --- internal/codespaces/api/api.go | 1 + pkg/cmd/codespace/create.go | 7 ++++- pkg/cmd/codespace/create_test.go | 48 ++++++++++++++++++++++++++++++++ 3 files changed, 55 insertions(+), 1 deletion(-) diff --git a/internal/codespaces/api/api.go b/internal/codespaces/api/api.go index 49b41b7e5..e151dfb54 100644 --- a/internal/codespaces/api/api.go +++ b/internal/codespaces/api/api.go @@ -183,6 +183,7 @@ type Codespace struct { VSCSTarget string `json:"vscs_target"` PendingOperation bool `json:"pending_operation"` PendingOperationDisabledReason string `json:"pending_operation_disabled_reason"` + IdleTimeoutNotice string `json:"idle_timeout_notice"` } type CodespaceGitStatus struct { diff --git a/pkg/cmd/codespace/create.go b/pkg/cmd/codespace/create.go index 81bb57bc4..312ccf61f 100644 --- a/pkg/cmd/codespace/create.go +++ b/pkg/cmd/codespace/create.go @@ -48,7 +48,6 @@ func newCreateCmd(app *App) *cobra.Command { // Create creates a new Codespace func (a *App) Create(ctx context.Context, opts createOptions) error { - // Overrides for Codespace developers to target test environments vscsLocation := os.Getenv("VSCS_LOCATION") vscsTarget := os.Getenv("VSCS_TARGET") @@ -153,7 +152,13 @@ func (a *App) Create(ctx context.Context, opts createOptions) error { } } + cs := a.io.ColorScheme() + fmt.Fprintln(a.io.Out, codespace.Name) + if codespace.IdleTimeoutNotice != "" { + fmt.Fprintln(a.io.Out, cs.Cyan("Notice:"), codespace.IdleTimeoutNotice) + } + return nil } diff --git a/pkg/cmd/codespace/create_test.go b/pkg/cmd/codespace/create_test.go index 2d417620d..a03aa0677 100644 --- a/pkg/cmd/codespace/create_test.go +++ b/pkg/cmd/codespace/create_test.go @@ -70,6 +70,54 @@ func TestApp_Create(t *testing.T) { }, wantStdout: "monalisa-dotfiles-abcd1234\n", }, + { + name: "create codespace with default branch shows idle timeout notice if present", + fields: fields{ + apiClient: &apiClientMock{ + GetCodespaceRegionLocationFunc: func(ctx context.Context) (string, error) { + return "EUROPE", nil + }, + GetRepositoryFunc: func(ctx context.Context, nwo string) (*api.Repository, error) { + return &api.Repository{ + ID: 1234, + FullName: nwo, + DefaultBranch: "main", + }, nil + }, + GetCodespacesMachinesFunc: func(ctx context.Context, repoID int, branch, location string) ([]*api.Machine, error) { + return []*api.Machine{ + { + Name: "GIGA", + DisplayName: "Gigabits of a machine", + }, + }, nil + }, + CreateCodespaceFunc: func(ctx context.Context, params *api.CreateCodespaceParams) (*api.Codespace, error) { + if params.Branch != "main" { + return nil, fmt.Errorf("got branch %q, want %q", params.Branch, "main") + } + if params.IdleTimeoutMinutes != 30 { + return nil, fmt.Errorf("idle timeout minutes was %v", params.IdleTimeoutMinutes) + } + return &api.Codespace{ + Name: "monalisa-dotfiles-abcd1234", + IdleTimeoutNotice: "Idle timeout for this codespace is set to 10 minutes in compliance with your organization's policy", + }, nil + }, + GetCodespaceRepoSuggestionsFunc: func(ctx context.Context, partialSearch string, params api.RepoSearchParameters) ([]string, error) { + return nil, nil // We can't ask for suggestions without a terminal. + }, + }, + }, + opts: createOptions{ + repo: "monalisa/dotfiles", + branch: "", + machine: "GIGA", + showStatus: false, + idleTimeout: 30 * time.Minute, + }, + wantStdout: "monalisa-dotfiles-abcd1234\nNotice: Idle timeout for this codespace is set to 10 minutes in compliance with your organization's policy\n", + }, { name: "create codespace that requires accepting additional permissions", fields: fields{ From 5b10b6e986b38fdbdbf1ada5526ea69d1464a0d9 Mon Sep 17 00:00:00 2001 From: Amanda Lin Date: Wed, 6 Apr 2022 09:57:36 -0500 Subject: [PATCH 2/2] use stderr instead and add tests --- pkg/cmd/codespace/create.go | 5 +-- pkg/cmd/codespace/create_test.go | 59 +++++++++++++++++++++++++++++++- 2 files changed, 61 insertions(+), 3 deletions(-) diff --git a/pkg/cmd/codespace/create.go b/pkg/cmd/codespace/create.go index 312ccf61f..f32b0fde9 100644 --- a/pkg/cmd/codespace/create.go +++ b/pkg/cmd/codespace/create.go @@ -155,8 +155,9 @@ func (a *App) Create(ctx context.Context, opts createOptions) error { cs := a.io.ColorScheme() fmt.Fprintln(a.io.Out, codespace.Name) - if codespace.IdleTimeoutNotice != "" { - fmt.Fprintln(a.io.Out, cs.Cyan("Notice:"), codespace.IdleTimeoutNotice) + + if a.io.IsStderrTTY() && codespace.IdleTimeoutNotice != "" { + fmt.Fprintln(a.io.ErrOut, cs.Yellow("Notice:"), codespace.IdleTimeoutNotice) } return nil diff --git a/pkg/cmd/codespace/create_test.go b/pkg/cmd/codespace/create_test.go index a03aa0677..0c2ff96bc 100644 --- a/pkg/cmd/codespace/create_test.go +++ b/pkg/cmd/codespace/create_test.go @@ -22,6 +22,7 @@ func TestApp_Create(t *testing.T) { wantErr error wantStdout string wantStderr string + isTTY bool }{ { name: "create codespace with default branch and 30m idle timeout", @@ -116,7 +117,59 @@ func TestApp_Create(t *testing.T) { showStatus: false, idleTimeout: 30 * time.Minute, }, - wantStdout: "monalisa-dotfiles-abcd1234\nNotice: Idle timeout for this codespace is set to 10 minutes in compliance with your organization's policy\n", + wantStdout: "monalisa-dotfiles-abcd1234\n", + wantStderr: "Notice: Idle timeout for this codespace is set to 10 minutes in compliance with your organization's policy\n", + isTTY: true, + }, + { + name: "create codespace with default branch does not show idle timeout notice if not conntected to terminal", + fields: fields{ + apiClient: &apiClientMock{ + GetCodespaceRegionLocationFunc: func(ctx context.Context) (string, error) { + return "EUROPE", nil + }, + GetRepositoryFunc: func(ctx context.Context, nwo string) (*api.Repository, error) { + return &api.Repository{ + ID: 1234, + FullName: nwo, + DefaultBranch: "main", + }, nil + }, + GetCodespacesMachinesFunc: func(ctx context.Context, repoID int, branch, location string) ([]*api.Machine, error) { + return []*api.Machine{ + { + Name: "GIGA", + DisplayName: "Gigabits of a machine", + }, + }, nil + }, + CreateCodespaceFunc: func(ctx context.Context, params *api.CreateCodespaceParams) (*api.Codespace, error) { + if params.Branch != "main" { + return nil, fmt.Errorf("got branch %q, want %q", params.Branch, "main") + } + if params.IdleTimeoutMinutes != 30 { + return nil, fmt.Errorf("idle timeout minutes was %v", params.IdleTimeoutMinutes) + } + return &api.Codespace{ + Name: "monalisa-dotfiles-abcd1234", + IdleTimeoutNotice: "Idle timeout for this codespace is set to 10 minutes in compliance with your organization's policy", + }, nil + }, + GetCodespaceRepoSuggestionsFunc: func(ctx context.Context, partialSearch string, params api.RepoSearchParameters) ([]string, error) { + return nil, nil // We can't ask for suggestions without a terminal. + }, + }, + }, + opts: createOptions{ + repo: "monalisa/dotfiles", + branch: "", + machine: "GIGA", + showStatus: false, + idleTimeout: 30 * time.Minute, + }, + wantStdout: "monalisa-dotfiles-abcd1234\n", + wantStderr: "", + isTTY: false, }, { name: "create codespace that requires accepting additional permissions", @@ -173,6 +226,10 @@ Alternatively, you can run "create" with the "--default-permissions" option to c for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { io, _, stdout, stderr := iostreams.Test() + io.SetStdoutTTY(tt.isTTY) + io.SetStdinTTY(tt.isTTY) + io.SetStderrTTY(tt.isTTY) + a := &App{ io: io, apiClient: tt.fields.apiClient,