github.com/abhinav/git-pr@v0.6.1-0.20171029234004-54218d68c11b/cmd/git-pr/land.go (about) 1 package main 2 3 import ( 4 "context" 5 "fmt" 6 "log" 7 8 "github.com/abhinav/git-pr/cli" 9 "github.com/abhinav/git-pr/editor" 10 "github.com/abhinav/git-pr/service" 11 12 "github.com/google/go-github/github" 13 "github.com/jessevdk/go-flags" 14 ) 15 16 type landCmd struct { 17 Editor string `long:"editor" env:"EDITOR" default:"vi" value-name:"EDITOR" description:"Editor to use for interactively editing commit messages."` 18 Args struct { 19 Branch string `positional-arg-name:"BRANCH" description:"Name of the branch to land. Defaults to the branch in the current directory."` 20 } `positional-args:"yes"` 21 22 getConfig configBuilder 23 getEditor func(string) (editor.Editor, error) 24 } 25 26 func newLandCommand(cbuild cli.ConfigBuilder) flags.Commander { 27 return &landCmd{ 28 getConfig: newConfigBuilder(cbuild), 29 getEditor: editor.Pick, 30 } 31 } 32 33 func (l *landCmd) Execute([]string) error { 34 ctx := context.Background() 35 36 cfg, err := l.getConfig() 37 if err != nil { 38 return err 39 } 40 41 editor, err := l.getEditor(l.Editor) 42 if err != nil { 43 return err 44 } 45 46 req := service.LandRequest{Editor: editor} 47 48 // TODO: accept other inputs for the PR to land 49 branch := l.Args.Branch 50 if branch == "" { 51 out, err := cfg.Git().CurrentBranch() 52 if err != nil { 53 return err 54 } 55 branch = out 56 req.LocalBranch = out 57 } 58 59 prs, err := cfg.GitHub().ListPullRequestsByHead(ctx, "", branch) 60 if err != nil { 61 return err 62 } 63 switch len(prs) { 64 case 0: 65 return fmt.Errorf("Could not find PRs with head %q", branch) 66 case 1: 67 req.PullRequest = prs[0] 68 default: 69 return errTooManyPRsWithHead{Head: branch, Pulls: prs} 70 } 71 72 log.Println("Landing", *req.PullRequest.HTMLURL) 73 res, err := cfg.Service.Land(ctx, &req) 74 if err != nil { 75 return fmt.Errorf("failed to land %v: %v", *req.PullRequest.HTMLURL, err) 76 } 77 78 if len(res.BranchesNotUpdated) > 0 { 79 log.Println("The following local branches were not updated because " + 80 "they did not match the corresponding remotes") 81 for _, br := range res.BranchesNotUpdated { 82 log.Println(" -", br) 83 } 84 } 85 return nil 86 } 87 88 type errTooManyPRsWithHead struct { 89 Head string 90 Pulls []*github.PullRequest 91 } 92 93 func (e errTooManyPRsWithHead) Error() string { 94 msg := fmt.Sprintf("Too many PRs found with head %q:", e.Head) 95 for _, pull := range e.Pulls { 96 msg += fmt.Sprintf("\n - %v", *pull.HTMLURL) 97 } 98 // TODO: when we support this: 99 // msg += fmt.Sprintf("\nPlease provide the PR number instead.") 100 return msg 101 }