diff --git a/pkg/cmdutil/prompt.go b/internal/prompter/prompter.go similarity index 86% rename from pkg/cmdutil/prompt.go rename to internal/prompter/prompter.go index 9b9354b2c..6b89867b6 100644 --- a/pkg/cmdutil/prompt.go +++ b/internal/prompter/prompter.go @@ -1,4 +1,4 @@ -package cmdutil +package prompter import ( "fmt" @@ -10,6 +10,18 @@ import ( "github.com/cli/cli/v2/pkg/surveyext" ) +//go:generate moq -rm -out prompter_mock.go . Prompter +type Prompter interface { + Select(string, string, []string) (int, error) + MultiSelect(string, string, []string) (int, error) + Input(string, string) (string, error) + InputHostname() (string, error) + Password(string) (string, error) + AuthToken() (string, error) + Confirm(string, bool) (bool, error) + MarkdownEditor(string, string, bool) (string, error) +} + func NewPrompter(editorCmd string, stdin io.Reader, stdout, stderr io.Writer) Prompter { return &surveyPrompter{ editorCmd: editorCmd, diff --git a/pkg/cmdutil/prompter_mock.go b/internal/prompter/prompter_mock.go similarity index 99% rename from pkg/cmdutil/prompter_mock.go rename to internal/prompter/prompter_mock.go index e2fcd339e..eea5393b2 100644 --- a/pkg/cmdutil/prompter_mock.go +++ b/internal/prompter/prompter_mock.go @@ -1,7 +1,7 @@ // Code generated by moq; DO NOT EDIT. // github.com/matryer/moq -package cmdutil +package prompter import ( "sync" diff --git a/pkg/cmd/auth/login/login.go b/pkg/cmd/auth/login/login.go index 937b72a2e..06cdb59a9 100644 --- a/pkg/cmd/auth/login/login.go +++ b/pkg/cmd/auth/login/login.go @@ -9,6 +9,7 @@ import ( "github.com/MakeNowJust/heredoc" "github.com/cli/cli/v2/internal/config" "github.com/cli/cli/v2/internal/ghinstance" + "github.com/cli/cli/v2/internal/prompter" "github.com/cli/cli/v2/pkg/cmd/auth/shared" "github.com/cli/cli/v2/pkg/cmdutil" "github.com/cli/cli/v2/pkg/iostreams" @@ -19,7 +20,7 @@ type LoginOptions struct { IO *iostreams.IOStreams Config func() (config.Config, error) HttpClient func() (*http.Client, error) - Prompter cmdutil.Prompter + Prompter prompter.Prompter MainExecutable string diff --git a/pkg/cmd/auth/login/login_test.go b/pkg/cmd/auth/login/login_test.go index 28bac297b..c05d9b9de 100644 --- a/pkg/cmd/auth/login/login_test.go +++ b/pkg/cmd/auth/login/login_test.go @@ -10,6 +10,7 @@ import ( "github.com/MakeNowJust/heredoc" "github.com/cli/cli/v2/internal/config" + "github.com/cli/cli/v2/internal/prompter" "github.com/cli/cli/v2/internal/run" "github.com/cli/cli/v2/pkg/cmdutil" "github.com/cli/cli/v2/pkg/httpmock" @@ -364,7 +365,7 @@ func Test_loginRun_Survey(t *testing.T) { name string opts *LoginOptions httpStubs func(*httpmock.Registry) - prompterStubs func(*cmdutil.PrompterMock) + prompterStubs func(*prompter.PrompterMock) runStubs func(*run.CommandStubber) wantHosts string wantErrOut *regexp.Regexp @@ -383,7 +384,7 @@ func Test_loginRun_Survey(t *testing.T) { httpStubs: func(reg *httpmock.Registry) { reg.Register(httpmock.REST("GET", ""), httpmock.ScopesResponder("repo,read:org")) }, - prompterStubs: func(pm *cmdutil.PrompterMock) { + prompterStubs: func(pm *prompter.PrompterMock) { pm.SelectFunc = func(_, _ string, _ []string) (int, error) { return 0, nil } @@ -403,7 +404,7 @@ func Test_loginRun_Survey(t *testing.T) { user: jillv git_protocol: https `), - prompterStubs: func(pm *cmdutil.PrompterMock) { + prompterStubs: func(pm *prompter.PrompterMock) { pm.SelectFunc = func(prompt, _ string, _ []string) (int, error) { switch prompt { case "What is your preferred protocol for Git operations?": @@ -437,7 +438,7 @@ func Test_loginRun_Survey(t *testing.T) { opts: &LoginOptions{ Interactive: true, }, - prompterStubs: func(pm *cmdutil.PrompterMock) { + prompterStubs: func(pm *prompter.PrompterMock) { pm.SelectFunc = func(prompt, _ string, _ []string) (int, error) { switch prompt { case "What account do you want to log into?": @@ -476,7 +477,7 @@ func Test_loginRun_Survey(t *testing.T) { opts: &LoginOptions{ Interactive: true, }, - prompterStubs: func(pm *cmdutil.PrompterMock) { + prompterStubs: func(pm *prompter.PrompterMock) { pm.SelectFunc = func(prompt, _ string, _ []string) (int, error) { switch prompt { case "What account do you want to log into?": @@ -506,7 +507,7 @@ func Test_loginRun_Survey(t *testing.T) { opts: &LoginOptions{ Interactive: true, }, - prompterStubs: func(pm *cmdutil.PrompterMock) { + prompterStubs: func(pm *prompter.PrompterMock) { pm.SelectFunc = func(prompt, _ string, _ []string) (int, error) { switch prompt { case "What account do you want to log into?": @@ -560,7 +561,7 @@ func Test_loginRun_Survey(t *testing.T) { httpmock.StringResponse(`{"data":{"viewer":{"login":"jillv"}}}`)) } - pm := &cmdutil.PrompterMock{} + pm := &prompter.PrompterMock{} pm.ConfirmFunc = func(_ string, _ bool) (bool, error) { return false, nil } diff --git a/pkg/cmd/auth/shared/git_credential.go b/pkg/cmd/auth/shared/git_credential.go index 22a68da6b..e6cbe3c29 100644 --- a/pkg/cmd/auth/shared/git_credential.go +++ b/pkg/cmd/auth/shared/git_credential.go @@ -10,14 +10,14 @@ import ( "github.com/MakeNowJust/heredoc" "github.com/cli/cli/v2/git" "github.com/cli/cli/v2/internal/ghinstance" + "github.com/cli/cli/v2/internal/prompter" "github.com/cli/cli/v2/internal/run" - "github.com/cli/cli/v2/pkg/cmdutil" "github.com/google/shlex" ) type GitCredentialFlow struct { Executable string - Prompter cmdutil.Prompter + Prompter prompter.Prompter shouldSetup bool helper string diff --git a/pkg/cmd/auth/shared/login_flow.go b/pkg/cmd/auth/shared/login_flow.go index 590fb242d..373cc299d 100644 --- a/pkg/cmd/auth/shared/login_flow.go +++ b/pkg/cmd/auth/shared/login_flow.go @@ -10,8 +10,8 @@ import ( "github.com/cli/cli/v2/api" "github.com/cli/cli/v2/internal/authflow" "github.com/cli/cli/v2/internal/ghinstance" + "github.com/cli/cli/v2/internal/prompter" "github.com/cli/cli/v2/pkg/cmd/ssh-key/add" - "github.com/cli/cli/v2/pkg/cmdutil" "github.com/cli/cli/v2/pkg/iostreams" "github.com/cli/cli/v2/pkg/ssh" ) @@ -34,7 +34,7 @@ type LoginOptions struct { Scopes []string Executable string GitProtocol string - Prompter cmdutil.Prompter + Prompter prompter.Prompter sshContext ssh.Context } diff --git a/pkg/cmd/auth/shared/login_flow_test.go b/pkg/cmd/auth/shared/login_flow_test.go index 27db56bad..8bcecfc6a 100644 --- a/pkg/cmd/auth/shared/login_flow_test.go +++ b/pkg/cmd/auth/shared/login_flow_test.go @@ -8,8 +8,8 @@ import ( "testing" "github.com/MakeNowJust/heredoc" + "github.com/cli/cli/v2/internal/prompter" "github.com/cli/cli/v2/internal/run" - "github.com/cli/cli/v2/pkg/cmdutil" "github.com/cli/cli/v2/pkg/httpmock" "github.com/cli/cli/v2/pkg/iostreams" "github.com/cli/cli/v2/pkg/ssh" @@ -47,7 +47,7 @@ func TestLogin_ssh(t *testing.T) { httpmock.REST("POST", "api/v3/user/keys"), httpmock.StringResponse(`{}`)) - pm := &cmdutil.PrompterMock{} + pm := &prompter.PrompterMock{} pm.SelectFunc = func(prompt, _ string, _ []string) (int, error) { switch prompt { case "What is your preferred protocol for Git operations?": diff --git a/pkg/cmd/extension/command_test.go b/pkg/cmd/extension/command_test.go index 6d1090d5c..8cdb45d45 100644 --- a/pkg/cmd/extension/command_test.go +++ b/pkg/cmd/extension/command_test.go @@ -12,6 +12,7 @@ import ( "github.com/MakeNowJust/heredoc" "github.com/cli/cli/v2/internal/config" "github.com/cli/cli/v2/internal/ghrepo" + "github.com/cli/cli/v2/internal/prompter" "github.com/cli/cli/v2/pkg/cmdutil" "github.com/cli/cli/v2/pkg/extensions" "github.com/cli/cli/v2/pkg/httpmock" @@ -30,7 +31,7 @@ func TestNewCmdExtension(t *testing.T) { name string args []string managerStubs func(em *extensions.ExtensionManagerMock) func(*testing.T) - prompterStubs func(pm *cmdutil.PrompterMock) + prompterStubs func(pm *prompter.PrompterMock) isTTY bool wantErr bool errMsg string @@ -386,7 +387,7 @@ func TestNewCmdExtension(t *testing.T) { } }, isTTY: true, - prompterStubs: func(pm *cmdutil.PrompterMock) { + prompterStubs: func(pm *prompter.PrompterMock) { pm.InputFunc = func(prompt, defVal string) (string, error) { if prompt == "Extension name:" { return "test", nil @@ -566,7 +567,7 @@ func TestNewCmdExtension(t *testing.T) { assertFunc = tt.managerStubs(em) } - pm := &cmdutil.PrompterMock{} + pm := &prompter.PrompterMock{} if tt.prompterStubs != nil { tt.prompterStubs(pm) } diff --git a/pkg/cmd/factory/default.go b/pkg/cmd/factory/default.go index 8c0cd06b9..5cfa82701 100644 --- a/pkg/cmd/factory/default.go +++ b/pkg/cmd/factory/default.go @@ -12,6 +12,7 @@ import ( "github.com/cli/cli/v2/git" "github.com/cli/cli/v2/internal/config" "github.com/cli/cli/v2/internal/ghrepo" + "github.com/cli/cli/v2/internal/prompter" "github.com/cli/cli/v2/pkg/cmd/extension" "github.com/cli/cli/v2/pkg/cmdutil" "github.com/cli/cli/v2/pkg/iostreams" @@ -31,7 +32,7 @@ func New(appVersion string) *cmdutil.Factory { f.HttpClient = httpClientFunc(f, appVersion) // Depends on Config, IOStreams, and appVersion f.Remotes = remotesFunc(f) // Depends on Config f.BaseRepo = BaseRepoFunc(f) // Depends on Remotes - f.Prompter = prompter(f) // Depends on Config and IOStreams + f.Prompter = newPrompter(f) // Depends on Config and IOStreams f.Browser = browser(f) // Depends on Config, and IOStreams f.ExtensionManager = extensionManager(f) // Depends on Config, HttpClient, and IOStreams @@ -108,10 +109,10 @@ func browser(f *cmdutil.Factory) cmdutil.Browser { return cmdutil.NewBrowser(browserLauncher(f), io.Out, io.ErrOut) } -func prompter(f *cmdutil.Factory) cmdutil.Prompter { +func newPrompter(f *cmdutil.Factory) prompter.Prompter { editor, _ := cmdutil.DetermineEditor(f.Config) io := f.IOStreams - return cmdutil.NewPrompter(editor, io.In, io.Out, io.ErrOut) + return prompter.NewPrompter(editor, io.In, io.Out, io.ErrOut) } // Browser precedence diff --git a/pkg/cmd/pr/review/review.go b/pkg/cmd/pr/review/review.go index 7549fe921..0d65cffa2 100644 --- a/pkg/cmd/pr/review/review.go +++ b/pkg/cmd/pr/review/review.go @@ -8,6 +8,7 @@ import ( "github.com/MakeNowJust/heredoc" "github.com/cli/cli/v2/api" "github.com/cli/cli/v2/internal/config" + "github.com/cli/cli/v2/internal/prompter" "github.com/cli/cli/v2/pkg/cmd/pr/shared" "github.com/cli/cli/v2/pkg/cmdutil" "github.com/cli/cli/v2/pkg/iostreams" @@ -19,7 +20,7 @@ type ReviewOptions struct { HttpClient func() (*http.Client, error) Config func() (config.Config, error) IO *iostreams.IOStreams - Prompter cmdutil.Prompter + Prompter prompter.Prompter Finder shared.PRFinder diff --git a/pkg/cmd/pr/review/review_test.go b/pkg/cmd/pr/review/review_test.go index ab41af9fb..9d1ad6ff9 100644 --- a/pkg/cmd/pr/review/review_test.go +++ b/pkg/cmd/pr/review/review_test.go @@ -14,6 +14,7 @@ import ( "github.com/cli/cli/v2/context" "github.com/cli/cli/v2/internal/config" "github.com/cli/cli/v2/internal/ghrepo" + "github.com/cli/cli/v2/internal/prompter" "github.com/cli/cli/v2/pkg/cmd/pr/shared" "github.com/cli/cli/v2/pkg/cmdutil" "github.com/cli/cli/v2/pkg/httpmock" @@ -165,7 +166,7 @@ func Test_NewCmdReview(t *testing.T) { } } -func runCommand(rt http.RoundTripper, prompter cmdutil.Prompter, remotes context.Remotes, isTTY bool, cli string) (*test.CmdOut, error) { +func runCommand(rt http.RoundTripper, prompter prompter.Prompter, remotes context.Remotes, isTTY bool, cli string) (*test.CmdOut, error) { ios, _, stdout, stderr := iostreams.Test() ios.SetStdoutTTY(isTTY) ios.SetStdinTTY(isTTY) @@ -271,7 +272,7 @@ func TestPRReview_interactive(t *testing.T) { }), ) - pm := &cmdutil.PrompterMock{ + pm := &prompter.PrompterMock{ SelectFunc: func(_, _ string, _ []string) (int, error) { return 1, nil }, MarkdownEditorFunc: func(_, _ string, _ bool) (string, error) { return "cool story", nil }, ConfirmFunc: func(_ string, _ bool) (bool, error) { return true, nil }, @@ -294,7 +295,7 @@ func TestPRReview_interactive_no_body(t *testing.T) { shared.RunCommandFinder("", &api.PullRequest{ID: "THE-ID", Number: 123}, ghrepo.New("OWNER", "REPO")) - pm := &cmdutil.PrompterMock{ + pm := &prompter.PrompterMock{ SelectFunc: func(_, _ string, _ []string) (int, error) { return 2, nil }, MarkdownEditorFunc: func(_, _ string, _ bool) (string, error) { return "", nil }, } @@ -318,7 +319,7 @@ func TestPRReview_interactive_blank_approve(t *testing.T) { }), ) - pm := &cmdutil.PrompterMock{ + pm := &prompter.PrompterMock{ SelectFunc: func(_, _ string, _ []string) (int, error) { return 1, nil }, MarkdownEditorFunc: func(_, defVal string, _ bool) (string, error) { return defVal, nil }, ConfirmFunc: func(_ string, _ bool) (bool, error) { return true, nil }, diff --git a/pkg/cmd/repo/delete/delete.go b/pkg/cmd/repo/delete/delete.go index 34e58780c..9e1d6d1d8 100644 --- a/pkg/cmd/repo/delete/delete.go +++ b/pkg/cmd/repo/delete/delete.go @@ -8,6 +8,7 @@ import ( "github.com/cli/cli/v2/api" "github.com/cli/cli/v2/internal/ghinstance" "github.com/cli/cli/v2/internal/ghrepo" + "github.com/cli/cli/v2/internal/prompter" "github.com/cli/cli/v2/pkg/cmdutil" "github.com/cli/cli/v2/pkg/iostreams" @@ -17,7 +18,7 @@ import ( type DeleteOptions struct { HttpClient func() (*http.Client, error) BaseRepo func() (ghrepo.Interface, error) - Prompter cmdutil.Prompter + Prompter prompter.Prompter IO *iostreams.IOStreams RepoArg string Confirmed bool diff --git a/pkg/cmd/repo/delete/delete_test.go b/pkg/cmd/repo/delete/delete_test.go index 7dc443aac..a49bbff4f 100644 --- a/pkg/cmd/repo/delete/delete_test.go +++ b/pkg/cmd/repo/delete/delete_test.go @@ -6,6 +6,7 @@ import ( "testing" "github.com/cli/cli/v2/internal/ghrepo" + "github.com/cli/cli/v2/internal/prompter" "github.com/cli/cli/v2/pkg/cmdutil" "github.com/cli/cli/v2/pkg/httpmock" "github.com/cli/cli/v2/pkg/iostreams" @@ -80,7 +81,7 @@ func Test_deleteRun(t *testing.T) { tty bool opts *DeleteOptions httpStubs func(*httpmock.Registry) - prompterStubs func(*cmdutil.PrompterMock) + prompterStubs func(*prompter.PrompterMock) wantStdout string wantErr bool errMsg string @@ -90,7 +91,7 @@ func Test_deleteRun(t *testing.T) { tty: true, opts: &DeleteOptions{RepoArg: "OWNER/REPO"}, wantStdout: "✓ Deleted repository OWNER/REPO\n", - prompterStubs: func(p *cmdutil.PrompterMock) { + prompterStubs: func(p *prompter.PrompterMock) { p.InputFunc = func(_, _ string) (string, error) { return "OWNER/REPO", nil } @@ -106,7 +107,7 @@ func Test_deleteRun(t *testing.T) { tty: true, opts: &DeleteOptions{}, wantStdout: "✓ Deleted repository OWNER/REPO\n", - prompterStubs: func(p *cmdutil.PrompterMock) { + prompterStubs: func(p *prompter.PrompterMock) { p.InputFunc = func(_, _ string) (string, error) { return "OWNER/REPO", nil } @@ -134,7 +135,7 @@ func Test_deleteRun(t *testing.T) { opts: &DeleteOptions{RepoArg: "REPO"}, wantStdout: "✓ Deleted repository OWNER/REPO\n", tty: true, - prompterStubs: func(p *cmdutil.PrompterMock) { + prompterStubs: func(p *prompter.PrompterMock) { p.InputFunc = func(_, _ string) (string, error) { return "OWNER/REPO", nil } @@ -150,7 +151,7 @@ func Test_deleteRun(t *testing.T) { }, } for _, tt := range tests { - pm := &cmdutil.PrompterMock{} + pm := &prompter.PrompterMock{} if tt.prompterStubs != nil { tt.prompterStubs(pm) } diff --git a/pkg/cmdutil/factory.go b/pkg/cmdutil/factory.go index bace0dfd6..3f3f0de0e 100644 --- a/pkg/cmdutil/factory.go +++ b/pkg/cmdutil/factory.go @@ -9,6 +9,7 @@ import ( "github.com/cli/cli/v2/context" "github.com/cli/cli/v2/internal/config" "github.com/cli/cli/v2/internal/ghrepo" + "github.com/cli/cli/v2/internal/prompter" "github.com/cli/cli/v2/pkg/extensions" "github.com/cli/cli/v2/pkg/iostreams" ) @@ -17,25 +18,10 @@ type Browser interface { Browse(string) error } -// TODO fix current breaking tests -// TODO linter warning for using the prompt package - -//go:generate moq -rm -out prompter_mock.go . Prompter -type Prompter interface { - Select(string, string, []string) (int, error) - MultiSelect(string, string, []string) (int, error) - Input(string, string) (string, error) - InputHostname() (string, error) - Password(string) (string, error) - AuthToken() (string, error) - Confirm(string, bool) (bool, error) - MarkdownEditor(string, string, bool) (string, error) -} - type Factory struct { IOStreams *iostreams.IOStreams Browser Browser - Prompter Prompter + Prompter prompter.Prompter HttpClient func() (*http.Client, error) BaseRepo func() (ghrepo.Interface, error)