github.com/cli/cli@v1.14.1-0.20210902173923-1af6a669e342/api/query_builder.go (about) 1 package api 2 3 import ( 4 "fmt" 5 "strings" 6 ) 7 8 func squeeze(r rune) rune { 9 switch r { 10 case '\n', '\t': 11 return -1 12 default: 13 return r 14 } 15 } 16 17 func shortenQuery(q string) string { 18 return strings.Map(squeeze, q) 19 } 20 21 var issueComments = shortenQuery(` 22 comments(first: 100) { 23 nodes { 24 author{login}, 25 authorAssociation, 26 body, 27 createdAt, 28 includesCreatedEdit, 29 isMinimized, 30 minimizedReason, 31 reactionGroups{content,users{totalCount}} 32 }, 33 pageInfo{hasNextPage,endCursor}, 34 totalCount 35 } 36 `) 37 38 var prReviewRequests = shortenQuery(` 39 reviewRequests(first: 100) { 40 nodes { 41 requestedReviewer { 42 __typename, 43 ...on User{login}, 44 ...on Team{ 45 organization{login} 46 name, 47 slug 48 } 49 } 50 } 51 } 52 `) 53 54 var prReviews = shortenQuery(` 55 reviews(first: 100) { 56 nodes { 57 author{login}, 58 authorAssociation, 59 submittedAt, 60 body, 61 state, 62 reactionGroups{content,users{totalCount}} 63 } 64 pageInfo{hasNextPage,endCursor} 65 } 66 `) 67 68 var prFiles = shortenQuery(` 69 files(first: 100) { 70 nodes { 71 additions, 72 deletions, 73 path 74 } 75 } 76 `) 77 78 var prCommits = shortenQuery(` 79 commits(first: 100) { 80 nodes { 81 commit { 82 authors(first:100) { 83 nodes { 84 name, 85 email, 86 user{id,login} 87 } 88 }, 89 messageHeadline, 90 messageBody, 91 oid, 92 committedDate, 93 authoredDate 94 } 95 } 96 } 97 `) 98 99 func StatusCheckRollupGraphQL(after string) string { 100 var afterClause string 101 if after != "" { 102 afterClause = ",after:" + after 103 } 104 return fmt.Sprintf(shortenQuery(` 105 statusCheckRollup: commits(last: 1) { 106 nodes { 107 commit { 108 statusCheckRollup { 109 contexts(first:100%s) { 110 nodes { 111 __typename 112 ...on StatusContext { 113 context, 114 state, 115 targetUrl 116 }, 117 ...on CheckRun { 118 name, 119 status, 120 conclusion, 121 startedAt, 122 completedAt, 123 detailsUrl 124 } 125 }, 126 pageInfo{hasNextPage,endCursor} 127 } 128 } 129 } 130 } 131 }`), afterClause) 132 } 133 134 var IssueFields = []string{ 135 "assignees", 136 "author", 137 "body", 138 "closed", 139 "comments", 140 "createdAt", 141 "closedAt", 142 "id", 143 "labels", 144 "milestone", 145 "number", 146 "projectCards", 147 "reactionGroups", 148 "state", 149 "title", 150 "updatedAt", 151 "url", 152 } 153 154 var PullRequestFields = append(IssueFields, 155 "additions", 156 "baseRefName", 157 "changedFiles", 158 "commits", 159 "deletions", 160 "files", 161 "headRefName", 162 "headRepository", 163 "headRepositoryOwner", 164 "isCrossRepository", 165 "isDraft", 166 "maintainerCanModify", 167 "mergeable", 168 "mergeCommit", 169 "mergedAt", 170 "mergedBy", 171 "mergeStateStatus", 172 "potentialMergeCommit", 173 "reviewDecision", 174 "reviewRequests", 175 "reviews", 176 "statusCheckRollup", 177 ) 178 179 func PullRequestGraphQL(fields []string) string { 180 var q []string 181 for _, field := range fields { 182 switch field { 183 case "author": 184 q = append(q, `author{login}`) 185 case "mergedBy": 186 q = append(q, `mergedBy{login}`) 187 case "headRepositoryOwner": 188 q = append(q, `headRepositoryOwner{id,login,...on User{name}}`) 189 case "headRepository": 190 q = append(q, `headRepository{id,name}`) 191 case "assignees": 192 q = append(q, `assignees(first:100){nodes{id,login,name},totalCount}`) 193 case "labels": 194 q = append(q, `labels(first:100){nodes{id,name,description,color},totalCount}`) 195 case "projectCards": 196 q = append(q, `projectCards(first:100){nodes{project{name}column{name}},totalCount}`) 197 case "milestone": 198 q = append(q, `milestone{number,title,description,dueOn}`) 199 case "reactionGroups": 200 q = append(q, `reactionGroups{content,users{totalCount}}`) 201 case "mergeCommit": 202 q = append(q, `mergeCommit{oid}`) 203 case "potentialMergeCommit": 204 q = append(q, `potentialMergeCommit{oid}`) 205 case "comments": 206 q = append(q, issueComments) 207 case "reviewRequests": 208 q = append(q, prReviewRequests) 209 case "reviews": 210 q = append(q, prReviews) 211 case "files": 212 q = append(q, prFiles) 213 case "commits": 214 q = append(q, prCommits) 215 case "lastCommit": // pseudo-field 216 q = append(q, `commits(last:1){nodes{commit{oid}}}`) 217 case "commitsCount": // pseudo-field 218 q = append(q, `commits{totalCount}`) 219 case "requiresStrictStatusChecks": // pseudo-field 220 q = append(q, `baseRef{branchProtectionRule{requiresStrictStatusChecks}}`) 221 case "statusCheckRollup": 222 q = append(q, StatusCheckRollupGraphQL("")) 223 default: 224 q = append(q, field) 225 } 226 } 227 return strings.Join(q, ",") 228 } 229 230 var RepositoryFields = []string{ 231 "id", 232 "name", 233 "nameWithOwner", 234 "owner", 235 "parent", 236 "templateRepository", 237 "description", 238 "homepageUrl", 239 "openGraphImageUrl", 240 "usesCustomOpenGraphImage", 241 "url", 242 "sshUrl", 243 "mirrorUrl", 244 "securityPolicyUrl", 245 246 "createdAt", 247 "pushedAt", 248 "updatedAt", 249 250 "isBlankIssuesEnabled", 251 "isSecurityPolicyEnabled", 252 "hasIssuesEnabled", 253 "hasProjectsEnabled", 254 "hasWikiEnabled", 255 "mergeCommitAllowed", 256 "squashMergeAllowed", 257 "rebaseMergeAllowed", 258 259 "forkCount", 260 "stargazerCount", 261 "watchers", 262 "issues", 263 "pullRequests", 264 265 "codeOfConduct", 266 "contactLinks", 267 "defaultBranchRef", 268 "deleteBranchOnMerge", 269 "diskUsage", 270 "fundingLinks", 271 "isArchived", 272 "isEmpty", 273 "isFork", 274 "isInOrganization", 275 "isMirror", 276 "isPrivate", 277 "isTemplate", 278 "isUserConfigurationRepository", 279 "licenseInfo", 280 "viewerCanAdminister", 281 "viewerDefaultCommitEmail", 282 "viewerDefaultMergeMethod", 283 "viewerHasStarred", 284 "viewerPermission", 285 "viewerPossibleCommitEmails", 286 "viewerSubscription", 287 288 "repositoryTopics", 289 "primaryLanguage", 290 "languages", 291 "issueTemplates", 292 "pullRequestTemplates", 293 "labels", 294 "milestones", 295 "latestRelease", 296 297 "assignableUsers", 298 "mentionableUsers", 299 "projects", 300 301 // "branchProtectionRules", // too complex to expose 302 // "collaborators", // does it make sense to expose without affiliation filter? 303 } 304 305 func RepositoryGraphQL(fields []string) string { 306 var q []string 307 for _, field := range fields { 308 switch field { 309 case "codeOfConduct": 310 q = append(q, "codeOfConduct{key,name,url}") 311 case "contactLinks": 312 q = append(q, "contactLinks{about,name,url}") 313 case "fundingLinks": 314 q = append(q, "fundingLinks{platform,url}") 315 case "licenseInfo": 316 q = append(q, "licenseInfo{key,name,nickname}") 317 case "owner": 318 q = append(q, "owner{id,login}") 319 case "parent": 320 q = append(q, "parent{id,name,owner{id,login}}") 321 case "templateRepository": 322 q = append(q, "templateRepository{id,name,owner{id,login}}") 323 case "repositoryTopics": 324 q = append(q, "repositoryTopics(first:100){nodes{topic{name}}}") 325 case "issueTemplates": 326 q = append(q, "issueTemplates{name,title,body,about}") 327 case "pullRequestTemplates": 328 q = append(q, "pullRequestTemplates{body,filename}") 329 case "labels": 330 q = append(q, "labels(first:100){nodes{id,color,name,description}}") 331 case "languages": 332 q = append(q, "languages(first:100){edges{size,node{name}}}") 333 case "primaryLanguage": 334 q = append(q, "primaryLanguage{name}") 335 case "latestRelease": 336 q = append(q, "latestRelease{publishedAt,tagName,name,url}") 337 case "milestones": 338 q = append(q, "milestones(first:100,states:OPEN){nodes{number,title,description,dueOn}}") 339 case "assignableUsers": 340 q = append(q, "assignableUsers(first:100){nodes{id,login,name}}") 341 case "mentionableUsers": 342 q = append(q, "mentionableUsers(first:100){nodes{id,login,name}}") 343 case "projects": 344 q = append(q, "projects(first:100,states:OPEN){nodes{id,name,number,body,resourcePath}}") 345 case "watchers": 346 q = append(q, "watchers{totalCount}") 347 case "issues": 348 q = append(q, "issues(states:OPEN){totalCount}") 349 case "pullRequests": 350 q = append(q, "pullRequests(states:OPEN){totalCount}") 351 case "defaultBranchRef": 352 q = append(q, "defaultBranchRef{name}") 353 default: 354 q = append(q, field) 355 } 356 } 357 return strings.Join(q, ",") 358 }