From 3b7e5fc24678c8e6558ddd42c565f8280d73f8e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mislav=20Marohni=C4=87?= Date: Tue, 21 Dec 2021 14:03:10 +0100 Subject: [PATCH] Store Executable() information on codespaces App This is to avoid having to explicitly pass it to each subcommand that needs it. Each codespaces command runs in the context of App, so that's a point of shared context that we can store state in. --- pkg/cmd/codespace/common.go | 22 ++++++++++++++-------- pkg/cmd/codespace/delete_test.go | 2 +- pkg/cmd/codespace/root.go | 5 ++--- pkg/cmd/codespace/ssh.go | 13 +++++++------ pkg/cmd/root/root.go | 3 ++- 5 files changed, 26 insertions(+), 19 deletions(-) diff --git a/pkg/cmd/codespace/common.go b/pkg/cmd/codespace/common.go index 09b9308aa..1107ae6a5 100644 --- a/pkg/cmd/codespace/common.go +++ b/pkg/cmd/codespace/common.go @@ -21,19 +21,25 @@ import ( "golang.org/x/term" ) -type App struct { - io *iostreams.IOStreams - apiClient apiClient - errLogger *log.Logger +type executable interface { + Executable() string } -func NewApp(io *iostreams.IOStreams, apiClient apiClient) *App { +type App struct { + io *iostreams.IOStreams + apiClient apiClient + errLogger *log.Logger + executable executable +} + +func NewApp(io *iostreams.IOStreams, exe executable, apiClient apiClient) *App { errLogger := log.New(io.ErrOut, "", 0) return &App{ - io: io, - apiClient: apiClient, - errLogger: errLogger, + io: io, + apiClient: apiClient, + errLogger: errLogger, + executable: exe, } } diff --git a/pkg/cmd/codespace/delete_test.go b/pkg/cmd/codespace/delete_test.go index 58090c809..89318b5e3 100644 --- a/pkg/cmd/codespace/delete_test.go +++ b/pkg/cmd/codespace/delete_test.go @@ -190,7 +190,7 @@ func TestDelete(t *testing.T) { io, _, stdout, stderr := iostreams.Test() io.SetStdinTTY(true) io.SetStdoutTTY(true) - app := NewApp(io, apiMock) + app := NewApp(io, nil, apiMock) err := app.Delete(context.Background(), opts) if (err != nil) != tt.wantErr { t.Errorf("delete() error = %v, wantErr %v", err, tt.wantErr) diff --git a/pkg/cmd/codespace/root.go b/pkg/cmd/codespace/root.go index 5a3499dee..5b2c0d8fc 100644 --- a/pkg/cmd/codespace/root.go +++ b/pkg/cmd/codespace/root.go @@ -1,11 +1,10 @@ package codespace import ( - "github.com/cli/cli/v2/pkg/cmdutil" "github.com/spf13/cobra" ) -func NewRootCmd(app *App, f *cmdutil.Factory) *cobra.Command { +func NewRootCmd(app *App) *cobra.Command { root := &cobra.Command{ Use: "codespace", Short: "Connect to and manage your codespaces", @@ -17,7 +16,7 @@ func NewRootCmd(app *App, f *cmdutil.Factory) *cobra.Command { root.AddCommand(newListCmd(app)) root.AddCommand(newLogsCmd(app)) root.AddCommand(newPortsCmd(app)) - root.AddCommand(newSSHCmd(app, f)) + root.AddCommand(newSSHCmd(app)) root.AddCommand(newCpCmd(app)) root.AddCommand(newStopCmd(app)) diff --git a/pkg/cmd/codespace/ssh.go b/pkg/cmd/codespace/ssh.go index 18730a176..19c4930f5 100644 --- a/pkg/cmd/codespace/ssh.go +++ b/pkg/cmd/codespace/ssh.go @@ -34,7 +34,7 @@ type sshOptions struct { scpArgs []string // scp arguments, for 'cs cp' (nil for 'cs ssh') } -func newSSHCmd(app *App, f *cmdutil.Factory) *cobra.Command { +func newSSHCmd(app *App) *cobra.Command { var opts sshOptions sshCmd := &cobra.Command{ @@ -70,7 +70,7 @@ func newSSHCmd(app *App, f *cmdutil.Factory) *cobra.Command { fmt.Fprintf(os.Stderr, "%v\n", err) } - sshCmd.AddCommand(newConfigCmd(app, f)) + sshCmd.AddCommand(newConfigCmd(app)) return sshCmd } @@ -174,7 +174,7 @@ func (a *App) SSH(ctx context.Context, sshArgs []string, opts sshOptions) (err e } } -func (a *App) printOpenSSHConfig(ctx context.Context, opts configOptions, executable string) error { +func (a *App) printOpenSSHConfig(ctx context.Context, opts configOptions) error { ctx, cancel := context.WithCancel(ctx) defer cancel() @@ -258,6 +258,7 @@ func (a *App) printOpenSSHConfig(ctx context.Context, opts configOptions, execut return fmt.Errorf("error formatting template: %w", err) } + ghExec := a.executable.Executable() for result := range sshUsers { if result.err != nil { fmt.Fprintf(os.Stderr, "%v\n", result.err) @@ -287,7 +288,7 @@ func (a *App) printOpenSSHConfig(ctx context.Context, opts configOptions, execut Name: result.codespace.Name, EscapedRef: strings.ReplaceAll(result.codespace.GitStatus.Ref, "/", "-"), SSHUser: result.user, - GHExec: executable, + GHExec: ghExec, } if err := t.Execute(a.io.Out, conf); err != nil { return err @@ -392,7 +393,7 @@ type configOptions struct { codespace string } -func newConfigCmd(app *App, f *cmdutil.Factory) *cobra.Command { +func newConfigCmd(app *App) *cobra.Command { var opts configOptions configCmd := &cobra.Command{ @@ -418,7 +419,7 @@ func newConfigCmd(app *App, f *cmdutil.Factory) *cobra.Command { $ echo 'include ~/.ssh/codespaces' >> ~/.ssh/config' `), RunE: func(cmd *cobra.Command, args []string) error { - return app.printOpenSSHConfig(cmd.Context(), opts, f.Executable()) + return app.printOpenSSHConfig(cmd.Context(), opts) }, DisableFlagsInUseLine: true, } diff --git a/pkg/cmd/root/root.go b/pkg/cmd/root/root.go index 58272306c..cff797e93 100644 --- a/pkg/cmd/root/root.go +++ b/pkg/cmd/root/root.go @@ -135,6 +135,7 @@ func newCodespaceCmd(f *cmdutil.Factory) *cobra.Command { vscsURL := os.Getenv("INTERNAL_VSCS_TARGET_URL") app := codespaceCmd.NewApp( f.IOStreams, + f, codespacesAPI.New( serverURL, apiURL, @@ -142,7 +143,7 @@ func newCodespaceCmd(f *cmdutil.Factory) *cobra.Command { &lazyLoadedHTTPClient{factory: f}, ), ) - cmd := codespaceCmd.NewRootCmd(app, f) + cmd := codespaceCmd.NewRootCmd(app) cmd.Use = "codespace" cmd.Aliases = []string{"cs"} cmd.Annotations = map[string]string{"IsCore": "true"}