From 66abe9e62e138d01c107de2f40c3d2373dc3c3b4 Mon Sep 17 00:00:00 2001 From: Corey Johnson Date: Thu, 30 Apr 2020 11:24:27 -0700 Subject: [PATCH 01/23] Add pr close test --- command/pr_test.go | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/command/pr_test.go b/command/pr_test.go index ba0989645..a133e04f9 100644 --- a/command/pr_test.go +++ b/command/pr_test.go @@ -800,3 +800,28 @@ func TestPrStateTitleWithColor(t *testing.T) { }) } } + +func TestPrClose(t *testing.T) { + initBlankContext("", "OWNER/REPO", "master") + http := initFakeHTTP() + http.StubRepoResponse("OWNER", "REPO") + + http.StubResponse(200, bytes.NewBufferString(` + { "data": { "repository": { + "pullRequest": { "number": 96 } + } } } + `)) + + http.StubResponse(200, bytes.NewBufferString(`{"id": "THE-ID"}`)) + + output, err := RunCommand(prCloseCmd, "pr close 96") + if err != nil { + t.Fatalf("error running command `pr close`: %v", err) + } + + r := regexp.MustCompile(`Closed pull request #96`) + + if !r.MatchString(output.Stderr()) { + t.Fatalf("output did not match regexp /%s/\n> output\n%q\n", r, output.Stderr()) + } +} From f9a55f4d8ed96b08d9081407d569695ff68dcf66 Mon Sep 17 00:00:00 2001 From: Corey Johnson Date: Thu, 30 Apr 2020 11:24:43 -0700 Subject: [PATCH 02/23] Add close pull request code --- api/queries_pr.go | 23 +++++++++++++++++++++++ command/pr.go | 42 ++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 63 insertions(+), 2 deletions(-) diff --git a/api/queries_pr.go b/api/queries_pr.go index 0b2fd378a..6af709947 100644 --- a/api/queries_pr.go +++ b/api/queries_pr.go @@ -1,11 +1,13 @@ package api import ( + "context" "fmt" "strings" "time" "github.com/cli/cli/internal/ghrepo" + "github.com/shurcooL/githubv4" ) type PullRequestsPayload struct { @@ -20,9 +22,11 @@ type PullRequestAndTotalCount struct { } type PullRequest struct { + ID string Number int Title string State string + Closed bool URL string BaseRefName string HeadRefName string @@ -755,6 +759,25 @@ loop: return &res, nil } +func PullRequestClose(client *Client, repo ghrepo.Interface, pr PullRequest) error { + var mutation struct { + ClosePullRequest struct { + PullRequest struct { + ID githubv4.ID + } + } `graphql:"closePullRequest(input: $input)"` + } + + input := githubv4.ClosePullRequestInput{ + 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 009548061..49e1f3c9a 100644 --- a/command/pr.go +++ b/command/pr.go @@ -21,16 +21,17 @@ func init() { RootCmd.AddCommand(prCmd) prCmd.AddCommand(prCheckoutCmd) prCmd.AddCommand(prCreateCmd) - prCmd.AddCommand(prListCmd) prCmd.AddCommand(prStatusCmd) - prCmd.AddCommand(prViewCmd) + prCmd.AddCommand(prCloseCmd) + prCmd.AddCommand(prListCmd) prListCmd.Flags().IntP("limit", "L", 30, "Maximum number of items to fetch") prListCmd.Flags().StringP("state", "s", "open", "Filter by state: {open|closed|merged|all}") prListCmd.Flags().StringP("base", "B", "", "Filter by base branch") prListCmd.Flags().StringSliceP("label", "l", nil, "Filter by label") prListCmd.Flags().StringP("assignee", "a", "", "Filter by assignee") + prCmd.AddCommand(prViewCmd) prViewCmd.Flags().BoolP("web", "w", false, "Open a pull request in the browser") } @@ -65,6 +66,11 @@ is displayed. With '--web', open the pull request in a web browser instead.`, RunE: prView, } +var prCloseCmd = &cobra.Command{ + Use: "close [{ | }]", + Short: "Close a pull request", + RunE: prClose, +} func prStatus(cmd *cobra.Command, args []string) error { ctx := contextForCommand(cmd) @@ -328,6 +334,38 @@ func prView(cmd *cobra.Command, args []string) error { } } +func prClose(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.Closed { + fmt.Fprintf(colorableErr(cmd), "%s Pull request #%d is already closed\n", utils.Yellow("!"), pr.Number) + return nil + } + + err = api.PullRequestClose(apiClient, baseRepo, *pr) + if err != nil { + return fmt.Errorf("API call failed:%w", err) + } + + fmt.Fprintf(colorableErr(cmd), "%s Closed pull request #%d\n", utils.Red("✔"), 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 19f6c69854588c154d0fe4c456befc3f070b5635 Mon Sep 17 00:00:00 2001 From: Corey Johnson Date: Thu, 30 Apr 2020 11:27:11 -0700 Subject: [PATCH 03/23] Actually make it work --- api/queries_pr.go | 2 ++ command/pr.go | 2 ++ 2 files changed, 4 insertions(+) diff --git a/api/queries_pr.go b/api/queries_pr.go index 6af709947..3bb56b80f 100644 --- a/api/queries_pr.go +++ b/api/queries_pr.go @@ -348,10 +348,12 @@ func PullRequestByNumber(client *Client, repo ghrepo.Interface, number int) (*Pu query($owner: String!, $repo: String!, $pr_number: Int!) { repository(owner: $owner, name: $repo) { pullRequest(number: $pr_number) { + id url number title state + closed body author { login diff --git a/command/pr.go b/command/pr.go index 49e1f3c9a..5799867c5 100644 --- a/command/pr.go +++ b/command/pr.go @@ -351,6 +351,8 @@ func prClose(cmd *cobra.Command, args []string) error { return err } + fmt.Printf("🌭 %+v\n", pr) + if pr.Closed { fmt.Fprintf(colorableErr(cmd), "%s Pull request #%d is already closed\n", utils.Yellow("!"), pr.Number) return nil From af6eaa8ca2ec5ee37334b95851e0d13e4fb950d6 Mon Sep 17 00:00:00 2001 From: Corey Johnson Date: Thu, 30 Apr 2020 11:41:32 -0700 Subject: [PATCH 04/23] Hot dog --- command/pr.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/command/pr.go b/command/pr.go index 5799867c5..49e1f3c9a 100644 --- a/command/pr.go +++ b/command/pr.go @@ -351,8 +351,6 @@ func prClose(cmd *cobra.Command, args []string) error { return err } - fmt.Printf("🌭 %+v\n", pr) - if pr.Closed { fmt.Fprintf(colorableErr(cmd), "%s Pull request #%d is already closed\n", utils.Yellow("!"), pr.Number) return nil From 4bf778b1365adccf8cf4dcc1a6a703177d27e9b0 Mon Sep 17 00:00:00 2001 From: Corey Johnson Date: Thu, 30 Apr 2020 11:41:39 -0700 Subject: [PATCH 05/23] require one arg --- command/pr.go | 1 + 1 file changed, 1 insertion(+) diff --git a/command/pr.go b/command/pr.go index 49e1f3c9a..d6873b4d7 100644 --- a/command/pr.go +++ b/command/pr.go @@ -69,6 +69,7 @@ With '--web', open the pull request in a web browser instead.`, var prCloseCmd = &cobra.Command{ Use: "close [{ | }]", Short: "Close a pull request", + Args: cobra.ExactArgs(1), RunE: prClose, } From e93b18a9af8bf745d98968834d82f14a98dd09ff Mon Sep 17 00:00:00 2001 From: Corey Johnson Date: Thu, 30 Apr 2020 11:41:48 -0700 Subject: [PATCH 06/23] Add already open test --- command/pr_test.go | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/command/pr_test.go b/command/pr_test.go index a133e04f9..bf21d7627 100644 --- a/command/pr_test.go +++ b/command/pr_test.go @@ -51,7 +51,6 @@ func RunCommand(cmd *cobra.Command, args string) (*cmdOut, error) { cmd.SetOut(&outBuf) errBuf := bytes.Buffer{} cmd.SetErr(&errBuf) - // Reset flag values so they don't leak between tests // FIXME: change how we initialize Cobra commands to render this hack unnecessary cmd.Flags().VisitAll(func(f *pflag.Flag) { @@ -825,3 +824,28 @@ func TestPrClose(t *testing.T) { t.Fatalf("output did not match regexp /%s/\n> output\n%q\n", r, output.Stderr()) } } + +func TestPrClose_alreadyClosed(t *testing.T) { + initBlankContext("", "OWNER/REPO", "master") + http := initFakeHTTP() + http.StubRepoResponse("OWNER", "REPO") + + http.StubResponse(200, bytes.NewBufferString(` + { "data": { "repository": { + "pullRequest": { "number": 101, "closed": true } + } } } + `)) + + http.StubResponse(200, bytes.NewBufferString(`{"id": "THE-ID"}`)) + + output, err := RunCommand(prCloseCmd, "pr close 101") + if err != nil { + t.Fatalf("error running command `pr close`: %v", err) + } + + r := regexp.MustCompile(`Pull request #101 is already closed`) + + if !r.MatchString(output.Stderr()) { + t.Fatalf("output did not match regexp /%s/\n> output\n%q\n", r, output.Stderr()) + } +} From 38f9e819c56762d5b25db9b7e2bfe4e009820f72 Mon Sep 17 00:00:00 2001 From: Corey Johnson Date: Fri, 1 May 2020 12:00:02 -0700 Subject: [PATCH 07/23] Add test for reopen --- command/pr_test.go | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/command/pr_test.go b/command/pr_test.go index bf21d7627..af876bf0a 100644 --- a/command/pr_test.go +++ b/command/pr_test.go @@ -849,3 +849,28 @@ func TestPrClose_alreadyClosed(t *testing.T) { t.Fatalf("output did not match regexp /%s/\n> output\n%q\n", r, output.Stderr()) } } + +func TestPRReopen(t *testing.T) { + initBlankContext("", "OWNER/REPO", "master") + http := initFakeHTTP() + http.StubRepoResponse("OWNER", "REPO") + + http.StubResponse(200, bytes.NewBufferString(` + { "data": { "repository": { + "pullRequest": { "number": 666, "closed": true} + } } } + `)) + + http.StubResponse(200, bytes.NewBufferString(`{"id": "THE-ID"}`)) + + output, err := RunCommand(prReopenCmd, "pr reopen 666") + if err != nil { + t.Fatalf("error running command `pr reopen`: %v", err) + } + + r := regexp.MustCompile(`Reopened pull request #666`) + + if !r.MatchString(output.Stderr()) { + t.Fatalf("output did not match regexp /%s/\n> output\n%q\n", r, output.Stderr()) + } +} From 0bb1d2018ab72b0ab8cbc8bf305f56880a489ecf Mon Sep 17 00:00:00 2001 From: Corey Johnson Date: Fri, 1 May 2020 12:00:13 -0700 Subject: [PATCH 08/23] Add code to reopen --- api/queries_pr.go | 19 +++++++++++++++++++ command/pr.go | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/api/queries_pr.go b/api/queries_pr.go index 3bb56b80f..3ae9ba98a 100644 --- a/api/queries_pr.go +++ b/api/queries_pr.go @@ -780,6 +780,25 @@ func PullRequestClose(client *Client, repo ghrepo.Interface, pr PullRequest) err return err } +func PullRequestReopen(client *Client, repo ghrepo.Interface, pr PullRequest) error { + var mutation struct { + ReopenPullRequest struct { + PullRequest struct { + ID githubv4.ID + } + } `graphql:"reopenPullRequest(input: $input)"` + } + + input := githubv4.ReopenPullRequestInput{ + 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 d6873b4d7..fe359f1d6 100644 --- a/command/pr.go +++ b/command/pr.go @@ -23,6 +23,7 @@ func init() { prCmd.AddCommand(prCreateCmd) prCmd.AddCommand(prStatusCmd) prCmd.AddCommand(prCloseCmd) + prCmd.AddCommand(prReopenCmd) prCmd.AddCommand(prListCmd) prListCmd.Flags().IntP("limit", "L", 30, "Maximum number of items to fetch") @@ -72,6 +73,12 @@ var prCloseCmd = &cobra.Command{ Args: cobra.ExactArgs(1), RunE: prClose, } +var prReopenCmd = &cobra.Command{ + Use: "reopen [{ | }]", + Short: "Reopen a pull request", + Args: cobra.ExactArgs(1), + RunE: prReopen, +} func prStatus(cmd *cobra.Command, args []string) error { ctx := contextForCommand(cmd) @@ -367,6 +374,38 @@ func prClose(cmd *cobra.Command, args []string) error { return nil } +func prReopen(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.Closed == false { + fmt.Fprintf(colorableErr(cmd), "%s Pull request #%d is already open\n", utils.Yellow("!"), pr.Number) + return nil + } + + err = api.PullRequestReopen(apiClient, baseRepo, *pr) + if err != nil { + return fmt.Errorf("API call failed:%w", err) + } + + fmt.Fprintf(colorableErr(cmd), "%s Reopened pull request #%d\n", utils.Red("✔"), 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 bc623a7a23bc7062b25a6e7ab115947f2b2313e5 Mon Sep 17 00:00:00 2001 From: Corey Johnson Date: Fri, 1 May 2020 12:07:23 -0700 Subject: [PATCH 09/23] Make it green --- command/pr.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/command/pr.go b/command/pr.go index fe359f1d6..5742ed158 100644 --- a/command/pr.go +++ b/command/pr.go @@ -401,7 +401,7 @@ func prReopen(cmd *cobra.Command, args []string) error { return fmt.Errorf("API call failed:%w", err) } - fmt.Fprintf(colorableErr(cmd), "%s Reopened pull request #%d\n", utils.Red("✔"), pr.Number) + fmt.Fprintf(colorableErr(cmd), "%s Reopened pull request #%d\n", utils.Green("✔"), pr.Number) return nil } From b8ff489bb5766c8c27bcf11247a94f3f2c41d3e8 Mon Sep 17 00:00:00 2001 From: Corey Johnson Date: Fri, 1 May 2020 12:07:30 -0700 Subject: [PATCH 10/23] Add already open test --- command/pr_test.go | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/command/pr_test.go b/command/pr_test.go index af876bf0a..8585dd83f 100644 --- a/command/pr_test.go +++ b/command/pr_test.go @@ -874,3 +874,28 @@ func TestPRReopen(t *testing.T) { t.Fatalf("output did not match regexp /%s/\n> output\n%q\n", r, output.Stderr()) } } + +func TestPRReopen_alreadyOpen(t *testing.T) { + initBlankContext("", "OWNER/REPO", "master") + http := initFakeHTTP() + http.StubRepoResponse("OWNER", "REPO") + + http.StubResponse(200, bytes.NewBufferString(` + { "data": { "repository": { + "pullRequest": { "number": 666, "closed": false} + } } } + `)) + + http.StubResponse(200, bytes.NewBufferString(`{"id": "THE-ID"}`)) + + output, err := RunCommand(prReopenCmd, "pr reopen 666") + if err != nil { + t.Fatalf("error running command `pr reopen`: %v", err) + } + + r := regexp.MustCompile(`Pull request #666 is already open`) + + if !r.MatchString(output.Stderr()) { + t.Fatalf("output did not match regexp /%s/\n> output\n%q\n", r, output.Stderr()) + } +} From 63b20baa1be4d2b45881eabe67b05e6680243f56 Mon Sep 17 00:00:00 2001 From: Corey Johnson Date: Fri, 1 May 2020 13:58:52 -0700 Subject: [PATCH 11/23] Add merged test --- command/pr_test.go | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/command/pr_test.go b/command/pr_test.go index 8585dd83f..0c92f2beb 100644 --- a/command/pr_test.go +++ b/command/pr_test.go @@ -899,3 +899,28 @@ func TestPRReopen_alreadyOpen(t *testing.T) { t.Fatalf("output did not match regexp /%s/\n> output\n%q\n", r, output.Stderr()) } } + +func TestPRReopen_merged(t *testing.T) { + initBlankContext("", "OWNER/REPO", "master") + http := initFakeHTTP() + http.StubRepoResponse("OWNER", "REPO") + + http.StubResponse(200, bytes.NewBufferString(` + { "data": { "repository": { + "pullRequest": { "number": 666, "closed": true, "state": "MERGED"} + } } } + `)) + + http.StubResponse(200, bytes.NewBufferString(`{"id": "THE-ID"}`)) + + output, err := RunCommand(prReopenCmd, "pr reopen 666") + if err != nil { + t.Fatalf("error running command `pr reopen`: %v", err) + } + + r := regexp.MustCompile(`Pull request #666 can't be reopened because it was merged.`) + + if !r.MatchString(output.Stderr()) { + t.Fatalf("output did not match regexp /%s/\n> output\n%q\n", r, output.Stderr()) + } +} From 922352753a9b5820503bee5b0353bacdceb43222 Mon Sep 17 00:00:00 2001 From: Corey Johnson Date: Fri, 1 May 2020 14:08:30 -0700 Subject: [PATCH 12/23] Add merged exit --- command/pr.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/command/pr.go b/command/pr.go index 5742ed158..8e3bba4e3 100644 --- a/command/pr.go +++ b/command/pr.go @@ -391,6 +391,11 @@ func prReopen(cmd *cobra.Command, args []string) error { return err } + if pr.State == "MERGED" { + fmt.Fprintf(colorableErr(cmd), "%s Pull request #%d can't be reopened because it was merged.", utils.Red("!"), pr.Number) + return nil + } + if pr.Closed == false { fmt.Fprintf(colorableErr(cmd), "%s Pull request #%d is already open\n", utils.Yellow("!"), pr.Number) return nil From 846425fe5e834a394d4e8f5d3f660e07f8264f09 Mon Sep 17 00:00:00 2001 From: Corey Johnson Date: Fri, 1 May 2020 14:16:49 -0700 Subject: [PATCH 13/23] simplified boolean comparison --- command/pr.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/command/pr.go b/command/pr.go index 8e3bba4e3..2d4b63d61 100644 --- a/command/pr.go +++ b/command/pr.go @@ -392,11 +392,11 @@ func prReopen(cmd *cobra.Command, args []string) error { } if pr.State == "MERGED" { - fmt.Fprintf(colorableErr(cmd), "%s Pull request #%d can't be reopened because it was merged.", utils.Red("!"), pr.Number) + fmt.Fprintf(colorableErr(cmd), "%s Pull request #%d can't be reopened because it was already merged.\n", utils.Red("!"), pr.Number) return nil } - if pr.Closed == false { + if !pr.Closed { fmt.Fprintf(colorableErr(cmd), "%s Pull request #%d is already open\n", utils.Yellow("!"), pr.Number) return nil } From fad697cbaf145cf49597c977187c42ca124f0616 Mon Sep 17 00:00:00 2001 From: Corey Johnson Date: Fri, 1 May 2020 14:18:01 -0700 Subject: [PATCH 14/23] Names --- command/pr_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/command/pr_test.go b/command/pr_test.go index 0c92f2beb..e89115e1a 100644 --- a/command/pr_test.go +++ b/command/pr_test.go @@ -900,7 +900,7 @@ func TestPRReopen_alreadyOpen(t *testing.T) { } } -func TestPRReopen_merged(t *testing.T) { +func TestPRReopen_alreadyMerged(t *testing.T) { initBlankContext("", "OWNER/REPO", "master") http := initFakeHTTP() http.StubRepoResponse("OWNER", "REPO") From 4020084f029d02776c2ddab11971423e28acb5ad Mon Sep 17 00:00:00 2001 From: Corey Johnson Date: Fri, 1 May 2020 14:54:38 -0700 Subject: [PATCH 15/23] Fix test --- command/pr_test.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/command/pr_test.go b/command/pr_test.go index e89115e1a..c70a5ed8a 100644 --- a/command/pr_test.go +++ b/command/pr_test.go @@ -918,9 +918,10 @@ func TestPRReopen_alreadyMerged(t *testing.T) { t.Fatalf("error running command `pr reopen`: %v", err) } - r := regexp.MustCompile(`Pull request #666 can't be reopened because it was merged.`) + r := regexp.MustCompile(`Pull request #666 can't be reopened because it was already merged.`) if !r.MatchString(output.Stderr()) { t.Fatalf("output did not match regexp /%s/\n> output\n%q\n", r, output.Stderr()) } + } From 1ee31db033bad37574d06dc0e56c02add0e3f8f6 Mon Sep 17 00:00:00 2001 From: Corey Johnson Date: Mon, 4 May 2020 10:10:03 -0700 Subject: [PATCH 16/23] Add "merged" message --- command/pr.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/command/pr.go b/command/pr.go index 2d4b63d61..a9cbe57ed 100644 --- a/command/pr.go +++ b/command/pr.go @@ -359,7 +359,10 @@ func prClose(cmd *cobra.Command, args []string) error { return err } - if pr.Closed { + if pr.State == "MERGED" { + fmt.Fprintf(colorableErr(cmd), "%s Can't close pull request #%d because it was already merged\n", utils.Yellow("!"), pr.Number) + return nil + } else if pr.Closed { fmt.Fprintf(colorableErr(cmd), "%s Pull request #%d is already closed\n", utils.Yellow("!"), pr.Number) return nil } From f7be93b135f447dee7e5216e4e39500e70ad4690 Mon Sep 17 00:00:00 2001 From: Corey Johnson Date: Mon, 4 May 2020 10:11:24 -0700 Subject: [PATCH 17/23] use less words --- command/pr.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/command/pr.go b/command/pr.go index a9cbe57ed..16d1c1e93 100644 --- a/command/pr.go +++ b/command/pr.go @@ -360,7 +360,7 @@ func prClose(cmd *cobra.Command, args []string) error { } if pr.State == "MERGED" { - fmt.Fprintf(colorableErr(cmd), "%s Can't close pull request #%d because it was already merged\n", utils.Yellow("!"), pr.Number) + fmt.Fprintf(colorableErr(cmd), "%s Pull request #%d was already merged\n", utils.Yellow("!"), pr.Number) return nil } else if pr.Closed { fmt.Fprintf(colorableErr(cmd), "%s Pull request #%d is already closed\n", utils.Yellow("!"), pr.Number) From 083693bc051ea0c34967521fe4ae1581b2d113a3 Mon Sep 17 00:00:00 2001 From: Corey Johnson Date: Mon, 4 May 2020 10:15:47 -0700 Subject: [PATCH 18/23] Update usage string --- command/pr.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/command/pr.go b/command/pr.go index 16d1c1e93..ebeb99fc2 100644 --- a/command/pr.go +++ b/command/pr.go @@ -68,13 +68,13 @@ 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, From 1e88226b2b6bd47861d62ed657f9489e3c5bccda Mon Sep 17 00:00:00 2001 From: Corey Johnson Date: Mon, 4 May 2020 10:16:30 -0700 Subject: [PATCH 19/23] Add space --- command/pr.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/command/pr.go b/command/pr.go index ebeb99fc2..04863f3f8 100644 --- a/command/pr.go +++ b/command/pr.go @@ -369,7 +369,7 @@ func prClose(cmd *cobra.Command, args []string) error { err = api.PullRequestClose(apiClient, baseRepo, *pr) if err != nil { - return fmt.Errorf("API call failed:%w", err) + return fmt.Errorf("API call failed: %w", err) } fmt.Fprintf(colorableErr(cmd), "%s Closed pull request #%d\n", utils.Red("✔"), pr.Number) @@ -406,7 +406,7 @@ func prReopen(cmd *cobra.Command, args []string) error { err = api.PullRequestReopen(apiClient, baseRepo, *pr) if err != nil { - return fmt.Errorf("API call failed:%w", err) + return fmt.Errorf("API call failed: %w", err) } fmt.Fprintf(colorableErr(cmd), "%s Reopened pull request #%d\n", utils.Green("✔"), pr.Number) From 5cc60c669effef621a13d550b30f39f08acbb97d Mon Sep 17 00:00:00 2001 From: Corey Johnson Date: Mon, 4 May 2020 10:19:54 -0700 Subject: [PATCH 20/23] Take in a pointer --- api/queries_pr.go | 4 ++-- command/pr.go | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/api/queries_pr.go b/api/queries_pr.go index 3ae9ba98a..ccbe1f390 100644 --- a/api/queries_pr.go +++ b/api/queries_pr.go @@ -761,7 +761,7 @@ loop: return &res, nil } -func PullRequestClose(client *Client, repo ghrepo.Interface, pr PullRequest) error { +func PullRequestClose(client *Client, repo ghrepo.Interface, pr *PullRequest) error { var mutation struct { ClosePullRequest struct { PullRequest struct { @@ -780,7 +780,7 @@ func PullRequestClose(client *Client, repo ghrepo.Interface, pr PullRequest) err return err } -func PullRequestReopen(client *Client, repo ghrepo.Interface, pr PullRequest) error { +func PullRequestReopen(client *Client, repo ghrepo.Interface, pr *PullRequest) error { var mutation struct { ReopenPullRequest struct { PullRequest struct { diff --git a/command/pr.go b/command/pr.go index 04863f3f8..b1736169a 100644 --- a/command/pr.go +++ b/command/pr.go @@ -367,7 +367,7 @@ func prClose(cmd *cobra.Command, args []string) error { return nil } - err = api.PullRequestClose(apiClient, baseRepo, *pr) + err = api.PullRequestClose(apiClient, baseRepo, pr) if err != nil { return fmt.Errorf("API call failed: %w", err) } @@ -395,7 +395,7 @@ func prReopen(cmd *cobra.Command, args []string) error { } if pr.State == "MERGED" { - fmt.Fprintf(colorableErr(cmd), "%s Pull request #%d can't be reopened because it was already merged.\n", utils.Red("!"), pr.Number) + fmt.Fprintf(colorableErr(cmd), "%s Pull request #%d can't be reopened because it was already merged\n", utils.Red("!"), pr.Number) return nil } @@ -404,7 +404,7 @@ func prReopen(cmd *cobra.Command, args []string) error { return nil } - err = api.PullRequestReopen(apiClient, baseRepo, *pr) + err = api.PullRequestReopen(apiClient, baseRepo, pr) if err != nil { return fmt.Errorf("API call failed: %w", err) } From 2f075fca73495bed7849e0734cb24cb4be703ee6 Mon Sep 17 00:00:00 2001 From: Corey Johnson Date: Mon, 4 May 2020 10:25:38 -0700 Subject: [PATCH 21/23] Return an error if the pr was already merged --- command/pr.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/command/pr.go b/command/pr.go index b1736169a..f57daed50 100644 --- a/command/pr.go +++ b/command/pr.go @@ -395,8 +395,8 @@ func prReopen(cmd *cobra.Command, args []string) error { } if pr.State == "MERGED" { - fmt.Fprintf(colorableErr(cmd), "%s Pull request #%d can't be reopened because it was already merged\n", utils.Red("!"), pr.Number) - return nil + err := fmt.Errorf("%s Pull request #%d can't be reopened because it was already merged", utils.Red("!"), pr.Number) + return err } if !pr.Closed { From 3b8f4794b497a3c81a0fb05c86d8a876182b82c1 Mon Sep 17 00:00:00 2001 From: Corey Johnson Date: Mon, 4 May 2020 10:31:31 -0700 Subject: [PATCH 22/23] Update test --- command/pr_test.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/command/pr_test.go b/command/pr_test.go index c70a5ed8a..d851eb838 100644 --- a/command/pr_test.go +++ b/command/pr_test.go @@ -914,13 +914,13 @@ func TestPRReopen_alreadyMerged(t *testing.T) { http.StubResponse(200, bytes.NewBufferString(`{"id": "THE-ID"}`)) output, err := RunCommand(prReopenCmd, "pr reopen 666") - if err != nil { - t.Fatalf("error running command `pr reopen`: %v", err) + if err == nil { + t.Fatalf("expected an error running command `pr reopen`: %v", err) } - r := regexp.MustCompile(`Pull request #666 can't be reopened because it was already merged.`) + r := regexp.MustCompile(`Pull request #666 can't be reopened because it was already merged`) - if !r.MatchString(output.Stderr()) { + if !r.MatchString(err.Error()) { t.Fatalf("output did not match regexp /%s/\n> output\n%q\n", r, output.Stderr()) } From fef11b348947ac5583e3c871c9b898012970663c Mon Sep 17 00:00:00 2001 From: Corey Johnson Date: Mon, 4 May 2020 10:44:20 -0700 Subject: [PATCH 23/23] Merged prs return error --- command/pr.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/command/pr.go b/command/pr.go index f57daed50..c4b268abe 100644 --- a/command/pr.go +++ b/command/pr.go @@ -360,8 +360,8 @@ func prClose(cmd *cobra.Command, args []string) error { } if pr.State == "MERGED" { - fmt.Fprintf(colorableErr(cmd), "%s Pull request #%d was already merged\n", utils.Yellow("!"), pr.Number) - return nil + err := fmt.Errorf("%s Pull request #%d can't be closed because it was already merged", utils.Red("!"), pr.Number) + return err } else if pr.Closed { fmt.Fprintf(colorableErr(cmd), "%s Pull request #%d is already closed\n", utils.Yellow("!"), pr.Number) return nil