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
|
package shared
import (
"errors"
"net/http"
"strings"
"github.com/cli/cli/v2/api"
"github.com/cli/cli/v2/internal/ghrepo"
)
type RulesetResponse struct {
Level struct {
Rulesets struct {
TotalCount int
Nodes []RulesetGraphQL
PageInfo struct {
HasNextPage bool
EndCursor string
}
}
}
}
type RulesetList struct {
TotalCount int
Rulesets []RulesetGraphQL
}
func ListRepoRulesets(httpClient *http.Client, repo ghrepo.Interface, limit int, includeParents bool) (*RulesetList, error) {
variables := map[string]interface{}{
"owner": repo.RepoOwner(),
"repo": repo.RepoName(),
"includeParents": includeParents,
}
return listRulesets(httpClient, rulesetsQuery(false), variables, limit, repo.RepoHost())
}
func ListOrgRulesets(httpClient *http.Client, orgLogin string, limit int, host string, includeParents bool) (*RulesetList, error) {
variables := map[string]interface{}{
"login": orgLogin,
"includeParents": includeParents,
}
return listRulesets(httpClient, rulesetsQuery(true), variables, limit, host)
}
func listRulesets(httpClient *http.Client, query string, variables map[string]interface{}, limit int, host string) (*RulesetList, error) {
pageLimit := min(limit, 100)
res := RulesetList{
Rulesets: []RulesetGraphQL{},
}
client := api.NewClientFromHTTP(httpClient)
for {
variables["limit"] = pageLimit
var data RulesetResponse
err := client.GraphQL(host, query, variables, &data)
if err != nil {
if strings.Contains(err.Error(), "requires one of the following scopes: ['admin:org']") {
return nil, errors.New("the 'admin:org' scope is required to view organization rulesets, try running 'gh auth refresh -s admin:org'")
}
return nil, err
}
res.TotalCount = data.Level.Rulesets.TotalCount
res.Rulesets = append(res.Rulesets, data.Level.Rulesets.Nodes...)
if len(res.Rulesets) >= limit {
break
}
if data.Level.Rulesets.PageInfo.HasNextPage {
variables["endCursor"] = data.Level.Rulesets.PageInfo.EndCursor
pageLimit = min(pageLimit, limit-len(res.Rulesets))
} else {
break
}
}
return &res, nil
}
func min(a, b int) int {
if a < b {
return a
}
return b
}
func rulesetsQuery(org bool) string {
if org {
return orgGraphQLHeader + sharedGraphQLBody
} else {
return repoGraphQLHeader + sharedGraphQLBody
}
}
const repoGraphQLHeader = `
query RepoRulesetList($limit: Int!, $endCursor: String, $includeParents: Boolean, $owner: String!, $repo: String!) {
level: repository(owner: $owner, name: $repo) {
`
const orgGraphQLHeader = `
query OrgRulesetList($limit: Int!, $endCursor: String, $includeParents: Boolean, $login: String!) {
level: organization(login: $login) {
`
const sharedGraphQLBody = `
rulesets(first: $limit, after: $endCursor, includeParents: $includeParents) {
totalCount
nodes {
databaseId
name
target
enforcement
source {
__typename
... on Repository { owner: nameWithOwner }
... on Organization { owner: login }
}
rules {
totalCount
}
}
pageInfo {
hasNextPage
endCursor
}
}}}`
|