Skip to content

Commit f4b8851

Browse files
committed
Merge remote-tracking branch 'origin/master' into pr-status-no-commits
2 parents 897d5c3 + e4b8ae0 commit f4b8851

15 files changed

Lines changed: 463 additions & 198 deletions

api/queries_pr.go

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,7 @@ func PullRequestByNumber(client *Client, repo ghrepo.Interface, number int) (*Pu
340340
return &resp.Repository.PullRequest, nil
341341
}
342342

343-
func PullRequestForBranch(client *Client, repo ghrepo.Interface, branch string) (*PullRequest, error) {
343+
func PullRequestForBranch(client *Client, repo ghrepo.Interface, baseBranch, headBranch string) (*PullRequest, error) {
344344
type response struct {
345345
Repository struct {
346346
PullRequests struct {
@@ -376,9 +376,9 @@ func PullRequestForBranch(client *Client, repo ghrepo.Interface, branch string)
376376
}
377377
}`
378378

379-
branchWithoutOwner := branch
380-
if idx := strings.Index(branch, ":"); idx >= 0 {
381-
branchWithoutOwner = branch[idx+1:]
379+
branchWithoutOwner := headBranch
380+
if idx := strings.Index(headBranch, ":"); idx >= 0 {
381+
branchWithoutOwner = headBranch[idx+1:]
382382
}
383383

384384
variables := map[string]interface{}{
@@ -394,12 +394,17 @@ func PullRequestForBranch(client *Client, repo ghrepo.Interface, branch string)
394394
}
395395

396396
for _, pr := range resp.Repository.PullRequests.Nodes {
397-
if pr.HeadLabel() == branch {
397+
if pr.HeadLabel() == headBranch {
398+
if baseBranch != "" {
399+
if pr.BaseRefName != baseBranch {
400+
continue
401+
}
402+
}
398403
return &pr, nil
399404
}
400405
}
401406

402-
return nil, &NotFoundError{fmt.Errorf("no open pull requests found for branch %q", branch)}
407+
return nil, &NotFoundError{fmt.Errorf("no open pull requests found for branch %q", headBranch)}
403408
}
404409

405410
// CreatePullRequest creates a pull request in a GitHub repository

api/queries_repo.go

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

33
import (
44
"bytes"
5+
"encoding/base64"
56
"encoding/json"
67
"fmt"
78
"sort"
89
"strings"
910
"time"
1011

1112
"github.com/cli/cli/internal/ghrepo"
13+
"github.com/cli/cli/utils"
1214
)
1315

1416
// Repository contains information about a GitHub repo
1517
type Repository struct {
16-
ID string
17-
Name string
18-
URL string
19-
CloneURL string
20-
CreatedAt time.Time
21-
Owner RepositoryOwner
18+
ID string
19+
Name string
20+
Description string
21+
URL string
22+
CloneURL string
23+
CreatedAt time.Time
24+
Owner RepositoryOwner
2225

2326
IsPrivate bool
2427
HasIssuesEnabled bool
@@ -69,6 +72,7 @@ func GitHubRepo(client *Client, repo ghrepo.Interface) (*Repository, error) {
6972
repository(owner: $owner, name: $name) {
7073
id
7174
hasIssuesEnabled
75+
description
7276
}
7377
}`
7478
variables := map[string]interface{}{
@@ -154,7 +158,7 @@ func RepoNetwork(client *Client, repos []ghrepo.Interface) (RepoNetworkResult, e
154158
keys = append(keys, key)
155159
}
156160
// sort keys to ensure `repo_{N}` entries are processed in order
157-
sort.Sort(sort.StringSlice(keys))
161+
sort.Strings(keys)
158162

159163
// Iterate over keys of GraphQL response data and, based on its name,
160164
// dynamically allocate the target struct an individual message gets decoded to.
@@ -279,3 +283,43 @@ func RepoCreate(client *Client, input RepoCreateInput) (*Repository, error) {
279283

280284
return &response.CreateRepository.Repository, nil
281285
}
286+
287+
func RepositoryReadme(client *Client, fullName string) (string, error) {
288+
type readmeResponse struct {
289+
Name string
290+
Content string
291+
}
292+
293+
var readme readmeResponse
294+
295+
err := client.REST("GET", fmt.Sprintf("repos/%s/readme", fullName), nil, &readme)
296+
if err != nil && !strings.HasSuffix(err.Error(), "'Not Found'") {
297+
return "", fmt.Errorf("could not get readme for repo: %w", err)
298+
}
299+
300+
decoded, err := base64.StdEncoding.DecodeString(readme.Content)
301+
if err != nil {
302+
return "", fmt.Errorf("failed to decode readme: %w", err)
303+
}
304+
305+
readmeContent := string(decoded)
306+
307+
if isMarkdownFile(readme.Name) {
308+
readmeContent, err = utils.RenderMarkdown(readmeContent)
309+
if err != nil {
310+
return "", fmt.Errorf("failed to render readme as markdown: %w", err)
311+
}
312+
}
313+
314+
return readmeContent, nil
315+
316+
}
317+
318+
func isMarkdownFile(filename string) bool {
319+
// kind of gross, but i'm assuming that 90% of the time the suffix will just be .md. it didn't
320+
// seem worth executing a regex for this given that assumption.
321+
return strings.HasSuffix(filename, ".md") ||
322+
strings.HasSuffix(filename, ".markdown") ||
323+
strings.HasSuffix(filename, ".mdown") ||
324+
strings.HasSuffix(filename, ".mkdown")
325+
}

command/issue.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ func init() {
3838
issueListCmd.Flags().StringP("author", "A", "", "Filter by author")
3939

4040
issueCmd.AddCommand(issueViewCmd)
41-
issueViewCmd.Flags().BoolP("preview", "p", false, "Display preview of issue content")
41+
issueViewCmd.Flags().BoolP("web", "w", false, "Open issue in browser")
4242
}
4343

4444
var issueCmd = &cobra.Command{
@@ -73,7 +73,7 @@ var issueViewCmd = &cobra.Command{
7373
}
7474
return nil
7575
},
76-
Short: "View an issue in the browser",
76+
Short: "View an issue",
7777
RunE: issueView,
7878
}
7979

@@ -213,17 +213,17 @@ func issueView(cmd *cobra.Command, args []string) error {
213213
}
214214
openURL := issue.URL
215215

216-
preview, err := cmd.Flags().GetBool("preview")
216+
web, err := cmd.Flags().GetBool("web")
217217
if err != nil {
218218
return err
219219
}
220220

221-
if preview {
222-
out := colorableOut(cmd)
223-
return printIssuePreview(out, issue)
224-
} else {
221+
if web {
225222
fmt.Fprintf(cmd.ErrOrStderr(), "Opening %s in your browser.\n", openURL)
226223
return utils.OpenInBrowser(openURL)
224+
} else {
225+
out := colorableOut(cmd)
226+
return printIssuePreview(out, issue)
227227
}
228228

229229
}

command/issue_test.go

Lines changed: 21 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ func TestIssueList_disabledIssues(t *testing.T) {
216216
}
217217
}
218218

219-
func TestIssueView(t *testing.T) {
219+
func TestIssueView_web(t *testing.T) {
220220
initBlankContext("OWNER/REPO", "master")
221221
http := initFakeHTTP()
222222
http.StubRepoResponse("OWNER", "REPO")
@@ -235,7 +235,7 @@ func TestIssueView(t *testing.T) {
235235
})
236236
defer restoreCmd()
237237

238-
output, err := RunCommand(issueViewCmd, "issue view 123")
238+
output, err := RunCommand(issueViewCmd, "issue view -w 123")
239239
if err != nil {
240240
t.Errorf("error running command `issue view`: %v", err)
241241
}
@@ -250,7 +250,7 @@ func TestIssueView(t *testing.T) {
250250
eq(t, url, "https://github.com/OWNER/REPO/issues/123")
251251
}
252252

253-
func TestIssueView_numberArgWithHash(t *testing.T) {
253+
func TestIssueView_web_numberArgWithHash(t *testing.T) {
254254
initBlankContext("OWNER/REPO", "master")
255255
http := initFakeHTTP()
256256
http.StubRepoResponse("OWNER", "REPO")
@@ -269,7 +269,7 @@ func TestIssueView_numberArgWithHash(t *testing.T) {
269269
})
270270
defer restoreCmd()
271271

272-
output, err := RunCommand(issueViewCmd, "issue view \"#123\"")
272+
output, err := RunCommand(issueViewCmd, "issue view -w \"#123\"")
273273
if err != nil {
274274
t.Errorf("error running command `issue view`: %v", err)
275275
}
@@ -284,7 +284,7 @@ func TestIssueView_numberArgWithHash(t *testing.T) {
284284
eq(t, url, "https://github.com/OWNER/REPO/issues/123")
285285
}
286286

287-
func TestIssueView_preview(t *testing.T) {
287+
func TestIssueView(t *testing.T) {
288288
initBlankContext("OWNER/REPO", "master")
289289
http := initFakeHTTP()
290290
http.StubRepoResponse("OWNER", "REPO")
@@ -309,28 +309,21 @@ func TestIssueView_preview(t *testing.T) {
309309
} } } }
310310
`))
311311

312-
output, err := RunCommand(issueViewCmd, "issue view -p 123")
312+
output, err := RunCommand(issueViewCmd, "issue view 123")
313313
if err != nil {
314314
t.Errorf("error running command `issue view`: %v", err)
315315
}
316316

317317
eq(t, output.Stderr(), "")
318318

319-
expectedLines := []*regexp.Regexp{
320-
regexp.MustCompile(`ix of coins`),
321-
regexp.MustCompile(`opened by marseilles. 9 comments. \(tarot\)`),
322-
regexp.MustCompile(`bold story`),
323-
regexp.MustCompile(`View this issue on GitHub: https://github.com/OWNER/REPO/issues/123`),
324-
}
325-
for _, r := range expectedLines {
326-
if !r.MatchString(output.String()) {
327-
t.Errorf("output did not match regexp /%s/\n> output\n%s\n", r, output)
328-
return
329-
}
330-
}
319+
test.ExpectLines(t, output.String(),
320+
"ix of coins",
321+
`opened by marseilles. 9 comments. \(tarot\)`,
322+
"bold story",
323+
"View this issue on GitHub: https://github.com/OWNER/REPO/issues/123")
331324
}
332325

333-
func TestIssueView_previewWithEmptyBody(t *testing.T) {
326+
func TestIssueView_WithEmptyBody(t *testing.T) {
334327
initBlankContext("OWNER/REPO", "master")
335328
http := initFakeHTTP()
336329
http.StubRepoResponse("OWNER", "REPO")
@@ -355,27 +348,20 @@ func TestIssueView_previewWithEmptyBody(t *testing.T) {
355348
} } } }
356349
`))
357350

358-
output, err := RunCommand(issueViewCmd, "issue view -p 123")
351+
output, err := RunCommand(issueViewCmd, "issue view 123")
359352
if err != nil {
360353
t.Errorf("error running command `issue view`: %v", err)
361354
}
362355

363356
eq(t, output.Stderr(), "")
364357

365-
expectedLines := []*regexp.Regexp{
366-
regexp.MustCompile(`ix of coins`),
367-
regexp.MustCompile(`opened by marseilles. 9 comments. \(tarot\)`),
368-
regexp.MustCompile(`View this issue on GitHub: https://github.com/OWNER/REPO/issues/123`),
369-
}
370-
for _, r := range expectedLines {
371-
if !r.MatchString(output.String()) {
372-
t.Errorf("output did not match regexp /%s/\n> output\n%s\n", r, output)
373-
return
374-
}
375-
}
358+
test.ExpectLines(t, output.String(),
359+
"ix of coins",
360+
`opened by marseilles. 9 comments. \(tarot\)`,
361+
"View this issue on GitHub: https://github.com/OWNER/REPO/issues/123")
376362
}
377363

378-
func TestIssueView_notFound(t *testing.T) {
364+
func TestIssueView_web_notFound(t *testing.T) {
379365
initBlankContext("OWNER/REPO", "master")
380366
http := initFakeHTTP()
381367

@@ -392,7 +378,7 @@ func TestIssueView_notFound(t *testing.T) {
392378
})
393379
defer restoreCmd()
394380

395-
_, err := RunCommand(issueViewCmd, "issue view 9999")
381+
_, err := RunCommand(issueViewCmd, "issue view -w 9999")
396382
if err == nil || err.Error() != "graphql error: 'Could not resolve to an Issue with the number of 9999.'" {
397383
t.Errorf("error running command `issue view`: %v", err)
398384
}
@@ -420,7 +406,7 @@ func TestIssueView_disabledIssues(t *testing.T) {
420406
}
421407
}
422408

423-
func TestIssueView_urlArg(t *testing.T) {
409+
func TestIssueView_web_urlArg(t *testing.T) {
424410
initBlankContext("OWNER/REPO", "master")
425411
http := initFakeHTTP()
426412
http.StubRepoResponse("OWNER", "REPO")
@@ -439,7 +425,7 @@ func TestIssueView_urlArg(t *testing.T) {
439425
})
440426
defer restoreCmd()
441427

442-
output, err := RunCommand(issueViewCmd, "issue view https://github.com/OWNER/REPO/issues/123")
428+
output, err := RunCommand(issueViewCmd, "issue view -w https://github.com/OWNER/REPO/issues/123")
443429
if err != nil {
444430
t.Errorf("error running command `issue view`: %v", err)
445431
}

0 commit comments

Comments
 (0)