From 16ad382f4dfbe27be609820531ad0202f6160e33 Mon Sep 17 00:00:00 2001 From: Corey Johnson Date: Tue, 5 May 2020 11:35:19 -0700 Subject: [PATCH 01/19] Add simple merge test --- command/pr_test.go | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/command/pr_test.go b/command/pr_test.go index 0aff5e14a..86d2829d2 100644 --- a/command/pr_test.go +++ b/command/pr_test.go @@ -3,6 +3,7 @@ package command import ( "bytes" "encoding/json" + "io" "io/ioutil" "os" "os/exec" @@ -938,5 +939,39 @@ func TestPRReopen_alreadyMerged(t *testing.T) { if !r.MatchString(err.Error()) { t.Fatalf("output did not match regexp /%s/\n> output\n%q\n", r, output.Stderr()) } - +} + +type stubResponse struct { + ResponseCode int + ResponseBody io.Reader +} + +func initWithStubs(stubs ...stubResponse) { + initBlankContext("", "OWNER/REPO", "master") + http := initFakeHTTP() + http.StubRepoResponse("OWNER", "REPO") + + for _, s := range stubs { + http.StubResponse(s.ResponseCode, s.ResponseBody) + } +} + +func TestPrMerge(t *testing.T) { + initWithStubs( + stubResponse{200, bytes.NewBufferString(`{ "data": { "repository": { + "pullRequest": { "number": 1, "closed": false, "state": "OPEN"} + } } }`)}, + stubResponse{200, bytes.NewBufferString(`{"id": "THE-ID"}`)}, + ) + + output, err := RunCommand("pr merge 1") + if err != nil { + t.Fatalf("error running command `pr merge`: %v", err) + } + + r := regexp.MustCompile(`Merged pull request #1`) + + if !r.MatchString(output.Stderr()) { + t.Fatalf("output did not match regexp /%s/\n> output\n%q\n", r, output.Stderr()) + } } From 0aca0eff1fe79820813df1b768a5d1e46140c66b Mon Sep 17 00:00:00 2001 From: Corey Johnson Date: Tue, 5 May 2020 11:35:27 -0700 Subject: [PATCH 02/19] Add merge code --- command/pr.go | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/command/pr.go b/command/pr.go index 126d3db01..313bb1f4d 100644 --- a/command/pr.go +++ b/command/pr.go @@ -24,6 +24,7 @@ func init() { prCmd.AddCommand(prStatusCmd) prCmd.AddCommand(prCloseCmd) prCmd.AddCommand(prReopenCmd) + prCmd.AddCommand(prMergeCmd) prCmd.AddCommand(prListCmd) prListCmd.Flags().IntP("limit", "L", 30, "Maximum number of items to fetch") @@ -80,6 +81,13 @@ var prReopenCmd = &cobra.Command{ RunE: prReopen, } +var prMergeCmd = &cobra.Command{ + Use: "merge ", + Short: "Merge a pull request", + Args: cobra.ExactArgs(1), + RunE: prMerge, +} + func prStatus(cmd *cobra.Command, args []string) error { ctx := contextForCommand(cmd) apiClient, err := apiClientForContext(ctx) @@ -420,6 +428,38 @@ func prReopen(cmd *cobra.Command, args []string) error { return nil } +func prMerge(cmd *cobra.Command, args []string) error { + ctx := contextForCommand(cmd) + apiClient, err := apiClientForContext(ctx) + if err != nil { + return err + } + + baseRepo, err := determineBaseRepo(cmd, ctx) + if err != nil { + return err + } + + pr, err := prFromArg(apiClient, baseRepo, args[0]) + if err != nil { + return err + } + + if pr.State == "MERGED" { + err := fmt.Errorf("%s Pull request #%d was already merged", utils.Red("!"), pr.Number) + return err + } + + err = api.PullRequestClose(apiClient, baseRepo, pr) + if err != nil { + return fmt.Errorf("API call failed: %w", err) + } + + fmt.Fprintf(colorableErr(cmd), "%s Merged pull request #%d\n", utils.Green("✔"), pr.Number) + + return nil +} + func printPrPreview(out io.Writer, pr *api.PullRequest) error { // Header (Title and State) fmt.Fprintln(out, utils.Bold(pr.Title)) From c0831d4c4f617e019027b12d74b6dd074276b09c Mon Sep 17 00:00:00 2001 From: Corey Johnson Date: Tue, 5 May 2020 11:56:45 -0700 Subject: [PATCH 03/19] Add merge api call --- api/queries_pr.go | 19 +++++++++++++++++++ command/pr.go | 2 +- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/api/queries_pr.go b/api/queries_pr.go index ccbe1f390..6da60ce31 100644 --- a/api/queries_pr.go +++ b/api/queries_pr.go @@ -799,6 +799,25 @@ func PullRequestReopen(client *Client, repo ghrepo.Interface, pr *PullRequest) e return err } +func PullRequestMerge(client *Client, repo ghrepo.Interface, pr *PullRequest) error { + var mutation struct { + ReopenPullRequest struct { + PullRequest struct { + ID githubv4.ID + } + } `graphql:"mergePullRequest(input: $input)"` + } + + input := githubv4.MergePullRequestInput{ + PullRequestID: pr.ID, + } + + v4 := githubv4.NewClient(client.http) + err := v4.Mutate(context.Background(), &mutation, input, nil) + + return err +} + func min(a, b int) int { if a < b { return a diff --git a/command/pr.go b/command/pr.go index 313bb1f4d..9e73e4709 100644 --- a/command/pr.go +++ b/command/pr.go @@ -450,7 +450,7 @@ func prMerge(cmd *cobra.Command, args []string) error { return err } - err = api.PullRequestClose(apiClient, baseRepo, pr) + err = api.PullRequestMerge(apiClient, baseRepo, pr) if err != nil { return fmt.Errorf("API call failed: %w", err) } From 8681e7a7b62381d6c097572ef6810fa1fecbf939 Mon Sep 17 00:00:00 2001 From: Corey Johnson Date: Tue, 5 May 2020 15:09:02 -0700 Subject: [PATCH 04/19] Make squash and rebase work --- api/queries_pr.go | 13 +++++++++++++ command/pr.go | 31 +++++++++++++++++++++++++++---- command/pr_test.go | 40 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 80 insertions(+), 4 deletions(-) diff --git a/api/queries_pr.go b/api/queries_pr.go index 6da60ce31..ffd31c75b 100644 --- a/api/queries_pr.go +++ b/api/queries_pr.go @@ -800,6 +800,18 @@ func PullRequestReopen(client *Client, repo ghrepo.Interface, pr *PullRequest) e } func PullRequestMerge(client *Client, repo ghrepo.Interface, pr *PullRequest) error { + return merge(client, repo, pr, githubv4.PullRequestMergeMethodMerge) +} + +func PullRequestRebase(client *Client, repo ghrepo.Interface, pr *PullRequest) error { + return merge(client, repo, pr, githubv4.PullRequestMergeMethodRebase) +} + +func PullRequestSquash(client *Client, repo ghrepo.Interface, pr *PullRequest) error { + return merge(client, repo, pr, githubv4.PullRequestMergeMethodSquash) +} + +func merge(client *Client, repo ghrepo.Interface, pr *PullRequest, mergeMethod githubv4.PullRequestMergeMethod) error { var mutation struct { ReopenPullRequest struct { PullRequest struct { @@ -810,6 +822,7 @@ func PullRequestMerge(client *Client, repo ghrepo.Interface, pr *PullRequest) er input := githubv4.MergePullRequestInput{ PullRequestID: pr.ID, + MergeMethod: &mergeMethod, } v4 := githubv4.NewClient(client.http) diff --git a/command/pr.go b/command/pr.go index 9e73e4709..4ff1a2ad3 100644 --- a/command/pr.go +++ b/command/pr.go @@ -25,6 +25,9 @@ func init() { prCmd.AddCommand(prCloseCmd) prCmd.AddCommand(prReopenCmd) prCmd.AddCommand(prMergeCmd) + prMergeCmd.Flags().BoolP("merge", "m", true, "merge the commits with the base branch") + prMergeCmd.Flags().BoolP("rebase", "r", false, "Rebase the commits onto the base branch") + prMergeCmd.Flags().BoolP("squash", "s", false, "Squash the commits into one commit and merge it into the base branch") prCmd.AddCommand(prListCmd) prListCmd.Flags().IntP("limit", "L", 30, "Maximum number of items to fetch") @@ -58,7 +61,7 @@ var prStatusCmd = &cobra.Command{ RunE: prStatus, } var prViewCmd = &cobra.Command{ - Use: "view [{ | | }]", + Use: "view <{ | | }>", Short: "View a pull request", Long: `Display the title, body, and other information about a pull request. @@ -82,7 +85,7 @@ var prReopenCmd = &cobra.Command{ } var prMergeCmd = &cobra.Command{ - Use: "merge ", + Use: "merge [--rebase | --merge | --squash]", Short: "Merge a pull request", Args: cobra.ExactArgs(1), RunE: prMerge, @@ -450,12 +453,32 @@ func prMerge(cmd *cobra.Command, args []string) error { return err } - err = api.PullRequestMerge(apiClient, baseRepo, pr) + rebase, err := cmd.Flags().GetBool("rebase") + if err != nil { + return err + } + squash, err := cmd.Flags().GetBool("squash") + if err != nil { + return err + } + + var output string + if rebase { + output = fmt.Sprintf("%s Rebased pull request #%d\n", utils.Green("✔"), pr.Number) + err = api.PullRequestRebase(apiClient, baseRepo, pr) + } else if squash { + output = fmt.Sprintf("%s Squashed and merged pull request #%d\n", utils.Green("✔"), pr.Number) + err = api.PullRequestSquash(apiClient, baseRepo, pr) + } else { + output = fmt.Sprintf("%s Merged pull request #%d\n", utils.Green("✔"), pr.Number) + err = api.PullRequestMerge(apiClient, baseRepo, pr) + } + if err != nil { return fmt.Errorf("API call failed: %w", err) } - fmt.Fprintf(colorableErr(cmd), "%s Merged pull request #%d\n", utils.Green("✔"), pr.Number) + fmt.Fprintf(colorableErr(cmd), output) return nil } diff --git a/command/pr_test.go b/command/pr_test.go index 86d2829d2..c4d4cfb07 100644 --- a/command/pr_test.go +++ b/command/pr_test.go @@ -975,3 +975,43 @@ func TestPrMerge(t *testing.T) { t.Fatalf("output did not match regexp /%s/\n> output\n%q\n", r, output.Stderr()) } } + +func TestPrMerge_rebase(t *testing.T) { + initWithStubs( + stubResponse{200, bytes.NewBufferString(`{ "data": { "repository": { + "pullRequest": { "number": 2, "closed": false, "state": "OPEN"} + } } }`)}, + stubResponse{200, bytes.NewBufferString(`{"id": "THE-ID"}`)}, + ) + + output, err := RunCommand("pr merge 2 --rebase") + if err != nil { + t.Fatalf("error running command `pr merge`: %v", err) + } + + r := regexp.MustCompile(`Rebased pull request #2`) + + if !r.MatchString(output.Stderr()) { + t.Fatalf("output did not match regexp /%s/\n> output\n%q\n", r, output.Stderr()) + } +} + +func TestPrMerge_squash(t *testing.T) { + initWithStubs( + stubResponse{200, bytes.NewBufferString(`{ "data": { "repository": { + "pullRequest": { "number": 3, "closed": false, "state": "OPEN"} + } } }`)}, + stubResponse{200, bytes.NewBufferString(`{"id": "THE-ID"}`)}, + ) + + output, err := RunCommand("pr merge 3 --squash") + if err != nil { + t.Fatalf("error running command `pr merge`: %v", err) + } + + r := regexp.MustCompile(`Squashed and merged pull request #3`) + + if !r.MatchString(output.Stderr()) { + t.Fatalf("output did not match regexp /%s/\n> output\n%q\n", r, output.Stderr()) + } +} From 062c8353eb51efd0e01d648a0fc1bb8673028e23 Mon Sep 17 00:00:00 2001 From: Corey Johnson Date: Tue, 5 May 2020 15:11:06 -0700 Subject: [PATCH 05/19] Add 'already merged' test --- command/pr_test.go | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/command/pr_test.go b/command/pr_test.go index c4d4cfb07..9d75a482d 100644 --- a/command/pr_test.go +++ b/command/pr_test.go @@ -1015,3 +1015,23 @@ func TestPrMerge_squash(t *testing.T) { t.Fatalf("output did not match regexp /%s/\n> output\n%q\n", r, output.Stderr()) } } + +func TestPrMerge_alreadyMerged(t *testing.T) { + initWithStubs( + stubResponse{200, bytes.NewBufferString(`{ "data": { "repository": { + "pullRequest": { "number": 4, "closed": true, "state": "MERGED"} + } } }`)}, + stubResponse{200, bytes.NewBufferString(`{"id": "THE-ID"}`)}, + ) + + output, err := RunCommand("pr merge 4") + if err == nil { + t.Fatalf("expected an error running command `pr merge`: %v", err) + } + + r := regexp.MustCompile(`Pull request #4 was already merged`) + + if !r.MatchString(err.Error()) { + t.Fatalf("output did not match regexp /%s/\n> output\n%q\n", r, output.Stderr()) + } +} From 8c85e14bac8f0bd47b8f0c8a16f9e23c314e8d98 Mon Sep 17 00:00:00 2001 From: Corey Johnson Date: Wed, 6 May 2020 11:19:00 -0700 Subject: [PATCH 06/19] Make it work without a PR number --- api/queries_pr.go | 2 ++ command/pr.go | 25 ++++++++++++++++++++----- command/pr_test.go | 20 ++++++++++++++++++++ 3 files changed, 42 insertions(+), 5 deletions(-) diff --git a/api/queries_pr.go b/api/queries_pr.go index ffd31c75b..0c42178f7 100644 --- a/api/queries_pr.go +++ b/api/queries_pr.go @@ -446,6 +446,7 @@ func PullRequestForBranch(client *Client, repo ghrepo.Interface, baseBranch, hea type response struct { Repository struct { PullRequests struct { + ID githubv4.ID Nodes []PullRequest } } @@ -456,6 +457,7 @@ func PullRequestForBranch(client *Client, repo ghrepo.Interface, baseBranch, hea repository(owner: $owner, name: $repo) { pullRequests(headRefName: $headRefName, states: OPEN, first: 30) { nodes { + id number title state diff --git a/command/pr.go b/command/pr.go index 4ff1a2ad3..e0b80871f 100644 --- a/command/pr.go +++ b/command/pr.go @@ -85,9 +85,9 @@ var prReopenCmd = &cobra.Command{ } var prMergeCmd = &cobra.Command{ - Use: "merge [--rebase | --merge | --squash]", + Use: "merge [number | url] [--rebase | --merge | --squash]", Short: "Merge a pull request", - Args: cobra.ExactArgs(1), + Args: cobra.MaximumNArgs(1), RunE: prMerge, } @@ -110,6 +110,7 @@ func prStatus(cmd *cobra.Command, args []string) error { repoOverride, _ := cmd.Flags().GetString("repo") currentPRNumber, currentPRHeadRef, err := prSelectorForCurrentBranch(ctx, baseRepo) + if err != nil && repoOverride == "" && err.Error() != "git: not on any branch" { return fmt.Errorf("could not query for pull request for current branch: %w", err) } @@ -443,9 +444,23 @@ func prMerge(cmd *cobra.Command, args []string) error { return err } - pr, err := prFromArg(apiClient, baseRepo, args[0]) - if err != nil { - return err + var pr *api.PullRequest + if len(args) > 0 { + pr, err = prFromArg(apiClient, baseRepo, args[0]) + if err != nil { + return err + } + } else { + _, branchWithOwner, err := prSelectorForCurrentBranch(ctx, baseRepo) + if err != nil { + return err + } + + pr, err = api.PullRequestForBranch(apiClient, baseRepo, "", branchWithOwner) + fmt.Printf("🌭 %+v\n", pr) + if err != nil { + return err + } } if pr.State == "MERGED" { diff --git a/command/pr_test.go b/command/pr_test.go index 9d75a482d..6b5be7eb6 100644 --- a/command/pr_test.go +++ b/command/pr_test.go @@ -976,6 +976,26 @@ func TestPrMerge(t *testing.T) { } } +func TestPrMerge_noPrNumberGiven(t *testing.T) { + initWithStubs( + stubResponse{200, bytes.NewBufferString(`{ "data": { "repository": { + "pullRequest": { "number": 100, "closed": false, "state": "OPEN"} + } } }`)}, + stubResponse{200, bytes.NewBufferString(`{"id": "THE-ID"}`)}, + ) + + output, err := RunCommand("pr merge") + if err != nil { + t.Fatalf("error running command `pr merge`: %v", err) + } + + r := regexp.MustCompile(`Merged pull request #100`) + + if !r.MatchString(output.Stderr()) { + t.Fatalf("output did not match regexp /%s/\n> output\n%q\n", r, output.Stderr()) + } +} + func TestPrMerge_rebase(t *testing.T) { initWithStubs( stubResponse{200, bytes.NewBufferString(`{ "data": { "repository": { From 5a04679535b2ae2c4b2bb6fe883bcbdd8a57c26c Mon Sep 17 00:00:00 2001 From: Corey Johnson Date: Wed, 6 May 2020 11:21:05 -0700 Subject: [PATCH 07/19] Remove debug output --- command/pr.go | 1 - 1 file changed, 1 deletion(-) diff --git a/command/pr.go b/command/pr.go index e0b80871f..ad76a2e1d 100644 --- a/command/pr.go +++ b/command/pr.go @@ -457,7 +457,6 @@ func prMerge(cmd *cobra.Command, args []string) error { } pr, err = api.PullRequestForBranch(apiClient, baseRepo, "", branchWithOwner) - fmt.Printf("🌭 %+v\n", pr) if err != nil { return err } From 1de57db74de9045cf5b8089d3edd02fa48cbc3ff Mon Sep 17 00:00:00 2001 From: Corey Johnson Date: Wed, 6 May 2020 11:27:41 -0700 Subject: [PATCH 08/19] Fix lint error --- command/pr.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/command/pr.go b/command/pr.go index ad76a2e1d..7b36089b5 100644 --- a/command/pr.go +++ b/command/pr.go @@ -492,7 +492,7 @@ func prMerge(cmd *cobra.Command, args []string) error { return fmt.Errorf("API call failed: %w", err) } - fmt.Fprintf(colorableErr(cmd), output) + fmt.Fprint(colorableErr(cmd), output) return nil } From 3d21a33bac0056d05fbaf604a8aa94cc17c72f61 Mon Sep 17 00:00:00 2001 From: Corey Johnson Date: Wed, 6 May 2020 11:47:43 -0700 Subject: [PATCH 09/19] update test --- command/pr_test.go | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/command/pr_test.go b/command/pr_test.go index 6b5be7eb6..4bbba2eae 100644 --- a/command/pr_test.go +++ b/command/pr_test.go @@ -946,8 +946,8 @@ type stubResponse struct { ResponseBody io.Reader } -func initWithStubs(stubs ...stubResponse) { - initBlankContext("", "OWNER/REPO", "master") +func initWithStubs(branch string, stubs ...stubResponse) { + initBlankContext("", "OWNER/REPO", branch) http := initFakeHTTP() http.StubRepoResponse("OWNER", "REPO") @@ -957,7 +957,7 @@ func initWithStubs(stubs ...stubResponse) { } func TestPrMerge(t *testing.T) { - initWithStubs( + initWithStubs("master", stubResponse{200, bytes.NewBufferString(`{ "data": { "repository": { "pullRequest": { "number": 1, "closed": false, "state": "OPEN"} } } }`)}, @@ -977,10 +977,16 @@ func TestPrMerge(t *testing.T) { } func TestPrMerge_noPrNumberGiven(t *testing.T) { - initWithStubs( - stubResponse{200, bytes.NewBufferString(`{ "data": { "repository": { - "pullRequest": { "number": 100, "closed": false, "state": "OPEN"} - } } }`)}, + cs, cmdTeardown := test.InitCmdStubber() + defer cmdTeardown() + + cs.Stub("branch.blueberries.remote origin\nbranch.blueberries.merge refs/heads/blueberries") // git config --get-regexp ^branch\.master\.(remote|merge) + + jsonFile, _ := os.Open("../test/fixtures/prViewPreviewWithMetadataByBranch.json") + defer jsonFile.Close() + + initWithStubs("blueberries", + stubResponse{200, jsonFile}, stubResponse{200, bytes.NewBufferString(`{"id": "THE-ID"}`)}, ) @@ -989,7 +995,7 @@ func TestPrMerge_noPrNumberGiven(t *testing.T) { t.Fatalf("error running command `pr merge`: %v", err) } - r := regexp.MustCompile(`Merged pull request #100`) + r := regexp.MustCompile(`Merged pull request #10`) if !r.MatchString(output.Stderr()) { t.Fatalf("output did not match regexp /%s/\n> output\n%q\n", r, output.Stderr()) @@ -997,7 +1003,7 @@ func TestPrMerge_noPrNumberGiven(t *testing.T) { } func TestPrMerge_rebase(t *testing.T) { - initWithStubs( + initWithStubs("master", stubResponse{200, bytes.NewBufferString(`{ "data": { "repository": { "pullRequest": { "number": 2, "closed": false, "state": "OPEN"} } } }`)}, @@ -1017,7 +1023,7 @@ func TestPrMerge_rebase(t *testing.T) { } func TestPrMerge_squash(t *testing.T) { - initWithStubs( + initWithStubs("master", stubResponse{200, bytes.NewBufferString(`{ "data": { "repository": { "pullRequest": { "number": 3, "closed": false, "state": "OPEN"} } } }`)}, @@ -1037,7 +1043,7 @@ func TestPrMerge_squash(t *testing.T) { } func TestPrMerge_alreadyMerged(t *testing.T) { - initWithStubs( + initWithStubs("master", stubResponse{200, bytes.NewBufferString(`{ "data": { "repository": { "pullRequest": { "number": 4, "closed": true, "state": "MERGED"} } } }`)}, From 5810acf6ac72df3d29a1b2a50fe6461e03c9192f Mon Sep 17 00:00:00 2001 From: Corey Johnson Date: Thu, 7 May 2020 10:29:56 -0700 Subject: [PATCH 10/19] Use correct struct --- api/queries_pr.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/queries_pr.go b/api/queries_pr.go index 0c42178f7..bcf589534 100644 --- a/api/queries_pr.go +++ b/api/queries_pr.go @@ -815,7 +815,7 @@ func PullRequestSquash(client *Client, repo ghrepo.Interface, pr *PullRequest) e func merge(client *Client, repo ghrepo.Interface, pr *PullRequest, mergeMethod githubv4.PullRequestMergeMethod) error { var mutation struct { - ReopenPullRequest struct { + MergePullRequest struct { PullRequest struct { ID githubv4.ID } From bcf41fd5e7da411b068d6323c12ca5c571bf28e5 Mon Sep 17 00:00:00 2001 From: Corey Johnson Date: Thu, 7 May 2020 10:30:14 -0700 Subject: [PATCH 11/19] Fix sentence case --- command/pr.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/command/pr.go b/command/pr.go index 7b36089b5..1d3cf704e 100644 --- a/command/pr.go +++ b/command/pr.go @@ -25,7 +25,7 @@ func init() { prCmd.AddCommand(prCloseCmd) prCmd.AddCommand(prReopenCmd) prCmd.AddCommand(prMergeCmd) - prMergeCmd.Flags().BoolP("merge", "m", true, "merge the commits with the base branch") + prMergeCmd.Flags().BoolP("merge", "m", true, "Merge the commits with the base branch") prMergeCmd.Flags().BoolP("rebase", "r", false, "Rebase the commits onto the base branch") prMergeCmd.Flags().BoolP("squash", "s", false, "Squash the commits into one commit and merge it into the base branch") From 2041f0ab1b0b8c643ff8a446ee0238cf1e845155 Mon Sep 17 00:00:00 2001 From: Corey Johnson Date: Thu, 7 May 2020 10:30:23 -0700 Subject: [PATCH 12/19] Fix usage syntax --- command/pr.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/command/pr.go b/command/pr.go index 1d3cf704e..0b134a309 100644 --- a/command/pr.go +++ b/command/pr.go @@ -61,7 +61,7 @@ var prStatusCmd = &cobra.Command{ RunE: prStatus, } var prViewCmd = &cobra.Command{ - Use: "view <{ | | }>", + Use: "view [{ | | }]", Short: "View a pull request", Long: `Display the title, body, and other information about a pull request. From 1ea38af79c41d1ef2041676202f3efbee7654759 Mon Sep 17 00:00:00 2001 From: Corey Johnson Date: Thu, 7 May 2020 10:30:31 -0700 Subject: [PATCH 13/19] Fix merge usage syntax --- command/pr.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/command/pr.go b/command/pr.go index 0b134a309..c7f74d256 100644 --- a/command/pr.go +++ b/command/pr.go @@ -85,7 +85,7 @@ var prReopenCmd = &cobra.Command{ } var prMergeCmd = &cobra.Command{ - Use: "merge [number | url] [--rebase | --merge | --squash]", + Use: "merge [{ | }] []", Short: "Merge a pull request", Args: cobra.MaximumNArgs(1), RunE: prMerge, From 4b2f14d9390d563e69680de68dac51e28e7d2bed Mon Sep 17 00:00:00 2001 From: Corey Johnson Date: Thu, 7 May 2020 10:30:51 -0700 Subject: [PATCH 14/19] Use PR if given --- command/pr.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/command/pr.go b/command/pr.go index c7f74d256..9691b9ba7 100644 --- a/command/pr.go +++ b/command/pr.go @@ -451,12 +451,16 @@ func prMerge(cmd *cobra.Command, args []string) error { return err } } else { - _, branchWithOwner, err := prSelectorForCurrentBranch(ctx, baseRepo) + prNumber, branchWithOwner, err := prSelectorForCurrentBranch(ctx, baseRepo) if err != nil { return err } - pr, err = api.PullRequestForBranch(apiClient, baseRepo, "", branchWithOwner) + if prNumber != 0 { + pr, err = api.PullRequestByNumber(apiClient, baseRepo, prNumber) + } else { + pr, err = api.PullRequestForBranch(apiClient, baseRepo, "", branchWithOwner) + } if err != nil { return err } From 5b78d47306cf12ba6d94e50ac64f08bf75ad2b7d Mon Sep 17 00:00:00 2001 From: Corey Johnson Date: Thu, 7 May 2020 10:30:59 -0700 Subject: [PATCH 15/19] Use stdout --- command/pr.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/command/pr.go b/command/pr.go index 9691b9ba7..8678fcb90 100644 --- a/command/pr.go +++ b/command/pr.go @@ -496,7 +496,7 @@ func prMerge(cmd *cobra.Command, args []string) error { return fmt.Errorf("API call failed: %w", err) } - fmt.Fprint(colorableErr(cmd), output) + fmt.Fprint(colorableOut(cmd), output) return nil } From 58663dccfdf857dd66dddcad9e3449b337dba1ab Mon Sep 17 00:00:00 2001 From: Corey Johnson Date: Thu, 7 May 2020 10:31:05 -0700 Subject: [PATCH 16/19] Better description --- command/pr.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/command/pr.go b/command/pr.go index 8678fcb90..e5cd8b514 100644 --- a/command/pr.go +++ b/command/pr.go @@ -482,7 +482,7 @@ func prMerge(cmd *cobra.Command, args []string) error { var output string if rebase { - output = fmt.Sprintf("%s Rebased pull request #%d\n", utils.Green("✔"), pr.Number) + output = fmt.Sprintf("%s Rebased and merged pull request #%d\n", utils.Green("✔"), pr.Number) err = api.PullRequestRebase(apiClient, baseRepo, pr) } else if squash { output = fmt.Sprintf("%s Squashed and merged pull request #%d\n", utils.Green("✔"), pr.Number) From ea6b3dca8ca403b2867d077e534697a3306dae01 Mon Sep 17 00:00:00 2001 From: Corey Johnson Date: Thu, 7 May 2020 10:52:30 -0700 Subject: [PATCH 17/19] Update pr_test.go --- command/pr_test.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/command/pr_test.go b/command/pr_test.go index 4bbba2eae..61971d538 100644 --- a/command/pr_test.go +++ b/command/pr_test.go @@ -971,7 +971,7 @@ func TestPrMerge(t *testing.T) { r := regexp.MustCompile(`Merged pull request #1`) - if !r.MatchString(output.Stderr()) { + if !r.MatchString(output.String()) { t.Fatalf("output did not match regexp /%s/\n> output\n%q\n", r, output.Stderr()) } } @@ -997,7 +997,7 @@ func TestPrMerge_noPrNumberGiven(t *testing.T) { r := regexp.MustCompile(`Merged pull request #10`) - if !r.MatchString(output.Stderr()) { + if !r.MatchString(output.String()) { t.Fatalf("output did not match regexp /%s/\n> output\n%q\n", r, output.Stderr()) } } @@ -1015,9 +1015,9 @@ func TestPrMerge_rebase(t *testing.T) { t.Fatalf("error running command `pr merge`: %v", err) } - r := regexp.MustCompile(`Rebased pull request #2`) + r := regexp.MustCompile(`Rebased and merged pull request #2`) - if !r.MatchString(output.Stderr()) { + if !r.MatchString(output.String()) { t.Fatalf("output did not match regexp /%s/\n> output\n%q\n", r, output.Stderr()) } } @@ -1037,7 +1037,7 @@ func TestPrMerge_squash(t *testing.T) { r := regexp.MustCompile(`Squashed and merged pull request #3`) - if !r.MatchString(output.Stderr()) { + if !r.MatchString(output.String()) { t.Fatalf("output did not match regexp /%s/\n> output\n%q\n", r, output.Stderr()) } } From b9c4a7668765c0f3c4c33b9d66768683fac038d5 Mon Sep 17 00:00:00 2001 From: Corey Johnson Date: Fri, 8 May 2020 11:20:00 -0700 Subject: [PATCH 18/19] Update usage docs --- command/pr.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/command/pr.go b/command/pr.go index e5cd8b514..d245349db 100644 --- a/command/pr.go +++ b/command/pr.go @@ -61,7 +61,7 @@ var prStatusCmd = &cobra.Command{ RunE: prStatus, } var prViewCmd = &cobra.Command{ - Use: "view [{ | | }]", + Use: "view [ | | ]", Short: "View a pull request", Long: `Display the title, body, and other information about a pull request. @@ -72,20 +72,20 @@ With '--web', open the pull request in a web browser instead.`, RunE: prView, } var prCloseCmd = &cobra.Command{ - Use: "close ", + Use: "close { | | }", Short: "Close a pull request", Args: cobra.ExactArgs(1), RunE: prClose, } var prReopenCmd = &cobra.Command{ - Use: "reopen ", + Use: "reopen { | | }", Short: "Reopen a pull request", Args: cobra.ExactArgs(1), RunE: prReopen, } var prMergeCmd = &cobra.Command{ - Use: "merge [{ | }] []", + Use: "merge [ | | ]", Short: "Merge a pull request", Args: cobra.MaximumNArgs(1), RunE: prMerge, From 43e15130f1db1086fa5e0fe1c368c3ecded03c44 Mon Sep 17 00:00:00 2001 From: Corey Johnson Date: Fri, 8 May 2020 11:37:45 -0700 Subject: [PATCH 19/19] Use a var --- api/queries_pr.go | 28 ++++++++++++++++------------ command/pr.go | 6 +++--- 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/api/queries_pr.go b/api/queries_pr.go index bcf589534..180b7091f 100644 --- a/api/queries_pr.go +++ b/api/queries_pr.go @@ -130,6 +130,14 @@ type PullRequestReviewStatus struct { ReviewRequired bool } +type PullRequestMergeMethod int + +const ( + PullRequestMergeMethodMerge PullRequestMergeMethod = iota + PullRequestMergeMethodRebase + PullRequestMergeMethodSquash +) + func (pr *PullRequest) ReviewStatus() PullRequestReviewStatus { var status PullRequestReviewStatus switch pr.ReviewDecision { @@ -801,19 +809,15 @@ func PullRequestReopen(client *Client, repo ghrepo.Interface, pr *PullRequest) e return err } -func PullRequestMerge(client *Client, repo ghrepo.Interface, pr *PullRequest) error { - return merge(client, repo, pr, githubv4.PullRequestMergeMethodMerge) -} +func PullRequestMerge(client *Client, repo ghrepo.Interface, pr *PullRequest, m PullRequestMergeMethod) error { + mergeMethod := githubv4.PullRequestMergeMethodMerge + switch m { + case PullRequestMergeMethodRebase: + mergeMethod = githubv4.PullRequestMergeMethodRebase + case PullRequestMergeMethodSquash: + mergeMethod = githubv4.PullRequestMergeMethodSquash + } -func PullRequestRebase(client *Client, repo ghrepo.Interface, pr *PullRequest) error { - return merge(client, repo, pr, githubv4.PullRequestMergeMethodRebase) -} - -func PullRequestSquash(client *Client, repo ghrepo.Interface, pr *PullRequest) error { - return merge(client, repo, pr, githubv4.PullRequestMergeMethodSquash) -} - -func merge(client *Client, repo ghrepo.Interface, pr *PullRequest, mergeMethod githubv4.PullRequestMergeMethod) error { var mutation struct { MergePullRequest struct { PullRequest struct { diff --git a/command/pr.go b/command/pr.go index d245349db..e590c0e70 100644 --- a/command/pr.go +++ b/command/pr.go @@ -483,13 +483,13 @@ func prMerge(cmd *cobra.Command, args []string) error { var output string if rebase { output = fmt.Sprintf("%s Rebased and merged pull request #%d\n", utils.Green("✔"), pr.Number) - err = api.PullRequestRebase(apiClient, baseRepo, pr) + err = api.PullRequestMerge(apiClient, baseRepo, pr, api.PullRequestMergeMethodRebase) } else if squash { output = fmt.Sprintf("%s Squashed and merged pull request #%d\n", utils.Green("✔"), pr.Number) - err = api.PullRequestSquash(apiClient, baseRepo, pr) + err = api.PullRequestMerge(apiClient, baseRepo, pr, api.PullRequestMergeMethodSquash) } else { output = fmt.Sprintf("%s Merged pull request #%d\n", utils.Green("✔"), pr.Number) - err = api.PullRequestMerge(apiClient, baseRepo, pr) + err = api.PullRequestMerge(apiClient, baseRepo, pr, api.PullRequestMergeMethodMerge) } if err != nil {