cli/api/queries.go
2019-10-30 12:00:16 -05:00

244 lines
5 KiB
Go

package api
import (
"fmt"
)
type PullRequestsPayload struct {
ViewerCreated []PullRequest
ReviewRequested []PullRequest
CurrentPR *PullRequest
}
type PullRequest struct {
Number int
Title string
URL string
HeadRefName string
}
type Repo interface {
RepoName() string
RepoOwner() string
}
func GitHubRepoId(client *Client, ghRepo Repo) (string, error) {
owner := ghRepo.RepoOwner()
repo := ghRepo.RepoName()
query := `
query FindRepoID($owner:String!, $name:String!) {
repository(owner:$owner, name:$name) {
id
}
}`
variables := map[string]interface{}{
"owner": owner,
"name": repo,
}
result := struct {
Repository struct {
Id string
}
}{}
err := client.GraphQL(query, variables, &result)
if err != nil {
return "", fmt.Errorf("failed to determine GH repo ID: %s", err)
}
return result.Repository.Id, nil
}
func PullRequests(client *Client, ghRepo Repo, currentBranch, currentUsername string) (*PullRequestsPayload, error) {
type edges struct {
Edges []struct {
Node PullRequest
}
PageInfo struct {
HasNextPage bool
EndCursor string
}
}
type response struct {
Repository struct {
PullRequests edges
}
ViewerCreated edges
ReviewRequested edges
}
query := `
fragment pr on PullRequest {
number
title
url
headRefName
}
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: 1) {
edges {
node {
...pr
}
}
}
}
viewerCreated: search(query: $viewerQuery, type: ISSUE, first: $per_page) {
edges {
node {
...pr
}
}
pageInfo {
hasNextPage
}
}
reviewRequested: search(query: $reviewerQuery, type: ISSUE, first: $per_page) {
edges {
node {
...pr
}
}
pageInfo {
hasNextPage
}
}
}
`
owner := ghRepo.RepoOwner()
repo := ghRepo.RepoName()
viewerQuery := fmt.Sprintf("repo:%s/%s state:open is:pr author:%s", owner, repo, currentUsername)
reviewerQuery := fmt.Sprintf("repo:%s/%s state:open review-requested:%s", owner, repo, currentUsername)
variables := map[string]interface{}{
"viewerQuery": viewerQuery,
"reviewerQuery": reviewerQuery,
"owner": owner,
"repo": repo,
"headRefName": currentBranch,
}
var resp response
err := client.GraphQL(query, variables, &resp)
if err != nil {
return nil, err
}
var viewerCreated []PullRequest
for _, edge := range resp.ViewerCreated.Edges {
viewerCreated = append(viewerCreated, edge.Node)
}
var reviewRequested []PullRequest
for _, edge := range resp.ReviewRequested.Edges {
reviewRequested = append(reviewRequested, edge.Node)
}
var currentPR *PullRequest
for _, edge := range resp.Repository.PullRequests.Edges {
currentPR = &edge.Node
}
payload := PullRequestsPayload{
viewerCreated,
reviewRequested,
currentPR,
}
return &payload, nil
}
func PullRequestsForBranch(client *Client, ghRepo Repo, branch string) ([]PullRequest, error) {
type response struct {
Repository struct {
PullRequests struct {
Edges []struct {
Node PullRequest
}
}
}
}
query := `
query($owner: String!, $repo: String!, $headRefName: String!) {
repository(owner: $owner, name: $repo) {
pullRequests(headRefName: $headRefName, states: OPEN, first: 1) {
edges {
node {
number
title
url
}
}
}
}
}`
variables := map[string]interface{}{
"owner": ghRepo.RepoOwner(),
"repo": ghRepo.RepoName(),
"headRefName": branch,
}
var resp response
err := client.GraphQL(query, variables, &resp)
if err != nil {
return nil, err
}
prs := []PullRequest{}
for _, edge := range resp.Repository.PullRequests.Edges {
prs = append(prs, edge.Node)
}
return prs, nil
}
func CreatePullRequest(client *Client, ghRepo Repo, title string, body string, draft bool, base string, head string) (string, error) {
repoId, err := GitHubRepoId(client, ghRepo)
if err != nil {
return "", err
}
if repoId == "" {
return "", fmt.Errorf("could not determine GH repo ID")
}
query := `
mutation CreatePullRequest($input: CreatePullRequestInput!) {
createPullRequest(input: $input) {
pullRequest {
url
}
}
}`
variables := map[string]interface{}{
"input": map[string]interface{}{
"repositoryId": repoId,
"baseRefName": base,
"headRefName": head,
"title": title,
"body": body,
"draft": draft,
},
}
result := struct {
CreatePullRequest struct {
PullRequest PullRequest
}
}{}
err = client.GraphQL(query, variables, &result)
if err != nil {
return "", err
}
return result.CreatePullRequest.PullRequest.URL, nil
}