X Tutup
Skip to content

Commit fc1c800

Browse files
author
Nate Smith
authored
Merge pull request cli#1492 from ShubhankarKG/newConfirmations
New confirmations
2 parents 82c6830 + 7955c4f commit fc1c800

File tree

2 files changed

+274
-52
lines changed

2 files changed

+274
-52
lines changed

pkg/cmd/repo/create/create.go

Lines changed: 225 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"path"
77
"strings"
88

9+
"github.com/AlecAivazis/survey/v2"
910
"github.com/MakeNowJust/heredoc"
1011
"github.com/cli/cli/git"
1112
"github.com/cli/cli/internal/config"
@@ -23,13 +24,16 @@ type CreateOptions struct {
2324
Config func() (config.Config, error)
2425
IO *iostreams.IOStreams
2526

26-
Name string
27-
Description string
28-
Homepage string
29-
Team string
30-
EnableIssues bool
31-
EnableWiki bool
32-
Public bool
27+
Name string
28+
Description string
29+
Homepage string
30+
Team string
31+
EnableIssues bool
32+
EnableWiki bool
33+
Public bool
34+
Private bool
35+
Internal bool
36+
ConfirmSubmit bool
3337
}
3438

3539
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
7882
cmd.Flags().StringVarP(&opts.Team, "team", "t", "", "The name of the organization team to be granted access")
7983
cmd.Flags().BoolVar(&opts.EnableIssues, "enable-issues", true, "Enable issues in the new repository")
8084
cmd.Flags().BoolVar(&opts.EnableWiki, "enable-wiki", true, "Enable wiki in the new repository")
81-
cmd.Flags().BoolVar(&opts.Public, "public", false, "Make the new repository public (default: private)")
85+
cmd.Flags().BoolVar(&opts.Public, "public", false, "Make the new repository public")
86+
cmd.Flags().BoolVar(&opts.Private, "private", false, "Make the new repository private")
87+
cmd.Flags().BoolVar(&opts.Internal, "internal", false, "Make the new repository internal")
88+
cmd.Flags().BoolVarP(&opts.ConfirmSubmit, "confirm", "y", false, "Confirm the submission directly")
8289

