Merge pull request #1492 from ShubhankarKG/newConfirmations
New confirmations
This commit is contained in:
commit
fc1c800042
2 changed files with 283 additions and 61 deletions
|
|
@ -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,16 @@ 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
|
||||
Private bool
|
||||
Internal bool
|
||||
ConfirmSubmit bool
|
||||
}
|
||||
|
||||
func NewCmdCreate(f *cmdutil.Factory, runF func(*CreateOptions) error) *cobra.Command {
|
||||
|
|
@ -78,7 +82,10 @@ func NewCmdCreate(f *cmdutil.Factory, runF func(*CreateOptions) error) *cobra.Co
|
|||
cmd.Flags().StringVarP(&opts.Team, "team", "t", "", "The name of the organization team to be granted access")
|
||||
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().BoolVar(&opts.Public, "public", false, "Make the new repository public")
|
||||
cmd.Flags().BoolVar(&opts.Private, "private", false, "Make the new repository private")
|
||||
cmd.Flags().BoolVar(&opts.Internal, "internal", false, "Make the new repository internal")
|
||||
cmd.Flags().BoolVarP(&opts.ConfirmSubmit, "confirm", "y", false, "Confirm the submission directly")
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
|
@ -88,7 +95,12 @@ func createRun(opts *CreateOptions) error {
|
|||
|
||||
var repoToCreate ghrepo.Interface
|
||||
|
||||
isNameAnArg := false
|
||||
isDescEmpty := opts.Description == ""
|
||||
isVisibilityPassed := false
|
||||
|
||||
if opts.Name != "" {
|
||||
isNameAnArg = true
|
||||
if strings.Contains(opts.Name, "/") {
|
||||
var err error
|
||||
repoToCreate, err = ghrepo.FromFullName(opts.Name)
|
||||
|
|
@ -105,10 +117,52 @@ func createRun(opts *CreateOptions) error {
|
|||
repoToCreate = ghrepo.New("", path.Base(projectDir))
|
||||
}
|
||||
|
||||
visibility := "PRIVATE"
|
||||
enabledFlagCount := 0
|
||||
visibility := ""
|
||||
if opts.Public {
|
||||
enabledFlagCount++
|
||||
visibility = "PUBLIC"
|
||||
}
|
||||
if opts.Private {
|
||||
enabledFlagCount++
|
||||
visibility = "PRIVATE"
|
||||
}
|
||||
if opts.Internal {
|
||||
enabledFlagCount++
|
||||
visibility = "INTERNAL"
|
||||
}
|
||||
|
||||
if enabledFlagCount > 1 {
|
||||
return fmt.Errorf("expected exactly one of --public, --private, or --internal to be true")
|
||||
} else if enabledFlagCount == 1 {
|
||||
isVisibilityPassed = true
|
||||
}
|
||||
|
||||
// Trigger interactive prompt if name is not passed
|
||||
if !isNameAnArg {
|
||||
newName, newDesc, newVisibility, err := interactiveRepoCreate(isDescEmpty, isVisibilityPassed, repoToCreate.RepoName())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if newName != "" {
|
||||
opts.Name = newName
|
||||
}
|
||||
if newDesc != "" {
|
||||
opts.Description = newDesc
|
||||
}
|
||||
if newVisibility != "" {
|
||||
visibility = newVisibility
|
||||
}
|
||||
} else {
|
||||
// Go for a prompt only if visibility isn't passed
|
||||
if !isVisibilityPassed {
|
||||
newVisibility, err := getVisibility()
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
visibility = newVisibility
|
||||
}
|
||||
}
|
||||
|
||||
input := repoCreateInput{
|
||||
Name: repoToCreate.RepoName(),
|
||||
|
|
@ -126,67 +180,186 @@ func createRun(opts *CreateOptions) error {
|
|||
return err
|
||||
}
|
||||
|
||||
repo, err := repoCreate(httpClient, repoToCreate.RepoHost(), input)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
stderr := opts.IO.ErrOut
|
||||
stdout := opts.IO.Out
|
||||
isTTY := opts.IO.IsStdoutTTY()
|
||||
|
||||
if isTTY {
|
||||
fmt.Fprintf(stderr, "%s Created repository %s on GitHub\n", utils.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(repo.RepoHost(), "git_protocol")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
remoteURL := ghrepo.FormatRemoteURL(repo, protocol)
|
||||
|
||||
if projectDirErr == nil {
|
||||
_, err = git.AddRemote("origin", remoteURL)
|
||||
createLocalDirectory := opts.ConfirmSubmit
|
||||
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, repoToCreate.RepoHost(), 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", utils.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", utils.GreenCheck(), path)
|
||||
protocol, err := cfg.Get(repo.RepoHost(), "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 := createLocalDirectory
|
||||
if !doSetup {
|
||||
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", utils.GreenCheck(), path)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
fmt.Fprintln(opts.IO.Out, "Discarding...")
|
||||
return nil
|
||||
}
|
||||
|
||||
func interactiveRepoCreate(isDescEmpty bool, isVisibilityPassed bool, repoName string) (string, string, string, error) {
|
||||
qs := []*survey.Question{}
|
||||
|
||||
repoOwnerQuestion := &survey.Question{
|
||||
Name: "repoOwner",
|
||||
Prompt: &survey.Input{
|
||||
Message: "Repository name",
|
||||
Default: repoName,
|
||||
},
|
||||
}
|
||||
qs = append(qs, repoOwnerQuestion)
|
||||
|
||||
if isDescEmpty {
|
||||
repoDescriptionQuestion := &survey.Question{
|
||||
Name: "repoDescription",
|
||||
Prompt: &survey.Input{
|
||||
Message: "Repository description",
|
||||
},
|
||||
}
|
||||
|
||||
qs = append(qs, repoDescriptionQuestion)
|
||||
}
|
||||
|
||||
if !isVisibilityPassed {
|
||||
repoVisibilityQuestion := &survey.Question{
|
||||
Name: "repoVisibility",
|
||||
Prompt: &survey.Select{
|
||||
Message: "Visibility",
|
||||
Options: []string{"Public", "Private", "Internal"},
|
||||
},
|
||||
}
|
||||
qs = append(qs, repoVisibilityQuestion)
|
||||
}
|
||||
|
||||
answers := struct {
|
||||
RepoOwner string
|
||||
RepoDescription string
|
||||
RepoVisibility string
|
||||
}{}
|
||||
|
||||
err := prompt.SurveyAsk(qs, &answers)
|
||||
|
||||
if err != nil {
|
||||
return "", "", "", err
|
||||
}
|
||||
|
||||
return answers.RepoOwner, answers.RepoDescription, strings.ToUpper(answers.RepoVisibility), 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,
|
||||
Default: true,
|
||||
},
|
||||
}
|
||||
qs = append(qs, confirmSubmitQuestion)
|
||||
|
||||
answer := struct {
|
||||
ConfirmSubmit bool
|
||||
}{}
|
||||
|
||||
err := prompt.SurveyAsk(qs, &answer)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return answer.ConfirmSubmit, nil
|
||||
}
|
||||
|
||||
func getVisibility() (string, error) {
|
||||
qs := []*survey.Question{}
|
||||
|
||||
getVisibilityQuestion := &survey.Question{
|
||||
Name: "repoVisibility",
|
||||
Prompt: &survey.Select{
|
||||
Message: "Visibility",
|
||||
Options: []string{"Public", "Private", "Internal"},
|
||||
},
|
||||
}
|
||||
qs = append(qs, getVisibilityQuestion)
|
||||
|
||||
answer := struct {
|
||||
RepoVisibility string
|
||||
}{}
|
||||
|
||||
err := prompt.SurveyAsk(qs, &answer)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return strings.ToUpper(answer.RepoVisibility), nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,22 @@ func TestRepoCreate(t *testing.T) {
|
|||
})
|
||||
defer restoreCmd()
|
||||
|
||||
as, surveyTearDown := prompt.InitAskStubber()
|
||||
defer surveyTearDown()
|
||||
|
||||
as.Stub([]*prompt.QuestionStub{
|
||||
{
|
||||
Name: "repoVisibility",
|
||||
Value: "PRIVATE",
|
||||
},
|
||||
})
|
||||
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 +170,22 @@ func TestRepoCreate_org(t *testing.T) {
|
|||
})
|
||||
defer restoreCmd()
|
||||
|
||||
as, surveyTearDown := prompt.InitAskStubber()
|
||||
defer surveyTearDown()
|
||||
|
||||
as.Stub([]*prompt.QuestionStub{
|
||||
{
|
||||
Name: "repoVisibility",
|
||||
Value: "PRIVATE",
|
||||
},
|
||||
})
|
||||
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 +252,22 @@ func TestRepoCreate_orgWithTeam(t *testing.T) {
|
|||
})
|
||||
defer restoreCmd()
|
||||
|
||||
as, surveyTearDown := prompt.InitAskStubber()
|
||||
defer surveyTearDown()
|
||||
|
||||
as.Stub([]*prompt.QuestionStub{
|
||||
{
|
||||
Name: "repoVisibility",
|
||||
Value: "PRIVATE",
|
||||
},
|
||||
})
|
||||
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)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue