Merge pull request #205 from github/and-four-more
Add "show more" to the issues and PR results in `gh issue status` and `gh pr status`
This commit is contained in:
commit
869f50ec0f
7 changed files with 180 additions and 116 deletions
|
|
@ -5,9 +5,14 @@ import (
|
|||
)
|
||||
|
||||
type IssuesPayload struct {
|
||||
Assigned []Issue
|
||||
Mentioned []Issue
|
||||
Authored []Issue
|
||||
Assigned IssuesAndTotalCount
|
||||
Mentioned IssuesAndTotalCount
|
||||
Authored IssuesAndTotalCount
|
||||
}
|
||||
|
||||
type IssuesAndTotalCount struct {
|
||||
Issues []Issue
|
||||
TotalCount int
|
||||
}
|
||||
|
||||
type Issue struct {
|
||||
|
|
@ -80,13 +85,16 @@ func IssueStatus(client *Client, ghRepo Repo, currentUsername string) (*IssuesPa
|
|||
type response struct {
|
||||
Repository struct {
|
||||
Assigned struct {
|
||||
Nodes []Issue
|
||||
TotalCount int
|
||||
Nodes []Issue
|
||||
}
|
||||
Mentioned struct {
|
||||
Nodes []Issue
|
||||
TotalCount int
|
||||
Nodes []Issue
|
||||
}
|
||||
Authored struct {
|
||||
Nodes []Issue
|
||||
TotalCount int
|
||||
Nodes []Issue
|
||||
}
|
||||
HasIssuesEnabled bool
|
||||
}
|
||||
|
|
@ -97,16 +105,19 @@ func IssueStatus(client *Client, ghRepo Repo, currentUsername string) (*IssuesPa
|
|||
repository(owner: $owner, name: $repo) {
|
||||
hasIssuesEnabled
|
||||
assigned: issues(filterBy: {assignee: $viewer, states: OPEN}, first: $per_page, orderBy: {field: CREATED_AT, direction: DESC}) {
|
||||
totalCount
|
||||
nodes {
|
||||
...issue
|
||||
}
|
||||
}
|
||||
mentioned: issues(filterBy: {mentioned: $viewer, states: OPEN}, first: $per_page, orderBy: {field: CREATED_AT, direction: DESC}) {
|
||||
totalCount
|
||||
nodes {
|
||||
...issue
|
||||
}
|
||||
}
|
||||
authored: issues(filterBy: {createdBy: $viewer, states: OPEN}, first: $per_page, orderBy: {field: CREATED_AT, direction: DESC}) {
|
||||
totalCount
|
||||
nodes {
|
||||
...issue
|
||||
}
|
||||
|
|
@ -133,9 +144,18 @@ func IssueStatus(client *Client, ghRepo Repo, currentUsername string) (*IssuesPa
|
|||
}
|
||||
|
||||
payload := IssuesPayload{
|
||||
Assigned: resp.Repository.Assigned.Nodes,
|
||||
Mentioned: resp.Repository.Mentioned.Nodes,
|
||||
Authored: resp.Repository.Authored.Nodes,
|
||||
Assigned: IssuesAndTotalCount{
|
||||
Issues: resp.Repository.Assigned.Nodes,
|
||||
TotalCount: resp.Repository.Assigned.TotalCount,
|
||||
},
|
||||
Mentioned: IssuesAndTotalCount{
|
||||
Issues: resp.Repository.Mentioned.Nodes,
|
||||
TotalCount: resp.Repository.Mentioned.TotalCount,
|
||||
},
|
||||
Authored: IssuesAndTotalCount{
|
||||
Issues: resp.Repository.Authored.Nodes,
|
||||
TotalCount: resp.Repository.Authored.TotalCount,
|
||||
},
|
||||
}
|
||||
|
||||
return &payload, nil
|
||||
|
|
|
|||
|
|
@ -6,11 +6,16 @@ import (
|
|||
)
|
||||
|
||||
type PullRequestsPayload struct {
|
||||
ViewerCreated []PullRequest
|
||||
ReviewRequested []PullRequest
|
||||
ViewerCreated PullRequestAndTotalCount
|
||||
ReviewRequested PullRequestAndTotalCount
|
||||
CurrentPR *PullRequest
|
||||
}
|
||||
|
||||
type PullRequestAndTotalCount struct {
|
||||
TotalCount int
|
||||
PullRequests []PullRequest
|
||||
}
|
||||
|
||||
type PullRequest struct {
|
||||
Number int
|
||||
Title string
|
||||
|
|
@ -123,7 +128,8 @@ type Repo interface {
|
|||
|
||||
func PullRequests(client *Client, ghRepo Repo, currentPRNumber int, currentPRHeadRef, currentUsername string) (*PullRequestsPayload, error) {
|
||||
type edges struct {
|
||||
Edges []struct {
|
||||
TotalCount int
|
||||
Edges []struct {
|
||||
Node PullRequest
|
||||
}
|
||||
}
|
||||
|
|
@ -177,6 +183,7 @@ func PullRequests(client *Client, ghRepo Repo, currentPRNumber int, currentPRHea
|
|||
query($owner: String!, $repo: String!, $headRefName: String!, $viewerQuery: String!, $reviewerQuery: String!, $per_page: Int = 10) {
|
||||
repository(owner: $owner, name: $repo) {
|
||||
pullRequests(headRefName: $headRefName, states: OPEN, first: $per_page) {
|
||||
totalCount
|
||||
edges {
|
||||
node {
|
||||
...prWithReviews
|
||||
|
|
@ -198,6 +205,7 @@ func PullRequests(client *Client, ghRepo Repo, currentPRNumber int, currentPRHea
|
|||
|
||||
query := fragments + queryPrefix + `
|
||||
viewerCreated: search(query: $viewerQuery, type: ISSUE, first: $per_page) {
|
||||
totalCount: issueCount
|
||||
edges {
|
||||
node {
|
||||
...prWithReviews
|
||||
|
|
@ -205,6 +213,7 @@ func PullRequests(client *Client, ghRepo Repo, currentPRNumber int, currentPRHea
|
|||
}
|
||||
}
|
||||
reviewRequested: search(query: $reviewerQuery, type: ISSUE, first: $per_page) {
|
||||
totalCount: issueCount
|
||||
edges {
|
||||
node {
|
||||
...pr
|
||||
|
|
@ -260,9 +269,15 @@ func PullRequests(client *Client, ghRepo Repo, currentPRNumber int, currentPRHea
|
|||
}
|
||||
|
||||
payload := PullRequestsPayload{
|
||||
viewerCreated,
|
||||
reviewRequested,
|
||||
currentPR,
|
||||
ViewerCreated: PullRequestAndTotalCount{
|
||||
PullRequests: viewerCreated,
|
||||
TotalCount: resp.ViewerCreated.TotalCount,
|
||||
},
|
||||
ReviewRequested: PullRequestAndTotalCount{
|
||||
PullRequests: reviewRequested,
|
||||
TotalCount: resp.ReviewRequested.TotalCount,
|
||||
},
|
||||
CurrentPR: currentPR,
|
||||
}
|
||||
|
||||
return &payload, nil
|
||||
|
|
|
|||
|
|
@ -172,8 +172,8 @@ func issueStatus(cmd *cobra.Command, args []string) error {
|
|||
out := colorableOut(cmd)
|
||||
|
||||
printHeader(out, "Issues assigned to you")
|
||||
if len(issuePayload.Assigned) > 0 {
|
||||
printIssues(out, " ", issuePayload.Assigned...)
|
||||
if issuePayload.Assigned.TotalCount > 0 {
|
||||
printIssues(out, " ", issuePayload.Assigned.TotalCount, issuePayload.Assigned.Issues)
|
||||
} else {
|
||||
message := fmt.Sprintf(" There are no issues assigned to you")
|
||||
printMessage(out, message)
|
||||
|
|
@ -181,16 +181,16 @@ func issueStatus(cmd *cobra.Command, args []string) error {
|
|||
fmt.Fprintln(out)
|
||||
|
||||
printHeader(out, "Issues mentioning you")
|
||||
if len(issuePayload.Mentioned) > 0 {
|
||||
printIssues(out, " ", issuePayload.Mentioned...)
|
||||
if issuePayload.Mentioned.TotalCount > 0 {
|
||||
printIssues(out, " ", issuePayload.Mentioned.TotalCount, issuePayload.Mentioned.Issues)
|
||||
} else {
|
||||
printMessage(out, " There are no issues mentioning you")
|
||||
}
|
||||
fmt.Fprintln(out)
|
||||
|
||||
printHeader(out, "Issues opened by you")
|
||||
if len(issuePayload.Authored) > 0 {
|
||||
printIssues(out, " ", issuePayload.Authored...)
|
||||
if issuePayload.Authored.TotalCount > 0 {
|
||||
printIssues(out, " ", issuePayload.Authored.TotalCount, issuePayload.Authored.Issues)
|
||||
} else {
|
||||
printMessage(out, " There are no issues opened by you")
|
||||
}
|
||||
|
|
@ -318,7 +318,7 @@ func issueCreate(cmd *cobra.Command, args []string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func printIssues(w io.Writer, prefix string, issues ...api.Issue) {
|
||||
func printIssues(w io.Writer, prefix string, totalCount int, issues []api.Issue) {
|
||||
for _, issue := range issues {
|
||||
number := utils.Green("#" + strconv.Itoa(issue.Number))
|
||||
coloredLabels := labelList(issue)
|
||||
|
|
@ -327,6 +327,10 @@ func printIssues(w io.Writer, prefix string, issues ...api.Issue) {
|
|||
}
|
||||
fmt.Fprintf(w, "%s%s %s%s\n", prefix, number, truncate(70, replaceExcessiveWhitespace(issue.Title)), coloredLabels)
|
||||
}
|
||||
remaining := totalCount - len(issues)
|
||||
if remaining > 0 {
|
||||
fmt.Fprintf(w, utils.Gray("%sAnd %d more\n"), prefix, remaining)
|
||||
}
|
||||
}
|
||||
|
||||
func labelList(issue api.Issue) string {
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@ func prStatus(cmd *cobra.Command, args []string) error {
|
|||
|
||||
printHeader(out, "Current branch")
|
||||
if prPayload.CurrentPR != nil {
|
||||
printPrs(out, *prPayload.CurrentPR)
|
||||
printPrs(out, 0, *prPayload.CurrentPR)
|
||||
} else {
|
||||
message := fmt.Sprintf(" There is no pull request associated with %s", utils.Cyan("["+currentPRHeadRef+"]"))
|
||||
printMessage(out, message)
|
||||
|
|
@ -107,16 +107,16 @@ func prStatus(cmd *cobra.Command, args []string) error {
|
|||
fmt.Fprintln(out)
|
||||
|
||||
printHeader(out, "Created by you")
|
||||
if len(prPayload.ViewerCreated) > 0 {
|
||||
printPrs(out, prPayload.ViewerCreated...)
|
||||
if prPayload.ViewerCreated.TotalCount > 0 {
|
||||
printPrs(out, prPayload.ViewerCreated.TotalCount, prPayload.ViewerCreated.PullRequests...)
|
||||
} else {
|
||||
printMessage(out, " You have no open pull requests")
|
||||
}
|
||||
fmt.Fprintln(out)
|
||||
|
||||
printHeader(out, "Requesting a code review from you")
|
||||
if len(prPayload.ReviewRequested) > 0 {
|
||||
printPrs(out, prPayload.ReviewRequested...)
|
||||
if prPayload.ReviewRequested.TotalCount > 0 {
|
||||
printPrs(out, prPayload.ReviewRequested.TotalCount, prPayload.ReviewRequested.PullRequests...)
|
||||
} else {
|
||||
printMessage(out, " You have no pull requests to review")
|
||||
}
|
||||
|
|
@ -435,7 +435,7 @@ func prCheckout(cmd *cobra.Command, args []string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func printPrs(w io.Writer, prs ...api.PullRequest) {
|
||||
func printPrs(w io.Writer, totalCount int, prs ...api.PullRequest) {
|
||||
for _, pr := range prs {
|
||||
prNumber := fmt.Sprintf("#%d", pr.Number)
|
||||
fmt.Fprintf(w, " %s %s %s", utils.Green(prNumber), truncate(50, replaceExcessiveWhitespace(pr.Title)), utils.Cyan("["+pr.HeadLabel()+"]"))
|
||||
|
|
@ -472,6 +472,10 @@ func printPrs(w io.Writer, prs ...api.PullRequest) {
|
|||
|
||||
fmt.Fprint(w, "\n")
|
||||
}
|
||||
remaining := totalCount - len(prs)
|
||||
if remaining > 0 {
|
||||
fmt.Fprintf(w, utils.Gray(" And %d more\n"), remaining)
|
||||
}
|
||||
}
|
||||
|
||||
func printHeader(w io.Writer, s string) {
|
||||
|
|
|
|||
19
test/fixtures/issueStatus.json
vendored
19
test/fixtures/issueStatus.json
vendored
|
|
@ -3,30 +3,33 @@
|
|||
"repository": {
|
||||
"hasIssuesEnabled": true,
|
||||
"assigned": {
|
||||
"totalCount": 2,
|
||||
"nodes": [
|
||||
{
|
||||
"number": 9,
|
||||
"title": "corey thinks squash tastes bad"
|
||||
"number": 9,
|
||||
"title": "corey thinks squash tastes bad"
|
||||
},
|
||||
{
|
||||
"number": 10,
|
||||
"title": "broccoli is a superfood"
|
||||
"number": 10,
|
||||
"title": "broccoli is a superfood"
|
||||
}
|
||||
]
|
||||
},
|
||||
"mentioned": {
|
||||
"totalCount": 2,
|
||||
"nodes": [
|
||||
{
|
||||
"number": 8,
|
||||
"title": "rabbits eat carrots"
|
||||
"number": 8,
|
||||
"title": "rabbits eat carrots"
|
||||
},
|
||||
{
|
||||
"number": 11,
|
||||
"title": "swiss chard is neutral"
|
||||
"number": 11,
|
||||
"title": "swiss chard is neutral"
|
||||
}
|
||||
]
|
||||
},
|
||||
"authored": {
|
||||
"totalCount": 0,
|
||||
"nodes": []
|
||||
}
|
||||
}
|
||||
|
|
|
|||
93
test/fixtures/prStatus.json
vendored
93
test/fixtures/prStatus.json
vendored
|
|
@ -1,52 +1,57 @@
|
|||
{"data":{
|
||||
"repository": {
|
||||
"pullRequests": {
|
||||
{
|
||||
"data": {
|
||||
"repository": {
|
||||
"pullRequests": {
|
||||
"totalCount": 1,
|
||||
"edges": [
|
||||
{
|
||||
"node": {
|
||||
"number": 10,
|
||||
"title": "Blueberries are a good fruit",
|
||||
"url": "https://github.com/github/gh-cli/pull/10",
|
||||
"headRefName": "blueberries",
|
||||
"headRepositoryOwner": {
|
||||
"login": "OWNER"
|
||||
},
|
||||
"isCrossRepository": false
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"viewerCreated": {
|
||||
"totalCount": 1,
|
||||
"edges": [
|
||||
{
|
||||
"node": {
|
||||
"number": 10,
|
||||
"title": "Blueberries are a good fruit",
|
||||
"url": "https://github.com/github/gh-cli/pull/10",
|
||||
"headRefName": "blueberries",
|
||||
"headRepositoryOwner": {
|
||||
"login": "OWNER"
|
||||
},
|
||||
"isCrossRepository": false
|
||||
"number": 8,
|
||||
"title": "Strawberries are not actually berries",
|
||||
"url": "https://github.com/github/gh-cli/pull/8",
|
||||
"headRefName": "strawberries"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"reviewRequested": {
|
||||
"totalCount": 2,
|
||||
"edges": [
|
||||
{
|
||||
"node": {
|
||||
"number": 9,
|
||||
"title": "Apples are tasty",
|
||||
"url": "https://github.com/github/gh-cli/pull/9",
|
||||
"headRefName": "apples"
|
||||
}
|
||||
},
|
||||
{
|
||||
"node": {
|
||||
"number": 11,
|
||||
"title": "Figs are my favorite",
|
||||
"url": "https://github.com/github/gh-cli/pull/1",
|
||||
"headRefName": "figs"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"viewerCreated": {
|
||||
"edges": [
|
||||
{
|
||||
"node": {
|
||||
"number": 8,
|
||||
"title": "Strawberries are not actually berries",
|
||||
"url": "https://github.com/github/gh-cli/pull/8",
|
||||
"headRefName": "strawberries"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"reviewRequested": {
|
||||
"edges": [
|
||||
{
|
||||
"node": {
|
||||
"number": 9,
|
||||
"title": "Apples are tasty",
|
||||
"url": "https://github.com/github/gh-cli/pull/9",
|
||||
"headRefName": "apples"
|
||||
}
|
||||
},
|
||||
{
|
||||
"node": {
|
||||
"number": 11,
|
||||
"title": "Figs are my favorite",
|
||||
"url": "https://github.com/github/gh-cli/pull/1",
|
||||
"headRefName": "figs"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}}
|
||||
}
|
||||
|
|
|
|||
85
test/fixtures/prStatusChecks.json
vendored
85
test/fixtures/prStatusChecks.json
vendored
|
|
@ -1,11 +1,13 @@
|
|||
{
|
||||
"data":{
|
||||
"data": {
|
||||
"repository": {
|
||||
"pullRequests": {
|
||||
"totalCount": 0,
|
||||
"edges": []
|
||||
}
|
||||
},
|
||||
"viewerCreated": {
|
||||
"totalCount": 3,
|
||||
"edges": [
|
||||
{
|
||||
"node": {
|
||||
|
|
@ -15,17 +17,21 @@
|
|||
"headRefName": "strawberries",
|
||||
"reviewDecision": "CHANGES_REQUESTED",
|
||||
"commits": {
|
||||
"nodes": [{
|
||||
"commit": {
|
||||
"statusCheckRollup": {
|
||||
"contexts": {
|
||||
"nodes": [{
|
||||
"state": "SUCCESS"
|
||||
}]
|
||||
"nodes": [
|
||||
{
|
||||
"commit": {
|
||||
"statusCheckRollup": {
|
||||
"contexts": {
|
||||
"nodes": [
|
||||
{
|
||||
"state": "SUCCESS"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}]
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -37,18 +43,22 @@
|
|||
"headRefName": "banananana",
|
||||
"reviewDecision": "APPROVED",
|
||||
"commits": {
|
||||
"nodes": [{
|
||||
"commit": {
|
||||
"statusCheckRollup": {
|
||||
"contexts": {
|
||||
"nodes": [{
|
||||
"status": "IN_PROGRESS",
|
||||
"conclusion": ""
|
||||
}]
|
||||
"nodes": [
|
||||
{
|
||||
"commit": {
|
||||
"statusCheckRollup": {
|
||||
"contexts": {
|
||||
"nodes": [
|
||||
{
|
||||
"status": "IN_PROGRESS",
|
||||
"conclusion": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}]
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -60,33 +70,36 @@
|
|||
"headRefName": "avo",
|
||||
"reviewDecision": "REVIEW_REQUIRED",
|
||||
"commits": {
|
||||
"nodes": [{
|
||||
"commit": {
|
||||
"statusCheckRollup": {
|
||||
"contexts": {
|
||||
"nodes": [
|
||||
{
|
||||
"status": "IN_PROGRESS",
|
||||
"conclusion": ""
|
||||
},
|
||||
{
|
||||
"state": "FAILURE"
|
||||
},
|
||||
{
|
||||
"status": "COMPLETED",
|
||||
"conclusion": "NEUTRAL"
|
||||
}
|
||||
]
|
||||
"nodes": [
|
||||
{
|
||||
"commit": {
|
||||
"statusCheckRollup": {
|
||||
"contexts": {
|
||||
"nodes": [
|
||||
{
|
||||
"status": "IN_PROGRESS",
|
||||
"conclusion": ""
|
||||
},
|
||||
{
|
||||
"state": "FAILURE"
|
||||
},
|
||||
{
|
||||
"status": "COMPLETED",
|
||||
"conclusion": "NEUTRAL"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}]
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"reviewRequested": {
|
||||
"totalCount": 0,
|
||||
"edges": []
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue