1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
|
package label
import (
"fmt"
"net/http"
"strings"
"github.com/cli/cli/v2/api"
"github.com/cli/cli/v2/internal/ghrepo"
)
const (
maxPageSize = 100
defaultOrder = "asc"
defaultSort = "created"
)
var defaultFields = []string{
"color",
"description",
"name",
}
type listLabelsResponseData struct {
Repository struct {
Labels struct {
TotalCount int
Nodes []label
PageInfo struct {
HasNextPage bool
EndCursor string
}
}
}
}
type listQueryOptions struct {
Limit int
Query string
Order string
Sort string
fields []string
}
func (opts listQueryOptions) OrderBy() map[string]string {
// Set on copy to keep original intact.
if opts.Order == "" {
opts.Order = defaultOrder
}
if opts.Sort == "" {
opts.Sort = defaultSort
}
field := strings.ToUpper(opts.Sort)
if opts.Sort == "created" {
field = "CREATED_AT"
}
return map[string]string{
"direction": strings.ToUpper(opts.Order),
"field": field,
}
}
// listLabels lists the labels in the given repo. Pass -1 for limit to list all labels;
// otherwise, only that number of labels is returned for any number of pages.
func listLabels(client *http.Client, repo ghrepo.Interface, opts listQueryOptions) ([]label, int, error) {
if len(opts.fields) == 0 {
opts.fields = defaultFields
}
apiClient := api.NewClientFromHTTP(client)
fragment := fmt.Sprintf("fragment label on Label{%s}", strings.Join(opts.fields, ","))
query := fragment + `
query LabelList($owner: String!, $repo: String!, $limit: Int!, $endCursor: String, $query: String, $orderBy: LabelOrder) {
repository(owner: $owner, name: $repo) {
labels(first: $limit, after: $endCursor, query: $query, orderBy: $orderBy) {
totalCount,
nodes {
...label
}
pageInfo {
hasNextPage
endCursor
}
}
}
}`
variables := map[string]interface{}{
"owner": repo.RepoOwner(),
"repo": repo.RepoName(),
"orderBy": opts.OrderBy(),
"query": opts.Query,
}
var labels []label
var totalCount int
loop:
for {
var response listLabelsResponseData
variables["limit"] = determinePageSize(opts.Limit - len(labels))
err := apiClient.GraphQL(repo.RepoHost(), query, variables, &response)
if err != nil {
return nil, 0, err
}
totalCount = response.Repository.Labels.TotalCount
for _, label := range response.Repository.Labels.Nodes {
labels = append(labels, label)
if len(labels) == opts.Limit {
break loop
}
}
if response.Repository.Labels.PageInfo.HasNextPage {
variables["endCursor"] = response.Repository.Labels.PageInfo.EndCursor
} else {
break
}
}
return labels, totalCount, nil
}
func determinePageSize(numRequestedItems int) int {
// If numRequestedItems is -1 then retrieve maxPageSize
if numRequestedItems < 0 || numRequestedItems > maxPageSize {
return maxPageSize
}
return numRequestedItems
}
|