X Tutup
Skip to content

Commit 508f678

Browse files
committed
Have PullRequestForBranch accept "owner:branch" value for forks
When on a `patch-1` branch locally, `gh pr view` would happily open the first open PR it finds with "patch-1" as its head, even those coming from forks.
1 parent c7a38b6 commit 508f678

File tree

5 files changed

+77
-81
lines changed

5 files changed

+77
-81
lines changed

api/queries_pr.go

Lines changed: 40 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package api
22

33
import (
44
"fmt"
5+
"strings"
56
)
67

78
type PullRequestsPayload struct {
@@ -141,7 +142,6 @@ func PullRequests(client *Client, ghRepo Repo, currentBranch, currentUsername st
141142
title
142143
url
143144
headRefName
144-
headRefName
145145
headRepositoryOwner {
146146
login
147147
}
@@ -172,7 +172,7 @@ func PullRequests(client *Client, ghRepo Repo, currentBranch, currentUsername st
172172
}
173173
query($owner: String!, $repo: String!, $headRefName: String!, $viewerQuery: String!, $reviewerQuery: String!, $per_page: Int = 10) {
174174
repository(owner: $owner, name: $repo) {
175-
pullRequests(headRefName: $headRefName, states: OPEN, first: 1) {
175+
pullRequests(headRefName: $headRefName, states: OPEN, first: $per_page) {
176176
edges {
177177
node {
178178
...prWithReviews
@@ -209,12 +209,17 @@ func PullRequests(client *Client, ghRepo Repo, currentBranch, currentUsername st
209209
viewerQuery := fmt.Sprintf("repo:%s/%s state:open is:pr author:%s", owner, repo, currentUsername)
210210
reviewerQuery := fmt.Sprintf("repo:%s/%s state:open review-requested:%s", owner, repo, currentUsername)
211211

212+
branchWithoutOwner := currentBranch
213+
if idx := strings.Index(currentBranch, ":"); idx >= 0 {
214+
branchWithoutOwner = currentBranch[idx+1:]
215+
}
216+
212217
variables := map[string]interface{}{
213218
"viewerQuery": viewerQuery,
214219
"reviewerQuery": reviewerQuery,
215220
"owner": owner,
216221
"repo": repo,
217-
"headRefName": currentBranch,
222+
"headRefName": branchWithoutOwner,
218223
}
219224

220225
var resp response
@@ -235,7 +240,9 @@ func PullRequests(client *Client, ghRepo Repo, currentBranch, currentUsername st
235240

236241
var currentPR *PullRequest
237242
for _, edge := range resp.Repository.PullRequests.Edges {
238-
currentPR = &edge.Node
243+
if edge.Node.HeadLabel() == currentBranch {
244+
currentPR = &edge.Node
245+
}
239246
}
240247

241248
payload := PullRequestsPayload{
@@ -289,36 +296,42 @@ func PullRequestByNumber(client *Client, ghRepo Repo, number int) (*PullRequest,
289296
return &resp.Repository.PullRequest, nil
290297
}
291298

292-
func PullRequestsForBranch(client *Client, ghRepo Repo, branch string) ([]PullRequest, error) {
299+
func PullRequestForBranch(client *Client, ghRepo Repo, branch string) (*PullRequest, error) {
293300
type response struct {
294301
Repository struct {
295302
PullRequests struct {
296-
Edges []struct {
297-
Node PullRequest
298-
}
303+
Nodes []PullRequest
299304
}
300305
}
301306
}
302307

303308
query := `
304-
query($owner: String!, $repo: String!, $headRefName: String!) {
305-
repository(owner: $owner, name: $repo) {
306-
pullRequests(headRefName: $headRefName, states: OPEN, first: 1) {
307-
edges {
308-
node {
309-
number
310-
title
311-
url
312-
}
313-
}
314-
}
315-
}
316-
}`
309+
query($owner: String!, $repo: String!, $headRefName: String!) {
310+
repository(owner: $owner, name: $repo) {
311+
pullRequests(headRefName: $headRefName, states: OPEN, first: 30) {
312+
nodes {
313+
number
314+
title
315+
url
316+
headRefName
317+
headRepositoryOwner {
318+
login
319+
}
320+
isCrossRepository
321+
}
322+
}
323+
}
324+
}`
325+
326+
branchWithoutOwner := branch
327+
if idx := strings.Index(branch, ":"); idx >= 0 {
328+
branchWithoutOwner = branch[idx+1:]
329+
}
317330

318331
variables := map[string]interface{}{
319332
"owner": ghRepo.RepoOwner(),
320333
"repo": ghRepo.RepoName(),
321-
"headRefName": branch,
334+
"headRefName": branchWithoutOwner,
322335
}
323336

324337
var resp response
@@ -327,12 +340,13 @@ func PullRequestsForBranch(client *Client, ghRepo Repo, branch string) ([]PullRe
327340
return nil, err
328341
}
329342

330-
prs := []PullRequest{}
331-
for _, edge := range resp.Repository.PullRequests.Edges {
332-
prs = append(prs, edge.Node)
343+
for _, pr := range resp.Repository.PullRequests.Nodes {
344+
if pr.HeadLabel() == branch {
345+
return &pr, nil
346+
}
333347
}
334348

335-
return prs, nil
349+
return nil, fmt.Errorf("no open pull requests found for branch %q", branch)
336350
}
337351

338352
func CreatePullRequest(client *Client, ghRepo Repo, params map[string]interface{}) (*PullRequest, error) {

command/pr.go

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -243,13 +243,11 @@ func prView(cmd *cobra.Command, args []string) error {
243243
return err
244244
}
245245

246-
prs, err := api.PullRequestsForBranch(apiClient, baseRepo, currentBranch)
246+
pr, err := api.PullRequestForBranch(apiClient, baseRepo, currentBranch)
247247
if err != nil {
248248
return err
249-
} else if len(prs) < 1 {
250-
return fmt.Errorf("the '%s' branch has no open pull requests", currentBranch)
251249
}
252-
openURL = prs[0].URL
250+
openURL = pr.URL
253251
}
254252

255253
fmt.Printf("Opening %s in your browser.\n", openURL)

command/pr_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ func eq(t *testing.T, got interface{}, expected interface{}) {
2222
}
2323

2424
func TestPRStatus(t *testing.T) {
25-
initBlankContext("OWNER/REPO", "master")
25+
initBlankContext("OWNER/REPO", "blueberries")
2626
http := initFakeHTTP()
2727

2828
jsonFile, _ := os.Open("../test/fixtures/prStatus.json")
@@ -100,7 +100,7 @@ func TestPRList_filtering(t *testing.T) {
100100
}
101101

102102
func TestPRView(t *testing.T) {
103-
initBlankContext("OWNER/REPO", "master")
103+
initBlankContext("OWNER/REPO", "blueberries")
104104
http := initFakeHTTP()
105105

106106
jsonFile, _ := os.Open("../test/fixtures/prView.json")
@@ -148,7 +148,7 @@ func TestPRView_NoActiveBranch(t *testing.T) {
148148
defer restoreCmd()
149149

150150
output, err := test.RunCommand(RootCmd, "pr view")
151-
if err == nil || err.Error() != "the 'master' branch has no open pull requests" {
151+
if err == nil || err.Error() != `no open pull requests found for branch "master"` {
152152
t.Errorf("error running command `pr view`: %v", err)
153153
}
154154

test/fixtures/prStatus.json

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,11 @@
77
"number": 10,
88
"title": "Blueberries are a good fruit",
99
"url": "https://github.com/github/gh-cli/pull/10",
10-
"headRefName": "[blueberries]"
10+
"headRefName": "blueberries",
11+
"headRepositoryOwner": {
12+
"login": "OWNER"
13+
},
14+
"isCrossRepository": false
1115
}
1216
}
1317
]
@@ -20,7 +24,7 @@
2024
"number": 8,
2125
"title": "Strawberries are not actually berries",
2226
"url": "https://github.com/github/gh-cli/pull/8",
23-
"headRefName": "[strawberries]"
27+
"headRefName": "strawberries"
2428
}
2529
}
2630
],
@@ -33,15 +37,15 @@
3337
"number": 9,
3438
"title": "Apples are tasty",
3539
"url": "https://github.com/github/gh-cli/pull/9",
36-
"headRefName": "[apples]"
40+
"headRefName": "apples"
3741
}
3842
},
3943
{
4044
"node": {
4145
"number": 11,
4246
"title": "Figs are my favorite",
4347
"url": "https://github.com/github/gh-cli/pull/1",
44-
"headRefName": "[figs]"
48+
"headRefName": "figs"
4549
}
4650
}
4751
],

test/fixtures/prView.json

Lines changed: 24 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,30 @@
1-
{"data":{
2-
"repository": {
3-
"pullRequests": {
4-
"edges": [
5-
{
6-
"node": {
1+
{
2+
"data": {
3+
"repository": {
4+
"pullRequests": {
5+
"nodes": [
6+
{
7+
"number": 12,
8+
"title": "Blueberries are from a fork",
9+
"url": "https://github.com/OWNER/REPO/pull/12",
10+
"headRefName": "blueberries",
11+
"headRepositoryOwner": {
12+
"login": "hubot"
13+
},
14+
"isCrossRepository": true
15+
},
16+
{
717
"number": 10,
818
"title": "Blueberries are a good fruit",
919
"url": "https://github.com/OWNER/REPO/pull/10",
10-
"headRefName": "[blueberries]"
20+
"headRefName": "blueberries",
21+
"headRepositoryOwner": {
22+
"login": "OWNER"
23+
},
24+
"isCrossRepository": false
1125
}
12-
}
13-
]
14-
}
15-
},
16-
"viewerCreated": {
17-
"edges": [
18-
{
19-
"node": {
20-
"number": 8,
21-
"title": "Strawberries are not actually berries",
22-
"url": "https://github.com/OWNER/REPO/pull/8",
23-
"headRefName": "[strawberries]"
24-
}
25-
}
26-
],
27-
"pageInfo": { "hasNextPage": false }
28-
},
29-
"reviewRequested": {
30-
"edges": [
31-
{
32-
"node": {
33-
"number": 9,
34-
"title": "Apples are tasty",
35-
"url": "https://github.com/OWNER/REPO/pull/9",
36-
"headRefName": "[apples]"
37-
}
38-
},
39-
{
40-
"node": {
41-
"number": 11,
42-
"title": "Figs are my favorite",
43-
"url": "https://github.com/OWNER/REPO/pull/1",
44-
"headRefName": "[figs]"
45-
}
26+
]
4627
}
47-
],
48-
"pageInfo": { "hasNextPage": false }
28+
}
4929
}
50-
}}
30+
}

0 commit comments

Comments
 (0)
X Tutup