Improve issue view re: overfetching, PR support
- Supports passing a PR as argument, not just issues - Makes it non-fatal when project cards were not able to load - Cleans up legacy method for fetching issues
This commit is contained in:
parent
3cf3d6d2d4
commit
34fc5fb75c
11 changed files with 240 additions and 183 deletions
|
|
@ -146,17 +146,31 @@ type GraphQLErrorResponse struct {
|
|||
func (gr GraphQLErrorResponse) Error() string {
|
||||
errorMessages := make([]string, 0, len(gr.Errors))
|
||||
for _, e := range gr.Errors {
|
||||
errorMessages = append(errorMessages, e.Message)
|
||||
msg := e.Message
|
||||
if p := e.PathString(); p != "" {
|
||||
msg = fmt.Sprintf("%s (%s)", msg, p)
|
||||
}
|
||||
errorMessages = append(errorMessages, msg)
|
||||
}
|
||||
return fmt.Sprintf("GraphQL error: %s", strings.Join(errorMessages, "\n"))
|
||||
return fmt.Sprintf("GraphQL: %s", strings.Join(errorMessages, ", "))
|
||||
}
|
||||
|
||||
// Match checks if this error is only about a specific type on a specific path.
|
||||
// Match checks if this error is only about a specific type on a specific path. If the path argument ends
|
||||
// with a ".", it will match all its subpaths as well.
|
||||
func (gr GraphQLErrorResponse) Match(expectType, expectPath string) bool {
|
||||
if len(gr.Errors) != 1 {
|
||||
return false
|
||||
for _, e := range gr.Errors {
|
||||
if e.Type != expectType || !matchPath(e.PathString(), expectPath) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return gr.Errors[0].Type == expectType && gr.Errors[0].PathString() == expectPath
|
||||
return true
|
||||
}
|
||||
|
||||
func matchPath(p, expect string) bool {
|
||||
if strings.HasSuffix(expect, ".") {
|
||||
return strings.HasPrefix(p, expect) || p == strings.TrimSuffix(expect, ".")
|
||||
}
|
||||
return p == expect
|
||||
}
|
||||
|
||||
// HTTPError is an error returned by a failed API call
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ func TestGraphQLError(t *testing.T) {
|
|||
)
|
||||
|
||||
err := client.GraphQL("github.com", "", nil, &response)
|
||||
if err == nil || err.Error() != "GraphQL error: OH NO\nthis is fine" {
|
||||
if err == nil || err.Error() != "GraphQL: OH NO (repository.issue), this is fine (repository.issues.0.comments)" {
|
||||
t.Fatalf("got %q", err.Error())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -71,17 +71,19 @@ func (l Labels) Names() []string {
|
|||
}
|
||||
|
||||
type ProjectCards struct {
|
||||
Nodes []struct {
|
||||
Project struct {
|
||||
Name string `json:"name"`
|
||||
} `json:"project"`
|
||||
Column struct {
|
||||
Name string `json:"name"`
|
||||
} `json:"column"`
|
||||
}
|
||||
Nodes []*ProjectInfo
|
||||
TotalCount int
|
||||
}
|
||||
|
||||
type ProjectInfo struct {
|
||||
Project struct {
|
||||
Name string `json:"name"`
|
||||
} `json:"project"`
|
||||
Column struct {
|
||||
Name string `json:"name"`
|
||||
} `json:"column"`
|
||||
}
|
||||
|
||||
func (p ProjectCards) ProjectNames() []string {
|
||||
names := make([]string, len(p.Nodes))
|
||||
for i, c := range p.Nodes {
|
||||
|
|
@ -233,113 +235,6 @@ func IssueStatus(client *Client, repo ghrepo.Interface, options IssueStatusOptio
|
|||
return &payload, nil
|
||||
}
|
||||
|
||||
func IssueByNumber(client *Client, repo ghrepo.Interface, number int) (*Issue, error) {
|
||||
type response struct {
|
||||
Repository struct {
|
||||
Issue Issue
|
||||
HasIssuesEnabled bool
|
||||
}
|
||||
}
|
||||
|
||||
query := `
|
||||
query IssueByNumber($owner: String!, $repo: String!, $issue_number: Int!) {
|
||||
repository(owner: $owner, name: $repo) {
|
||||
hasIssuesEnabled
|
||||
issue(number: $issue_number) {
|
||||
id
|
||||
title
|
||||
state
|
||||
body
|
||||
author {
|
||||
login
|
||||
}
|
||||
comments(last: 1) {
|
||||
nodes {
|
||||
author {
|
||||
login
|
||||
}
|
||||
authorAssociation
|
||||
body
|
||||
createdAt
|
||||
includesCreatedEdit
|
||||
isMinimized
|
||||
minimizedReason
|
||||
reactionGroups {
|
||||
content
|
||||
users {
|
||||
totalCount
|
||||
}
|
||||
}
|
||||
}
|
||||
totalCount
|
||||
}
|
||||
number
|
||||
url
|
||||
createdAt
|
||||
assignees(first: 100) {
|
||||
nodes {
|
||||
id
|
||||
name
|
||||
login
|
||||
}
|
||||
totalCount
|
||||
}
|
||||
labels(first: 100) {
|
||||
nodes {
|
||||
id
|
||||
name
|
||||
description
|
||||
color
|
||||
}
|
||||
totalCount
|
||||
}
|
||||
projectCards(first: 100) {
|
||||
nodes {
|
||||
project {
|
||||
name
|
||||
}
|
||||
column {
|
||||
name
|
||||
}
|
||||
}
|
||||
totalCount
|
||||
}
|
||||
milestone {
|
||||
number
|
||||
title
|
||||
description
|
||||
dueOn
|
||||
}
|
||||
reactionGroups {
|
||||
content
|
||||
users {
|
||||
totalCount
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}`
|
||||
|
||||
variables := map[string]interface{}{
|
||||
"owner": repo.RepoOwner(),
|
||||
"repo": repo.RepoName(),
|
||||
"issue_number": number,
|
||||
}
|
||||
|
||||
var resp response
|
||||
err := client.GraphQL(repo.RepoHost(), query, variables, &resp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if !resp.Repository.HasIssuesEnabled {
|
||||
|
||||
return nil, &IssuesDisabledError{fmt.Errorf("the '%s' repository has disabled issues", ghrepo.FullName(repo))}
|
||||
}
|
||||
|
||||
return &resp.Repository.Issue, nil
|
||||
}
|
||||
|
||||
func (i Issue) Link() string {
|
||||
return i.URL
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ func TestGitHubRepo_notFound(t *testing.T) {
|
|||
if err == nil {
|
||||
t.Fatal("GitHubRepo did not return an error")
|
||||
}
|
||||
if wants := "GraphQL error: Could not resolve to a Repository with the name 'OWNER/REPO'."; err.Error() != wants {
|
||||
if wants := "GraphQL: Could not resolve to a Repository with the name 'OWNER/REPO'."; err.Error() != wants {
|
||||
t.Errorf("GitHubRepo error: want %q, got %q", wants, err.Error())
|
||||
}
|
||||
if repo != nil {
|
||||
|
|
|
|||
|
|
@ -35,6 +35,22 @@ var issueComments = shortenQuery(`
|
|||
}
|
||||
`)
|
||||
|
||||
var issueCommentLast = shortenQuery(`
|
||||
comments(last: 1) {
|
||||
nodes {
|
||||
author{login},
|
||||
authorAssociation,
|
||||
body,
|
||||
createdAt,
|
||||
includesCreatedEdit,
|
||||
isMinimized,
|
||||
minimizedReason,
|
||||
reactionGroups{content,users{totalCount}}
|
||||
},
|
||||
totalCount
|
||||
}
|
||||
`)
|
||||
|
||||
var prReviewRequests = shortenQuery(`
|
||||
reviewRequests(first: 100) {
|
||||
nodes {
|
||||
|
|
@ -206,6 +222,8 @@ func PullRequestGraphQL(fields []string) string {
|
|||
q = append(q, `potentialMergeCommit{oid}`)
|
||||
case "comments":
|
||||
q = append(q, issueComments)
|
||||
case "lastComment": // pseudo-field
|
||||
q = append(q, issueCommentLast)
|
||||
case "reviewRequests":
|
||||
q = append(q, prReviewRequests)
|
||||
case "reviews":
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue