cli/api/queries_issue.go
Mislav Marohnić b223176b37 Accept issue URL in issue view <issue>
Also validates that the issue passed either by number or by URL exists.
2019-12-03 21:41:22 +01:00

236 lines
4.7 KiB
Go

package api
import (
"fmt"
)
type IssuesPayload struct {
Assigned []Issue
Mentioned []Issue
Authored []Issue
}
type Issue struct {
Number int
Title string
URL string
State string
Labels struct {
Nodes []IssueLabel
TotalCount int
}
}
type IssueLabel struct {
Name string
}
type apiIssues struct {
Issues struct {
Nodes []Issue
}
}
const fragments = `
fragment issue on Issue {
number
title
url
state
labels(first: 3) {
nodes {
name
}
totalCount
}
}
`
func IssueCreate(client *Client, ghRepo Repo, params map[string]interface{}) (*Issue, error) {
repoID, err := GitHubRepoId(client, ghRepo)
if err != nil {
return nil, err
}
query := `
mutation CreateIssue($input: CreateIssueInput!) {
createIssue(input: $input) {
issue {
url
}
}
}`
inputParams := map[string]interface{}{
"repositoryId": repoID,
}
for key, val := range params {
inputParams[key] = val
}
variables := map[string]interface{}{
"input": inputParams,
}
result := struct {
CreateIssue struct {
Issue Issue
}
}{}
err = client.GraphQL(query, variables, &result)
if err != nil {
return nil, err
}
return &result.CreateIssue.Issue, nil
}
func IssueStatus(client *Client, ghRepo Repo, currentUsername string) (*IssuesPayload, error) {
type response struct {
Assigned apiIssues
Mentioned apiIssues
Authored apiIssues
}
query := fragments + `
query($owner: String!, $repo: String!, $viewer: String!, $per_page: Int = 10) {
assigned: repository(owner: $owner, name: $repo) {
issues(filterBy: {assignee: $viewer, states: OPEN}, first: $per_page, orderBy: {field: CREATED_AT, direction: DESC}) {
nodes {
...issue
}
}
}
mentioned: repository(owner: $owner, name: $repo) {
issues(filterBy: {mentioned: $viewer, states: OPEN}, first: $per_page, orderBy: {field: CREATED_AT, direction: DESC}) {
nodes {
...issue
}
}
}
authored: repository(owner: $owner, name: $repo) {
issues(filterBy: {createdBy: $viewer, states: OPEN}, first: $per_page, orderBy: {field: CREATED_AT, direction: DESC}) {
nodes {
...issue
}
}
}
}
`
owner := ghRepo.RepoOwner()
repo := ghRepo.RepoName()
variables := map[string]interface{}{
"owner": owner,
"repo": repo,
"viewer": currentUsername,
}
var resp response
err := client.GraphQL(query, variables, &resp)
if err != nil {
return nil, err
}
payload := IssuesPayload{
Assigned: resp.Assigned.Issues.Nodes,
Mentioned: resp.Mentioned.Issues.Nodes,
Authored: resp.Authored.Issues.Nodes,
}
return &payload, nil
}
func IssueList(client *Client, ghRepo Repo, state string, labels []string, assigneeString string, limit int) ([]Issue, error) {
var states []string
switch state {
case "open", "":
states = []string{"OPEN"}
case "closed":
states = []string{"CLOSED"}
case "all":
states = []string{"OPEN", "CLOSED"}
default:
return nil, fmt.Errorf("invalid state: %s", state)
}
// If you don't want to filter by lables, graphql requires you need
// to send nil instead of an empty array.
if len(labels) == 0 {
labels = nil
}
var assignee interface{}
if len(assigneeString) > 0 {
assignee = assigneeString
} else {
assignee = nil
}
query := fragments + `
query($owner: String!, $repo: String!, $limit: Int, $states: [IssueState!] = OPEN, $labels: [String!], $assignee: String) {
repository(owner: $owner, name: $repo) {
issues(first: $limit, orderBy: {field: CREATED_AT, direction: DESC}, states: $states, labels: $labels, filterBy: {assignee: $assignee}) {
nodes {
...issue
}
}
}
}
`
owner := ghRepo.RepoOwner()
repo := ghRepo.RepoName()
variables := map[string]interface{}{
"limit": limit,
"owner": owner,
"repo": repo,
"states": states,
"labels": labels,
"assignee": assignee,
}
var resp struct {
Repository apiIssues
}
err := client.GraphQL(query, variables, &resp)
if err != nil {
return nil, err
}
return resp.Repository.Issues.Nodes, nil
}
func IssueByNumber(client *Client, ghRepo Repo, number int) (*Issue, error) {
type response struct {
Repository struct {
Issue Issue
}
}
query := `
query($owner: String!, $repo: String!, $issue_number: Int!) {
repository(owner: $owner, name: $repo) {
issue(number: $issue_number) {
number
url
}
}
}`
variables := map[string]interface{}{
"owner": ghRepo.RepoOwner(),
"repo": ghRepo.RepoName(),
"issue_number": number,
}
var resp response
err := client.GraphQL(query, variables, &resp)
if err != nil {
return nil, err
}
return &resp.Repository.Issue, nil
}