Add state
This commit is contained in:
parent
817820e464
commit
44c7495bab
5 changed files with 252 additions and 145 deletions
104
api/queries.go
104
api/queries.go
|
|
@ -2,7 +2,6 @@ package api
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
type PullRequestsPayload struct {
|
||||
|
|
@ -24,109 +23,6 @@ type Repo interface {
|
|||
RepoOwner() string
|
||||
}
|
||||
|
||||
type IssuesPayload struct {
|
||||
Assigned []Issue
|
||||
Mentioned []Issue
|
||||
Recent []Issue
|
||||
}
|
||||
|
||||
type Issue struct {
|
||||
Number int
|
||||
Title string
|
||||
URL string
|
||||
}
|
||||
|
||||
func Issues(client *Client, ghRepo Repo, currentUsername string) (*IssuesPayload, error) {
|
||||
type issues struct {
|
||||
Issues struct {
|
||||
Edges []struct {
|
||||
Node Issue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type response struct {
|
||||
Assigned issues
|
||||
Mentioned issues
|
||||
Recent issues
|
||||
}
|
||||
|
||||
query := `
|
||||
fragment issue on Issue {
|
||||
number
|
||||
title
|
||||
}
|
||||
query($owner: String!, $repo: String!, $since: DateTime!, $viewer: String!, $per_page: Int = 10) {
|
||||
assigned: repository(owner: $owner, name: $repo) {
|
||||
issues(filterBy: {assignee: $viewer}, first: $per_page, orderBy: {field: CREATED_AT, direction: DESC}) {
|
||||
edges {
|
||||
node {
|
||||
...issue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
mentioned: repository(owner: $owner, name: $repo) {
|
||||
issues(filterBy: {mentioned: $viewer}, first: $per_page, orderBy: {field: CREATED_AT, direction: DESC}) {
|
||||
edges {
|
||||
node {
|
||||
...issue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
recent: repository(owner: $owner, name: $repo) {
|
||||
issues(filterBy: {since: $since}, first: $per_page, orderBy: {field: CREATED_AT, direction: DESC}) {
|
||||
edges {
|
||||
node {
|
||||
...issue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
owner := ghRepo.RepoOwner()
|
||||
repo := ghRepo.RepoName()
|
||||
since := time.Now().UTC().Add(time.Hour * -24).Format("2006-01-02T15:04:05-0700")
|
||||
variables := map[string]interface{}{
|
||||
"owner": owner,
|
||||
"repo": repo,
|
||||
"viewer": currentUsername,
|
||||
"since": since,
|
||||
}
|
||||
|
||||
var resp response
|
||||
err := client.GraphQL(query, variables, &resp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var assigned []Issue
|
||||
for _, edge := range resp.Assigned.Issues.Edges {
|
||||
assigned = append(assigned, edge.Node)
|
||||
}
|
||||
|
||||
var mentioned []Issue
|
||||
for _, edge := range resp.Mentioned.Issues.Edges {
|
||||
mentioned = append(mentioned, edge.Node)
|
||||
}
|
||||
|
||||
var recent []Issue
|
||||
for _, edge := range resp.Recent.Issues.Edges {
|
||||
recent = append(recent, edge.Node)
|
||||
}
|
||||
|
||||
payload := IssuesPayload{
|
||||
assigned,
|
||||
mentioned,
|
||||
recent,
|
||||
}
|
||||
|
||||
return &payload, nil
|
||||
}
|
||||
|
||||
func PullRequests(client *Client, ghRepo Repo, currentBranch, currentUsername string) (*PullRequestsPayload, error) {
|
||||
type edges struct {
|
||||
Edges []struct {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,10 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
func IssueCreate(client *Client, ghRepo Repo, params map[string]interface{}) (*Issue, error) {
|
||||
repoID, err := GitHubRepoId(client, ghRepo)
|
||||
if err != nil {
|
||||
|
|
@ -38,3 +43,162 @@ func IssueCreate(client *Client, ghRepo Repo, params map[string]interface{}) (*I
|
|||
|
||||
return &result.CreateIssue.Issue, nil
|
||||
}
|
||||
|
||||
type IssuesPayload struct {
|
||||
Assigned []Issue
|
||||
Mentioned []Issue
|
||||
Recent []Issue
|
||||
}
|
||||
|
||||
type Issue struct {
|
||||
Number int
|
||||
Title string
|
||||
URL string
|
||||
}
|
||||
|
||||
type apiIssues struct {
|
||||
Issues struct {
|
||||
Edges []struct {
|
||||
Node Issue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func IssueStatus(client *Client, ghRepo Repo, currentUsername string) (*IssuesPayload, error) {
|
||||
type response struct {
|
||||
Assigned apiIssues
|
||||
Mentioned apiIssues
|
||||
Recent apiIssues
|
||||
}
|
||||
|
||||
query := `
|
||||
fragment issue on Issue {
|
||||
number
|
||||
title
|
||||
}
|
||||
query($owner: String!, $repo: String!, $since: DateTime!, $viewer: String!, $per_page: Int = 10) {
|
||||
assigned: repository(owner: $owner, name: $repo) {
|
||||
issues(filterBy: {assignee: $viewer}, first: $per_page, orderBy: {field: CREATED_AT, direction: DESC}) {
|
||||
edges {
|
||||
node {
|
||||
...issue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
mentioned: repository(owner: $owner, name: $repo) {
|
||||
issues(filterBy: {mentioned: $viewer}, first: $per_page, orderBy: {field: CREATED_AT, direction: DESC}) {
|
||||
edges {
|
||||
node {
|
||||
...issue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
recent: repository(owner: $owner, name: $repo) {
|
||||
issues(filterBy: {since: $since}, first: $per_page, orderBy: {field: CREATED_AT, direction: DESC}) {
|
||||
edges {
|
||||
node {
|
||||
...issue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
owner := ghRepo.RepoOwner()
|
||||
repo := ghRepo.RepoName()
|
||||
since := time.Now().UTC().Add(time.Hour * -24).Format("2006-01-02T15:04:05-0700")
|
||||
variables := map[string]interface{}{
|
||||
"owner": owner,
|
||||
"repo": repo,
|
||||
"viewer": currentUsername,
|
||||
"since": since,
|
||||
}
|
||||
|
||||
var resp response
|
||||
err := client.GraphQL(query, variables, &resp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var assigned []Issue
|
||||
for _, edge := range resp.Assigned.Issues.Edges {
|
||||
assigned = append(assigned, edge.Node)
|
||||
}
|
||||
|
||||
var mentioned []Issue
|
||||
for _, edge := range resp.Mentioned.Issues.Edges {
|
||||
mentioned = append(mentioned, edge.Node)
|
||||
}
|
||||
|
||||
var recent []Issue
|
||||
for _, edge := range resp.Recent.Issues.Edges {
|
||||
recent = append(recent, edge.Node)
|
||||
}
|
||||
|
||||
payload := IssuesPayload{
|
||||
assigned,
|
||||
mentioned,
|
||||
recent,
|
||||
}
|
||||
|
||||
return &payload, nil
|
||||
}
|
||||
|
||||
func IssueList(client *Client, ghRepo Repo, state string) ([]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)
|
||||
}
|
||||
|
||||
query := `
|
||||
fragment issue on Issue {
|
||||
number
|
||||
title
|
||||
}
|
||||
query($owner: String!, $repo: String!, $per_page: Int = 10, $states: [IssueState!] = OPEN) {
|
||||
repository(owner: $owner, name: $repo) {
|
||||
issues(first: $per_page, orderBy: {field: CREATED_AT, direction: DESC}, states: $states) {
|
||||
edges {
|
||||
node {
|
||||
...issue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
owner := ghRepo.RepoOwner()
|
||||
repo := ghRepo.RepoName()
|
||||
variables := map[string]interface{}{
|
||||
"owner": owner,
|
||||
"repo": repo,
|
||||
"states": states,
|
||||
}
|
||||
|
||||
var resp struct {
|
||||
Repository apiIssues
|
||||
}
|
||||
|
||||
err := client.GraphQL(query, variables, &resp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var issues []Issue
|
||||
for _, edge := range resp.Repository.Issues.Edges {
|
||||
issues = append(issues, edge.Node)
|
||||
}
|
||||
|
||||
return issues, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ func init() {
|
|||
&cobra.Command{
|
||||
Use: "status",
|
||||
Short: "Show status of relevant issues",
|
||||
RunE: issueList,
|
||||
RunE: issueStatus,
|
||||
},
|
||||
&cobra.Command{
|
||||
Use: "view <issue-number>",
|
||||
|
|
@ -31,6 +31,16 @@ func init() {
|
|||
issueCmd.AddCommand(issueCreateCmd)
|
||||
issueCreateCmd.Flags().StringArrayP("message", "m", nil, "set title and body")
|
||||
issueCreateCmd.Flags().BoolP("web", "w", false, "open the web browser to create an issue")
|
||||
|
||||
issueListCmd := &cobra.Command{
|
||||
Use: "list",
|
||||
Short: "List open issues",
|
||||
RunE: issueList,
|
||||
}
|
||||
issueListCmd.Flags().StringP("assignee", "a", "", "filter by assignee")
|
||||
issueListCmd.Flags().StringP("label", "l", "", "Filter by assignee")
|
||||
issueListCmd.Flags().StringP("state", "s", "", "Filter by state")
|
||||
issueCmd.AddCommand((issueListCmd))
|
||||
}
|
||||
|
||||
var issueCmd = &cobra.Command{
|
||||
|
|
@ -56,12 +66,43 @@ func issueList(cmd *cobra.Command, args []string) error {
|
|||
return err
|
||||
}
|
||||
|
||||
state, err := cmd.Flags().GetString("state")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
issues, err := api.IssueList(apiClient, baseRepo, state)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(issues) > 0 {
|
||||
printIssues(issues...)
|
||||
} else {
|
||||
message := fmt.Sprintf("There are no open issues")
|
||||
printMessage(message)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func issueStatus(cmd *cobra.Command, args []string) error {
|
||||
ctx := contextForCommand(cmd)
|
||||
apiClient, err := apiClientForContext(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
baseRepo, err := ctx.BaseRepo()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
currentUser, err := ctx.AuthLogin()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
issuePayload, err := api.Issues(apiClient, baseRepo, currentUser)
|
||||
issuePayload, err := api.IssueStatus(apiClient, baseRepo, currentUser)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,6 +40,32 @@ func TestIssueStatus(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestIssueList(t *testing.T) {
|
||||
initBlankContext("OWNER/REPO", "master")
|
||||
http := initFakeHTTP()
|
||||
|
||||
jsonFile, _ := os.Open("../test/fixtures/issueList.json")
|
||||
defer jsonFile.Close()
|
||||
http.StubResponse(200, jsonFile)
|
||||
|
||||
output, err := test.RunCommand(RootCmd, "issue list")
|
||||
if err != nil {
|
||||
t.Errorf("error running command `issue list`: %v", err)
|
||||
}
|
||||
|
||||
expectedIssues := []*regexp.Regexp{
|
||||
regexp.MustCompile(`#1.*won`),
|
||||
regexp.MustCompile(`#2.*too`),
|
||||
regexp.MustCompile(`#4.*fore`),
|
||||
}
|
||||
|
||||
for _, r := range expectedIssues {
|
||||
if !r.MatchString(output) {
|
||||
t.Errorf("output did not match regexp /%s/", r)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestIssueView(t *testing.T) {
|
||||
initBlankContext("OWNER/REPO", "master")
|
||||
http := initFakeHTTP()
|
||||
|
|
|
|||
58
test/fixtures/issueList.json
vendored
58
test/fixtures/issueList.json
vendored
|
|
@ -1,47 +1,27 @@
|
|||
{
|
||||
"data": {
|
||||
"assigned": {
|
||||
"issues": {
|
||||
"edges": [
|
||||
{
|
||||
"node": {
|
||||
"number": 9,
|
||||
"title": "corey thinks squash tastes bad"
|
||||
}
|
||||
},
|
||||
{
|
||||
"node": {
|
||||
"number": 10,
|
||||
"title": "broccoli is a superfood"
|
||||
}
|
||||
"issues": {
|
||||
"edges": [
|
||||
{
|
||||
"node": {
|
||||
"number": 1,
|
||||
"title": "number won"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"mentioned": {
|
||||
"issues": {
|
||||
"edges": [
|
||||
{
|
||||
"node": {
|
||||
"number": 8,
|
||||
"title": "rabbits eat carrots"
|
||||
}
|
||||
},
|
||||
{
|
||||
"node": {
|
||||
"number": 11,
|
||||
"title": "swiss chard is neutral"
|
||||
}
|
||||
},
|
||||
{
|
||||
"node": {
|
||||
"number": 2,
|
||||
"title": "number too"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"node": {
|
||||
"number": 4,
|
||||
"title": "number fore"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"recent": {
|
||||
"issues": {
|
||||
"edges": []
|
||||
}
|
||||
},
|
||||
|
||||
"pageInfo": { "hasNextPage": false }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue