From 4b64a4689177446e966d1cc6c35520d854af8d15 Mon Sep 17 00:00:00 2001 From: ShubhankarKG Date: Tue, 4 Aug 2020 19:24:35 +0530 Subject: [PATCH] Add confirmation for risky step for repo create --- pkg/cmd/repo/create/create.go | 164 ++++++++++++++++++----------- pkg/cmd/repo/create/create_test.go | 31 ++++++ 2 files changed, 135 insertions(+), 60 deletions(-) diff --git a/pkg/cmd/repo/create/create.go b/pkg/cmd/repo/create/create.go index 313f9a91e..470e50467 100644 --- a/pkg/cmd/repo/create/create.go +++ b/pkg/cmd/repo/create/create.go @@ -6,6 +6,7 @@ import ( "path" "strings" + "github.com/AlecAivazis/survey/v2" "github.com/MakeNowJust/heredoc" "github.com/cli/cli/git" "github.com/cli/cli/internal/config" @@ -23,13 +24,14 @@ type CreateOptions struct { Config func() (config.Config, error) IO *iostreams.IOStreams - Name string - Description string - Homepage string - Team string - EnableIssues bool - EnableWiki bool - Public bool + Name string + Description string + Homepage string + Team string + EnableIssues bool + EnableWiki bool + Public bool + ConfirmSubmit bool } func NewCmdCreate(f *cmdutil.Factory, runF func(*CreateOptions) error) *cobra.Command { @@ -79,6 +81,7 @@ func NewCmdCreate(f *cmdutil.Factory, runF func(*CreateOptions) error) *cobra.Co cmd.Flags().BoolVar(&opts.EnableIssues, "enable-issues", true, "Enable issues in the new repository") cmd.Flags().BoolVar(&opts.EnableWiki, "enable-wiki", true, "Enable wiki in the new repository") cmd.Flags().BoolVar(&opts.Public, "public", false, "Make the new repository public (default: private)") + cmd.Flags().BoolVarP(&opts.ConfirmSubmit, "confirm", "y", false, "Confirm the submission directly") return cmd } @@ -126,68 +129,109 @@ func createRun(opts *CreateOptions) error { return err } - repo, err := repoCreate(httpClient, input) - if err != nil { - return err - } - - stderr := opts.IO.ErrOut - stdout := opts.IO.Out - greenCheck := utils.Green("✓") - isTTY := opts.IO.IsStdoutTTY() - - if isTTY { - fmt.Fprintf(stderr, "%s Created repository %s on GitHub\n", greenCheck, ghrepo.FullName(repo)) - } else { - fmt.Fprintln(stdout, repo.URL) - } - - // TODO This is overly wordy and I'd like to streamline this. - cfg, err := opts.Config() - if err != nil { - return err - } - protocol, err := cfg.Get("", "git_protocol") - if err != nil { - return err - } - remoteURL := ghrepo.FormatRemoteURL(repo, protocol) - - if projectDirErr == nil { - _, err = git.AddRemote("origin", remoteURL) + if !opts.ConfirmSubmit { + opts.ConfirmSubmit, err = confirmSubmission(input.Name, input.OwnerID, &opts.ConfirmSubmit) if err != nil { return err } + } + + if opts.ConfirmSubmit { + repo, err := repoCreate(httpClient, input) + if err != nil { + return err + } + + stderr := opts.IO.ErrOut + stdout := opts.IO.Out + greenCheck := utils.Green("✓") + isTTY := opts.IO.IsStdoutTTY() + if isTTY { - fmt.Fprintf(stderr, "%s Added remote %s\n", greenCheck, remoteURL) + fmt.Fprintf(stderr, "%s Created repository %s on GitHub\n", greenCheck, ghrepo.FullName(repo)) + } else { + fmt.Fprintln(stdout, repo.URL) } - } else if isTTY { - doSetup := false - err := prompt.Confirm(fmt.Sprintf("Create a local project directory for %s?", ghrepo.FullName(repo)), &doSetup) + + // TODO This is overly wordy and I'd like to streamline this. + cfg, err := opts.Config() if err != nil { return err } - - if doSetup { - path := repo.Name - - gitInit := git.GitCommand("init", path) - gitInit.Stdout = stdout - gitInit.Stderr = stderr - err = run.PrepareCmd(gitInit).Run() - if err != nil { - return err - } - gitRemoteAdd := git.GitCommand("-C", path, "remote", "add", "origin", remoteURL) - gitRemoteAdd.Stdout = stdout - gitRemoteAdd.Stderr = stderr - err = run.PrepareCmd(gitRemoteAdd).Run() - if err != nil { - return err - } - - fmt.Fprintf(stderr, "%s Initialized repository in './%s/'\n", greenCheck, path) + protocol, err := cfg.Get("", "git_protocol") + if err != nil { + return err } + remoteURL := ghrepo.FormatRemoteURL(repo, protocol) + + if projectDirErr == nil { + _, err = git.AddRemote("origin", remoteURL) + if err != nil { + return err + } + if isTTY { + fmt.Fprintf(stderr, "%s Added remote %s\n", greenCheck, remoteURL) + } + } else if isTTY { + doSetup := false + err := prompt.Confirm(fmt.Sprintf("Create a local project directory for %s?", ghrepo.FullName(repo)), &doSetup) + if err != nil { + return err + } + + if doSetup { + path := repo.Name + + gitInit := git.GitCommand("init", path) + gitInit.Stdout = stdout + gitInit.Stderr = stderr + err = run.PrepareCmd(gitInit).Run() + if err != nil { + return err + } + gitRemoteAdd := git.GitCommand("-C", path, "remote", "add", "origin", remoteURL) + gitRemoteAdd.Stdout = stdout + gitRemoteAdd.Stderr = stderr + err = run.PrepareCmd(gitRemoteAdd).Run() + if err != nil { + return err + } + + fmt.Fprintf(stderr, "%s Initialized repository in './%s/'\n", greenCheck, path) + } + } + return nil } + fmt.Fprintln(opts.IO.Out, "Discarding...") return nil } + +func confirmSubmission(repoName string, repoOwner string, isConfirmFlagPassed *bool) (bool, error) { + qs := []*survey.Question{} + + promptString := "" + if repoOwner != "" { + promptString = fmt.Sprintf("This will create %s/%s in your current directory. Continue? ", repoOwner, repoName) + } else { + promptString = fmt.Sprintf("This will create %s in your current directory. Continue? ", repoName) + } + + confirmSubmitQuestion := &survey.Question{ + Name: "confirmSubmit", + Prompt: &survey.Confirm{ + Message: promptString, + }, + } + qs = append(qs, confirmSubmitQuestion) + + answer := struct { + ConfirmSubmit bool + }{} + + err := prompt.SurveyAsk(qs, &answer) + if err != nil { + return false, err + } + + return answer.ConfirmSubmit, nil +} diff --git a/pkg/cmd/repo/create/create_test.go b/pkg/cmd/repo/create/create_test.go index d33ad5d25..dd7c5d2b5 100644 --- a/pkg/cmd/repo/create/create_test.go +++ b/pkg/cmd/repo/create/create_test.go @@ -14,6 +14,7 @@ import ( "github.com/cli/cli/pkg/cmdutil" "github.com/cli/cli/pkg/httpmock" "github.com/cli/cli/pkg/iostreams" + "github.com/cli/cli/pkg/prompt" "github.com/cli/cli/test" "github.com/google/shlex" "github.com/stretchr/testify/assert" @@ -87,6 +88,16 @@ func TestRepoCreate(t *testing.T) { }) defer restoreCmd() + as, surveyTearDown := prompt.InitAskStubber() + defer surveyTearDown() + + as.Stub([]*prompt.QuestionStub{ + { + Name: "confirmSubmit", + Value: true, + }, + }) + output, err := runCommand(httpClient, "REPO") if err != nil { t.Errorf("error running command `repo create`: %v", err) @@ -153,6 +164,16 @@ func TestRepoCreate_org(t *testing.T) { }) defer restoreCmd() + as, surveyTearDown := prompt.InitAskStubber() + defer surveyTearDown() + + as.Stub([]*prompt.QuestionStub{ + { + Name: "confirmSubmit", + Value: true, + }, + }) + output, err := runCommand(httpClient, "ORG/REPO") if err != nil { t.Errorf("error running command `repo create`: %v", err) @@ -219,6 +240,16 @@ func TestRepoCreate_orgWithTeam(t *testing.T) { }) defer restoreCmd() + as, surveyTearDown := prompt.InitAskStubber() + defer surveyTearDown() + + as.Stub([]*prompt.QuestionStub{ + { + Name: "confirmSubmit", + Value: true, + }, + }) + output, err := runCommand(httpClient, "ORG/REPO --team monkeys") if err != nil { t.Errorf("error running command `repo create`: %v", err)