8390
return cmd
8491
}
@@ -88,7 +95,12 @@ func createRun(opts *CreateOptions) error {
8895

8996
var repoToCreate ghrepo.Interface
9097

98+
isNameAnArg := false
99+
isDescEmpty := opts.Description == ""
100+
isVisibilityPassed := false
101+
91102
if opts.Name != "" {
103+
isNameAnArg = true
92104
if strings.Contains(opts.Name, "/") {
93105
var err error
94106
repoToCreate, err = ghrepo.FromFullName(opts.Name)
@@ -105,10 +117,52 @@ func createRun(opts *CreateOptions) error {
105117
repoToCreate = ghrepo.New("", path.Base(projectDir))
106118
}
107119

108-
visibility := "PRIVATE"
120+
enabledFlagCount := 0
121+
visibility := ""
109122
if opts.Public {
123+
enabledFlagCount++
110124
visibility = "PUBLIC"
111125
}
126+
if opts.Private {
127+
enabledFlagCount++
128+
visibility = "PRIVATE"
129+
}
130+
if opts.Internal {
131+
enabledFlagCount++
132+
visibility = "INTERNAL"
133+
}
134+
135+
if enabledFlagCount > 1 {
136+
return fmt.Errorf("expected exactly one of --public, --private, or --internal to be true")
137+
} else if enabledFlagCount == 1 {
138+
isVisibilityPassed = true
139+
}
140+
141+
// Trigger interactive prompt if name is not passed
142+
if !isNameAnArg {
143+
newName, newDesc, newVisibility, err := interactiveRepoCreate(isDescEmpty, isVisibilityPassed, repoToCreate.RepoName())
144+
if err != nil {
145+
return err
146+
}
147+
if newName != "" {
148+
opts.Name = newName
149+
}
150+
if newDesc != "" {
151+
opts.Description = newDesc
152+
}
153+
if newVisibility != "" {
154+
visibility = newVisibility
155+
}
156+
} else {
157+
// Go for a prompt only if visibility isn't passed
158+
if !isVisibilityPassed {
159+
newVisibility, err := getVisibility()
160+
if err != nil {
161+
return nil
162+
}
163+
visibility = newVisibility
164+
}
165+
}
112166

113167
input := repoCreateInput{
114168
Name: repoToCreate.RepoName(),
@@ -126,67 +180,186 @@ func createRun(opts *CreateOptions) error {
126180
return err
127181
}
128182

129-
repo, err := repoCreate(httpClient, repoToCreate.RepoHost(), input)
130-
if err != nil {
131-
return err
183+
createLocalDirectory := opts.ConfirmSubmit
184+
if !opts.ConfirmSubmit {
185+
opts.ConfirmSubmit, err = confirmSubmission(input.Name, input.OwnerID, &opts.ConfirmSubmit)
186+
if err != nil {
187+
return err
188+
}
132189
}
133190

134-
stderr := opts.IO.ErrOut
135-
stdout := opts.IO.Out
136-
isTTY := opts.IO.IsStdoutTTY()
191+
if opts.ConfirmSubmit {
192+
repo, err := repoCreate(httpClient, repoToCreate.RepoHost(), input)
193+
if err != nil {
194+
return err
195+
}
137196

138-
if isTTY {
139-
fmt.Fprintf(stderr, "%s Created repository %s on GitHub\n", utils.GreenCheck(), ghrepo.FullName(repo))
140-
} else {
141-
fmt.Fprintln(stdout, repo.URL)
142-
}
197+
stderr := opts.IO.ErrOut
198+
stdout := opts.IO.Out
199+
greenCheck := utils.Green("✓")
200+
isTTY := opts.IO.IsStdoutTTY()
143201

144-
// TODO This is overly wordy and I'd like to streamline this.
145-
cfg, err := opts.Config()
146-
if err != nil {
147-
return err
148-
}
149-
protocol, err := cfg.Get(repo.RepoHost(), "git_protocol")
150-
if err != nil {
151-
return err
152-
}
153-
remoteURL := ghrepo.FormatRemoteURL(repo, protocol)
202+
if isTTY {
203+
fmt.Fprintf(stderr, "%s Created repository %s on GitHub\n", greenCheck, ghrepo.FullName(repo))
204+
} else {
205+
fmt.Fprintln(stdout, repo.URL)
206+
}
154207

155-
if projectDirErr == nil {
156-
_, err = git.AddRemote("origin", remoteURL)
208+
// TODO This is overly wordy and I'd like to streamline this.
209+
cfg, err := opts.Config()
157210
if err != nil {
158211
return err
159212
}
160-
if isTTY {
161-
fmt.Fprintf(stderr, "%s Added remote %s\n", utils.GreenCheck(), remoteURL)
162-
}
163-
} else if isTTY {
164-
doSetup := false
165-
err := prompt.Confirm(fmt.Sprintf("Create a local project directory for %s?", ghrepo.FullName(repo)), &doSetup)
213+
protocol, err := cfg.Get(repo.RepoHost(), "git_protocol")
166214
if err != nil {
167215
return err
168216
}
217+
remoteURL := ghrepo.FormatRemoteURL(repo, protocol)
169218

170-
if doSetup {
171-
path := repo.Name
172-
173-
gitInit := git.GitCommand("init", path)
174-
gitInit.Stdout = stdout
175-
gitInit.Stderr = stderr
176-
err = run.PrepareCmd(gitInit).Run()
219+
if projectDirErr == nil {
220+
_, err = git.AddRemote("origin", remoteURL)
177221
if err != nil {
178222
return err
179223
}
180-
gitRemoteAdd := git.GitCommand("-C", path, "remote", "add", "origin", remoteURL)
181-
gitRemoteAdd.Stdout = stdout
182-
gitRemoteAdd.Stderr = stderr
183-
err = run.PrepareCmd(gitRemoteAdd).Run()
184-
if err != nil {
185-
return err
224+
if isTTY {
225+
fmt.Fprintf(stderr, "%s Added remote %s\n", greenCheck, remoteURL)
186226
}
227+
} else if isTTY {
228+
doSetup := createLocalDirectory
229+
if !doSetup {
230+
err := prompt.Confirm(fmt.Sprintf("Create a local project directory for %s?", ghrepo.FullName(repo)), &doSetup)
231+
if err != nil {
232+
return err
233+
}
234+
}
235+
if doSetup {
236+
path := repo.Name
237+
238+
gitInit := git.GitCommand("init", path)
239+
gitInit.Stdout = stdout
240+
gitInit.Stderr = stderr
241+
err = run.PrepareCmd(gitInit).Run()
242+
if err != nil {
243+
return err
244+
}
245+
gitRemoteAdd := git.GitCommand("-C", path, "remote", "add", "origin", remoteURL)
246+
gitRemoteAdd.Stdout = stdout
247+
gitRemoteAdd.Stderr = stderr
248+
err = run.PrepareCmd(gitRemoteAdd).Run()
249+
if err != nil {
250+
return err
251+
}
187252

188-
fmt.Fprintf(stderr, "%s Initialized repository in './%s/'\n", utils.GreenCheck(), path)
253+
fmt.Fprintf(stderr, "%s Initialized repository in './%s/'\n", utils.GreenCheck(), path)
254+
}
189255
}
256+
return nil
190257
}
258+
fmt.Fprintln(opts.IO.Out, "Discarding...")
191259
return nil
192260
}
261+
262+
func interactiveRepoCreate(isDescEmpty bool, isVisibilityPassed bool, repoName string) (string, string, string, error) {
263+
qs := []*survey.Question{}
264+
265+
repoOwnerQuestion := &survey.Question{
266+
Name: "repoOwner",
267+
Prompt: &survey.Input{
268+
Message: "Repository name",
269+
Default: repoName,
270+
},
271+
}
272+
qs = append(qs, repoOwnerQuestion)
273+
274+
if isDescEmpty {
275+
repoDescriptionQuestion := &survey.Question{
276+
Name: "repoDescription",
277+
Prompt: &survey.Input{
278+
Message: "Repository description",
279+
},
280+
}
281+
282+
qs = append(qs, repoDescriptionQuestion)
283+
}
284+
285+
if !isVisibilityPassed {
286+
repoVisibilityQuestion := &survey.Question{
287+
Name: "repoVisibility",
288+
Prompt: &survey.Select{
289+
Message: "Visibility",
290+
Options: []string{"Public", "Private", "Internal"},
291+
},
292+
}
293+
qs = append(qs, repoVisibilityQuestion)
294+
}
295+
296+
answers := struct {
297+
RepoOwner string
298+
RepoDescription string
299+
RepoVisibility string
300+
}{}
301+
302+
err := prompt.SurveyAsk(qs, &answers)
303+
304+
if err != nil {
305+
return "", "", "", err
306+
}
307+
308+
return answers.RepoOwner, answers.RepoDescription, strings.ToUpper(answers.RepoVisibility), nil
309+
310+
}
311+
312+
func confirmSubmission(repoName string, repoOwner string, isConfirmFlagPassed *bool) (bool, error) {
313+
qs := []*survey.Question{}
314+
315+
promptString := ""
316+
if repoOwner != "" {
317+
promptString = fmt.Sprintf("This will create '%s/%s' in your current directory. Continue? ", repoOwner, repoName)
318+
} else {
319+
promptString = fmt.Sprintf("This will create '%s' in your current directory. Continue? ", repoName)
320+
}
321+
322+
confirmSubmitQuestion := &survey.Question{
323+
Name: "confirmSubmit",
324+
Prompt: &survey.Confirm{
325+
Message: promptString,
326+
Default: true,
327+
},
328+
}
329+
qs = append(qs, confirmSubmitQuestion)
330+
331+
answer := struct {
332+
ConfirmSubmit bool
333+
}{}
334+
335+
err := prompt.SurveyAsk(qs, &answer)
336+
if err != nil {
337+
return false, err
338+
}
339+
340+
return answer.ConfirmSubmit, nil
341+
}
342+
343+
func getVisibility() (string, error) {
344+
qs := []*survey.Question{}
345+
346+
getVisibilityQuestion := &survey.Question{
347+
Name: "repoVisibility",
348+
Prompt: &survey.Select{
349+
Message: "Visibility",
350+
Options: []string{"Public", "Private", "Internal"},
351+
},
352+
}
353+
qs = append(qs, getVisibilityQuestion)
354+
355+
answer := struct {
356+
RepoVisibility string
357+
}{}
358+
359+
err := prompt.SurveyAsk(qs, &answer)
360+
if err != nil {
361+
return "", err
362+
}
363+
364+
return strings.ToUpper(answer.RepoVisibility), nil
365+
}

0 commit comments

Comments
 (0)
X Tutup