diff --git a/command/pr.go b/command/pr.go index 78c576ffe..d00bfd7bc 100644 --- a/command/pr.go +++ b/command/pr.go @@ -219,13 +219,30 @@ func prView(cmd *cobra.Command, args []string) error { return err } + apiClient, err := apiClientForContext(ctx) + if err != nil { + return err + } + var openURL string if len(args) > 0 { if prNumber, err := strconv.Atoi(args[0]); err == nil { - // TODO: move URL generation into GitHubRepository - openURL = fmt.Sprintf("https://github.com/%s/%s/pull/%d", baseRepo.RepoOwner(), baseRepo.RepoName(), prNumber) + pr, err := api.PullRequestByNumber(apiClient, baseRepo, prNumber) + if err != nil { + return err + } + openURL = pr.URL } else { - return fmt.Errorf("invalid pull request number: '%s'", args[0]) + prRE := regexp.MustCompile(`^https://github\.com/[^/]+/[^/]+/pull/\d+`) + if m := prRE.FindStringSubmatch(args[0]); m != nil { + openURL = m[0] + } else { + pr, err := api.PullRequestForBranch(apiClient, baseRepo, args[0]) + if err != nil { + return err + } + openURL = pr.URL + } } } else { prNumber, branchWithOwner, err := prSelectorForCurrentBranch(ctx) @@ -236,11 +253,6 @@ func prView(cmd *cobra.Command, args []string) error { if prNumber > 0 { openURL = fmt.Sprintf("https://github.com/%s/%s/pull/%d", baseRepo.RepoOwner(), baseRepo.RepoName(), prNumber) } else { - apiClient, err := apiClientForContext(ctx) - if err != nil { - return err - } - pr, err := api.PullRequestForBranch(apiClient, baseRepo, branchWithOwner) if err != nil { return err diff --git a/command/pr_test.go b/command/pr_test.go index 9e0da8331..f271560a5 100644 --- a/command/pr_test.go +++ b/command/pr_test.go @@ -251,7 +251,103 @@ func TestPRView_numberArg(t *testing.T) { t.Fatal("expected a command to run") } url := seenCmd.Args[len(seenCmd.Args)-1] - if url != "https://github.com/OWNER/REPO/pull/23" { - t.Errorf("got: %q", url) - } + eq(t, url, "https://github.com/OWNER/REPO/pull/23") +} + +func TestPRView_urlArg(t *testing.T) { + initBlankContext("OWNER/REPO", "master") + initFakeHTTP() + + var seenCmd *exec.Cmd + restoreCmd := utils.SetPrepareCmd(func(cmd *exec.Cmd) utils.Runnable { + seenCmd = cmd + return &outputStub{} + }) + defer restoreCmd() + + output, err := RunCommand(prViewCmd, "pr view https://github.com/OWNER/REPO/pull/23/files") + if err != nil { + t.Errorf("error running command `pr view`: %v", err) + } + + if output == "" { + t.Errorf("command output expected got an empty string") + } + + if seenCmd == nil { + t.Fatal("expected a command to run") + } + url := seenCmd.Args[len(seenCmd.Args)-1] + eq(t, url, "https://github.com/OWNER/REPO/pull/23") +} + +func TestPRView_branchArg(t *testing.T) { + initBlankContext("OWNER/REPO", "master") + http := initFakeHTTP() + + http.StubResponse(200, bytes.NewBufferString(` + { "data": { "repository": { "pullRequests": { "nodes": [ + { "headRefName": "blueberries", + "isCrossRepository": false, + "url": "https://github.com/OWNER/REPO/pull/23" } + ] } } } } + `)) + + var seenCmd *exec.Cmd + restoreCmd := utils.SetPrepareCmd(func(cmd *exec.Cmd) utils.Runnable { + seenCmd = cmd + return &outputStub{} + }) + defer restoreCmd() + + output, err := RunCommand(prViewCmd, "pr view blueberries") + if err != nil { + t.Errorf("error running command `pr view`: %v", err) + } + + if output == "" { + t.Errorf("command output expected got an empty string") + } + + if seenCmd == nil { + t.Fatal("expected a command to run") + } + url := seenCmd.Args[len(seenCmd.Args)-1] + eq(t, url, "https://github.com/OWNER/REPO/pull/23") +} + +func TestPRView_branchWithOwnerArg(t *testing.T) { + initBlankContext("OWNER/REPO", "master") + http := initFakeHTTP() + + http.StubResponse(200, bytes.NewBufferString(` + { "data": { "repository": { "pullRequests": { "nodes": [ + { "headRefName": "blueberries", + "isCrossRepository": true, + "headRepositoryOwner": { "login": "hubot" }, + "url": "https://github.com/hubot/REPO/pull/23" } + ] } } } } + `)) + + var seenCmd *exec.Cmd + restoreCmd := utils.SetPrepareCmd(func(cmd *exec.Cmd) utils.Runnable { + seenCmd = cmd + return &outputStub{} + }) + defer restoreCmd() + + output, err := RunCommand(prViewCmd, "pr view hubot:blueberries") + if err != nil { + t.Errorf("error running command `pr view`: %v", err) + } + + if output == "" { + t.Errorf("command output expected got an empty string") + } + + if seenCmd == nil { + t.Fatal("expected a command to run") + } + url := seenCmd.Args[len(seenCmd.Args)-1] + eq(t, url, "https://github.com/hubot/REPO/pull/23") }