Improve highlighting and add QoL changes

This commit is contained in:
2026-07-27 14:28:32 +02:00
parent 6bfe248388
commit 547cd123da
11 changed files with 989 additions and 109 deletions

View File

@@ -90,13 +90,18 @@ func (c *GitHubClient) query(ctx context.Context, query string, variables map[st
}
const listPRsQuery = `
query PullRequests($owner: String!, $name: String!, $limit: Int!) {
query PullRequests($query: String!, $limit: Int!) {
viewer { login }
repository(owner: $owner, name: $name) {
pullRequests(first: $limit, states: OPEN, orderBy: {field: UPDATED_AT, direction: DESC}) {
nodes {
search(query: $query, type: ISSUE, first: $limit) {
nodes {
... on PullRequest {
id number title url isDraft updatedAt
author { login }
repository {
name
nameWithOwner
owner { login }
}
reviewThreads(first: 1) { totalCount }
}
}
@@ -104,52 +109,72 @@ query PullRequests($owner: String!, $name: String!, $limit: Int!) {
}`
func (c *GitHubClient) ListPullRequests(ctx context.Context, owner, name string, limit int, showAll bool) ([]PullRequest, error) {
if showAll && owner == "" {
return nil, errors.New("--all requires --repo to avoid an unbounded global search")
}
var data struct {
Viewer struct {
Login string `json:"login"`
} `json:"viewer"`
Repository *struct {
PullRequests struct {
Nodes []struct {
ID string `json:"id"`
Number int `json:"number"`
Title string `json:"title"`
URL string `json:"url"`
IsDraft bool `json:"isDraft"`
UpdatedAt time.Time `json:"updatedAt"`
Author *struct {
Search struct {
Nodes []struct {
ID string `json:"id"`
Number int `json:"number"`
Title string `json:"title"`
URL string `json:"url"`
IsDraft bool `json:"isDraft"`
UpdatedAt time.Time `json:"updatedAt"`
Author *struct {
Login string `json:"login"`
} `json:"author"`
Repository struct {
Name string `json:"name"`
NameWithOwner string `json:"nameWithOwner"`
Owner struct {
Login string `json:"login"`
} `json:"author"`
ReviewThreads struct {
TotalCount int `json:"totalCount"`
} `json:"reviewThreads"`
} `json:"nodes"`
} `json:"pullRequests"`
} `json:"repository"`
} `json:"owner"`
} `json:"repository"`
ReviewThreads struct {
TotalCount int `json:"totalCount"`
} `json:"reviewThreads"`
} `json:"nodes"`
} `json:"search"`
}
if err := c.query(ctx, listPRsQuery, map[string]any{"owner": owner, "name": name, "limit": limit}, &data); err != nil {
search := "is:pr is:open sort:updated-desc"
if owner != "" {
search += " repo:" + owner + "/" + name
}
if !showAll {
search += " assignee:@me"
}
if err := c.query(ctx, listPRsQuery, map[string]any{"query": search, "limit": limit}, &data); err != nil {
return nil, err
}
if data.Repository == nil {
return nil, fmt.Errorf("repository %s/%s was not found or is not accessible", owner, name)
}
prs := make([]PullRequest, 0, len(data.Repository.PullRequests.Nodes))
for _, node := range data.Repository.PullRequests.Nodes {
prs := make([]PullRequest, 0, len(data.Search.Nodes))
for _, node := range data.Search.Nodes {
if node.Repository.NameWithOwner == "" {
continue
}
author := "[ghost]"
if node.Author != nil {
author = node.Author.Login
}
mine := author == data.Viewer.Login
if !showAll && !mine {
continue
}
prs = append(prs, PullRequest{
ID: node.ID, Number: node.Number, Title: node.Title, URL: node.URL,
ID: node.ID, Owner: node.Repository.Owner.Login, Repository: node.Repository.Name,
RepoWithOwner: node.Repository.NameWithOwner,
Number: node.Number, Title: node.Title, URL: node.URL,
Author: author, IsDraft: node.IsDraft, UpdatedAt: node.UpdatedAt,
ReviewCount: node.ReviewThreads.TotalCount, ViewerAuthored: mine,
ReviewCount: node.ReviewThreads.TotalCount, ViewerAuthored: author == data.Viewer.Login,
})
}
sort.SliceStable(prs, func(i, j int) bool {
left, right := strings.ToLower(prs[i].RepoWithOwner), strings.ToLower(prs[j].RepoWithOwner)
if left != right {
return left < right
}
return prs[i].UpdatedAt.After(prs[j].UpdatedAt)
})
return prs, nil
}
@@ -265,7 +290,8 @@ func (c *GitHubClient) GetPullRequest(ctx context.Context, owner, name string, n
}
details := PRDetails{
PullRequest: PullRequest{
ID: node.ID, Number: node.Number, Title: node.Title, URL: node.URL,
ID: node.ID, Owner: owner, Repository: name, RepoWithOwner: owner + "/" + name,
Number: node.Number, Title: node.Title, URL: node.URL,
Author: author, IsDraft: node.IsDraft, UpdatedAt: node.UpdatedAt,
ReviewCount: len(node.ReviewThreads.Nodes),
},