From b4b0c37febf0904a73e4fb89130ab82ac986d15f Mon Sep 17 00:00:00 2001 From: Corey Johnson Date: Thu, 14 Nov 2019 11:30:53 -0800 Subject: [PATCH] show labels --- api/queries_issue.go | 86 +++++++++++++++++++++++++++++--------------- command/issue.go | 25 ++++++++++--- go.mod | 1 + go.sum | 2 ++ 4 files changed, 81 insertions(+), 33 deletions(-) diff --git a/api/queries_issue.go b/api/queries_issue.go index 0437c7ec7..bbf9b276c 100644 --- a/api/queries_issue.go +++ b/api/queries_issue.go @@ -51,15 +51,29 @@ type IssuesPayload struct { } type Issue struct { - Number int - Title string - URL string + Number int + Title string + URL string + Labels []string + TotalLabelCount int } type apiIssues struct { Issues struct { Edges []struct { - Node Issue + Node struct { + Number int + Title string + URL string + Labels struct { + Edges []struct { + Node struct { + Name string + } + } + TotalCount int + } + } } } } @@ -123,20 +137,9 @@ func IssueStatus(client *Client, ghRepo Repo, currentUsername string) (*IssuesPa 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) - } + assigned := convertAPIToIssues(resp.Assigned) + mentioned := convertAPIToIssues(resp.Mentioned) + recent := convertAPIToIssues(resp.Recent) payload := IssuesPayload{ assigned, @@ -147,7 +150,7 @@ func IssueStatus(client *Client, ghRepo Repo, currentUsername string) (*IssuesPa return &payload, nil } -func IssueList(client *Client, ghRepo Repo, state string, labels []string, assigneeString string) ([]Issue, error) { +func IssueList(client *Client, ghRepo Repo, state string, labels []string, assigneeString string, limit int) ([]Issue, error) { var states []string switch state { case "open", "": @@ -176,11 +179,20 @@ func IssueList(client *Client, ghRepo Repo, state string, labels []string, assig query := ` fragment issue on Issue { number - title - } - query($owner: String!, $repo: String!, $per_page: Int = 10, $states: [IssueState!] = OPEN, $labels: [String!], $assignee: String) { + title + labels(first: 3) { + edges { + node { + name + } + } + totalCount + } + } + + query($owner: String!, $repo: String!, $limit: Int, $states: [IssueState!] = OPEN, $labels: [String!], $assignee: String) { repository(owner: $owner, name: $repo) { - issues(first: $per_page, orderBy: {field: CREATED_AT, direction: DESC}, states: $states, labels: $labels, filterBy: {assignee: $assignee}) { + issues(first: $limit, orderBy: {field: CREATED_AT, direction: DESC}, states: $states, labels: $labels, filterBy: {assignee: $assignee}) { edges { node { ...issue @@ -194,6 +206,7 @@ func IssueList(client *Client, ghRepo Repo, state string, labels []string, assig owner := ghRepo.RepoOwner() repo := ghRepo.RepoName() variables := map[string]interface{}{ + "limit": limit, "owner": owner, "repo": repo, "states": states, @@ -210,10 +223,27 @@ func IssueList(client *Client, ghRepo Repo, state string, labels []string, assig return nil, err } - var issues []Issue - for _, edge := range resp.Repository.Issues.Edges { - issues = append(issues, edge.Node) - } - + issues := convertAPIToIssues(resp.Repository) return issues, nil } + +func convertAPIToIssues(i apiIssues) []Issue { + var issues []Issue + for _, edge := range i.Issues.Edges { + var labels []string + for _, labelEdge := range edge.Node.Labels.Edges { + labels = append(labels, labelEdge.Node.Name) + } + + issue := Issue{ + Number: edge.Node.Number, + Title: edge.Node.Title, + URL: edge.Node.URL, + Labels: labels, + TotalLabelCount: edge.Node.Labels.TotalCount, + } + issues = append(issues, issue) + } + + return issues +} diff --git a/command/issue.go b/command/issue.go index acce47dd7..22fc897b8 100644 --- a/command/issue.go +++ b/command/issue.go @@ -37,9 +37,10 @@ func init() { Short: "List open issues", RunE: issueList, } - issueListCmd.Flags().StringP("assignee", "a", "", "Filter by assignee") - issueListCmd.Flags().StringSliceP("label", "l", nil, "Filter by labels ") - issueListCmd.Flags().StringP("state", "s", "", "Filter by state (open, closed or all)") + issueListCmd.Flags().StringP("assignee", "a", "", "filter by assignee") + issueListCmd.Flags().StringSliceP("label", "l", nil, "filter by label") + issueListCmd.Flags().StringP("state", "s", "", "filter by state (open|closed|all)") + issueListCmd.Flags().IntP("limit", "L", 30, "maximum number of items to fetch (default ") issueCmd.AddCommand((issueListCmd)) } @@ -81,7 +82,12 @@ func issueList(cmd *cobra.Command, args []string) error { return err } - issues, err := api.IssueList(apiClient, baseRepo, state, labels, assignee) + limit, err := cmd.Flags().GetInt("limit") + if err != nil { + return err + } + + issues, err := api.IssueList(apiClient, baseRepo, state, labels, assignee, limit) if err != nil { return err } @@ -238,6 +244,15 @@ func issueCreate(cmd *cobra.Command, args []string) error { func printIssues(issues ...api.Issue) { for _, issue := range issues { - fmt.Printf(" #%d %s\n", issue.Number, truncate(70, issue.Title)) + number := utils.Green("#" + strconv.Itoa(issue.Number)) + var coloredLabels string + if len(issue.Labels) > 0 { + var ellipse string + if issue.TotalLabelCount > len(issue.Labels) { + ellipse = "…" + } + coloredLabels = utils.Gray(fmt.Sprintf(" (%s%s)", strings.Join(issue.Labels, ", "), ellipse)) + } + fmt.Printf(" %s %s %s\n", number, truncate(70, issue.Title), coloredLabels) } } diff --git a/go.mod b/go.mod index 9c89ff7b1..1003bae41 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module github.com/github/gh-cli go 1.13 require ( + github.com/fatih/color v1.7.0 github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 github.com/mattn/go-colorable v0.1.2 github.com/mattn/go-isatty v0.0.9 diff --git a/go.sum b/go.sum index af7d46f56..b94183d79 100644 --- a/go.sum +++ b/go.sum @@ -7,6 +7,8 @@ github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3Ee github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys= +github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=