-
Notifications
You must be signed in to change notification settings - Fork 8
feat&perf(base): minor QoL improvements #22
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
42e35de
0875a74
903665e
f4a93ae
f016cb2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
|
|
@@ -7,7 +7,7 @@ | |||||||
| export default async function({login, graphql, rest, data, q, queries, imports, callbacks}, conf) { | ||||||||
| //Load inputs | ||||||||
| console.debug(`metrics/compute/${login}/base > started`) | ||||||||
| let {indepth, hireable, skip, "repositories.forks": _forks, "repositories.affiliations": _affiliations, "repositories.batch": _batch} = imports.metadata.plugins.base.inputs({data, q, account: "bypass"}) | ||||||||
| let {indepth, hireable, skip, "repositories.forks": _forks, "repositories.affiliations": _affiliations, "repositories.owned": _owned, "repositories.batch": _batch} = imports.metadata.plugins.base.inputs({data, q, account: "bypass"}) | ||||||||
| const repositories = conf.settings.repositories || 100 | ||||||||
| const forks = _forks ? "" : ", isFork: false" | ||||||||
| const affiliations = _affiliations?.length ? `, ownerAffiliations: [${_affiliations.map(x => x.toLocaleUpperCase()).join(", ")}]${conf.authenticated === login ? `, affiliations: [${_affiliations.map(x => x.toLocaleUpperCase()).join(", ")}]` : ""}` : "" | ||||||||
|
|
@@ -40,7 +40,7 @@ export default async function({login, graphql, rest, data, q, queries, imports, | |||||||
| console.debug(`metrics/compute/${login}/base > failed to load bulk query, falling back to unit queries`) | ||||||||
| //Query basic fields | ||||||||
| const fields = { | ||||||||
| user: ["packages", "starredRepositories", "watching", "sponsorshipsAsSponsor", "sponsorshipsAsMaintainer", "followers", "following", "issueComments", "organizations", "repositoriesContributedTo(includeUserRepositories: true)"], | ||||||||
| user: ["packages", "starredRepositories", "watching", "sponsorshipsAsSponsor", "sponsorshipsAsMaintainer", "followers", "following", "issueComments", "organizations", `repositoriesContributedTo(includeUserRepositories: ${_owned})`], | ||||||||
| organization: ["packages", "sponsorshipsAsSponsor", "sponsorshipsAsMaintainer", "membersWithRole"], | ||||||||
| }[account] ?? [] | ||||||||
| for (const field of fields) { | ||||||||
|
|
@@ -53,28 +53,24 @@ export default async function({login, graphql, rest, data, q, queries, imports, | |||||||
| } | ||||||||
| } | ||||||||
| //Query repositories fields | ||||||||
| for (const field of ["totalCount", "totalDiskUsage"]) { | ||||||||
| try { | ||||||||
| Object.assign(data.user.repositories, (await graphql(queries.base["field.repositories"]({login, account, field, affiliations})))[account].repositories) | ||||||||
| } | ||||||||
| catch (error) { | ||||||||
| console.debug(`metrics/compute/${login}/base > failed to retrieve repositories.${field}`) | ||||||||
| data.user.repositories[field] = NaN | ||||||||
| } | ||||||||
| try { | ||||||||
| Object.assign(data.user.repositories, (await graphql(queries.base["field.repositories"]({ login, account, affiliations })))[account].repositories) | ||||||||
| } | ||||||||
| catch { | ||||||||
| console.debug(`metrics/compute/${login}/base > failed to retrieve repositories count and disk usage`) | ||||||||
| data.user.repositories["totalCount"] = NaN | ||||||||
| data.user.repositories["totalDiskUsage"] = NaN | ||||||||
| } | ||||||||
| //Query user account fields | ||||||||
| if (account === "user") { | ||||||||
| //Query contributions collection | ||||||||
| { | ||||||||
| const fields = ["totalRepositoriesWithContributedCommits", "totalCommitContributions", "restrictedContributionsCount", "totalIssueContributions", "totalPullRequestContributions", "totalPullRequestReviewContributions"] | ||||||||
| for (const field of fields) { | ||||||||
| try { | ||||||||
| Object.assign(data.user.contributionsCollection, (await graphql(queries.base.contributions({login, account, field, range: ""})))[account].contributionsCollection) | ||||||||
| } | ||||||||
| catch { | ||||||||
| console.debug(`metrics/compute/${login}/base > failed to retrieve contributionsCollection.${field}`) | ||||||||
| data.user.contributionsCollection[field] = NaN | ||||||||
| } | ||||||||
| try { | ||||||||
| Object.assign(data.user.contributionsCollection, (await graphql(queries.base.contributions({ login, account, range: "", indepthFields: ""})))[account].contributionsCollection) | ||||||||
| } | ||||||||
| catch { | ||||||||
| console.debug(`metrics/compute/${login}/base > failed to retrieve contributionsCollection`) | ||||||||
| data.user.contributionsCollection ??= {} | ||||||||
| } | ||||||||
| } | ||||||||
| //Query calendar | ||||||||
|
|
@@ -90,39 +86,62 @@ export default async function({login, graphql, rest, data, q, queries, imports, | |||||||
| //Query contributions collection over account lifetime instead of last year | ||||||||
| if (account === "user") { | ||||||||
| if ((indepth) && (imports.metadata.plugins.base.extras("indepth", {...conf.settings, error: false}))) { | ||||||||
| const fields = ["totalRepositoriesWithContributedCommits", "totalCommitContributions", "restrictedContributionsCount", "totalIssueContributions", "totalPullRequestContributions", "totalPullRequestReviewContributions"] | ||||||||
| const start = new Date(data.user.createdAt) | ||||||||
| const end = new Date() | ||||||||
| const collection = {} | ||||||||
| for (const field of fields) { | ||||||||
| collection[field] = 0 | ||||||||
| //Load contribution calendar | ||||||||
| for (let from = new Date(start); from < end;) { | ||||||||
| //Set date range | ||||||||
| let to = new Date(from) | ||||||||
| to.setUTCHours(+6 * 4 * 7 * 24) | ||||||||
| if (to > end) | ||||||||
| to = end | ||||||||
| //Ensure that date ranges are not overlapping by setting it to previous day at 23:59:59.999 | ||||||||
| const dto = new Date(to) | ||||||||
| dto.setUTCHours(-1) | ||||||||
| dto.setUTCMinutes(59) | ||||||||
| dto.setUTCSeconds(59) | ||||||||
| dto.setUTCMilliseconds(999) | ||||||||
| //Fetch data from api | ||||||||
| try { | ||||||||
| console.debug(`metrics/compute/${login}/plugins > base > loading contributions collections for ${field} from "${from.toISOString()}" to "${dto.toISOString()}"`) | ||||||||
| const {[account]: {contributionsCollection}} = await graphql(queries.base.contributions({login, account, field, range: `(from: "${from.toISOString()}", to: "${dto.toISOString()}")`})) | ||||||||
| collection[field] += contributionsCollection[field] | ||||||||
| } | ||||||||
| catch { | ||||||||
| console.debug(`metrics/compute/${login}/plugins > base > failed to load contributions collections for ${field} from "${from.toISOString()}" to "${dto.toISOString()}"`) | ||||||||
| } | ||||||||
| //Set next date range start | ||||||||
| from = new Date(to) | ||||||||
| const contributions = [] | ||||||||
| const indepthExtraFields = ["commitContributionsByRepository", "pullRequestContributionsByRepository", "issueContributionsByRepository", "pullRequestReviewContributionsByRepository"] | ||||||||
| const totalReposContributed = new Set() | ||||||||
| const lifetimeCollection = {} | ||||||||
| //Load contribution calendar | ||||||||
| for (let from = new Date(start); from < end;) { | ||||||||
| //Set date range | ||||||||
| let to = new Date(from) | ||||||||
| to.setUTCHours(+6 * 4 * 7 * 24) | ||||||||
| if (to > end) | ||||||||
| to = end | ||||||||
| //Ensure that date ranges are not overlapping by setting it to previous day at 23:59:59.999 | ||||||||
| const dto = new Date(to) | ||||||||
| dto.setUTCHours(-1) | ||||||||
| dto.setUTCMinutes(59) | ||||||||
| dto.setUTCSeconds(59) | ||||||||
| dto.setUTCMilliseconds(999) | ||||||||
| //Fetch data from api | ||||||||
| try { | ||||||||
| console.debug(`metrics/compute/${login}/plugins > base > loading contributions collections from "${from.toISOString()}" to "${dto.toISOString()}"`) | ||||||||
| const extraFieldsWithParams = indepthExtraFields.map(x => `${x} { repository { nameWithOwner } }`).join('\n') | ||||||||
| const { [account]: { contributionsCollection } } = await graphql(queries.base.contributions({ login, account, indepthFields: extraFieldsWithParams, range: `(from: "${from.toISOString()}", to: "${dto.toISOString()}")` })) | ||||||||
| contributions.push(contributionsCollection) | ||||||||
| } | ||||||||
| catch { | ||||||||
| console.debug(`metrics/compute/${login}/plugins > base > failed to load contributions collections from "${from.toISOString()}" to "${dto.toISOString()}"`) | ||||||||
| } | ||||||||
| data.user.contributionsCollection[field] = Math.max(collection[field], data.user.contributionsCollection[field]) | ||||||||
| //Set next date range start | ||||||||
| from = new Date(to) | ||||||||
| } | ||||||||
|
|
||||||||
| for (const contribution of contributions) { | ||||||||
| for (const field in contribution) { | ||||||||
| if (indepthExtraFields.includes(field)) { | ||||||||
| for (const repo of contribution[field]) { | ||||||||
| const nameWithOwner = repo.repository.nameWithOwner | ||||||||
| if (!_owned && nameWithOwner.split('/')[0] === login) continue | ||||||||
| totalReposContributed.add(nameWithOwner) | ||||||||
| } | ||||||||
| } else { | ||||||||
| lifetimeCollection[field] ??= 0 | ||||||||
| lifetimeCollection[field] += contribution[field] | ||||||||
| } | ||||||||
|
Comment on lines
+122
to
+133
|
||||||||
| } | ||||||||
| } | ||||||||
|
|
||||||||
| for (const field in lifetimeCollection) { | ||||||||
| data.user.contributionsCollection[field] = Math.max( | ||||||||
| lifetimeCollection[field], | ||||||||
| data.user.contributionsCollection[field] ?? 0 | ||||||||
| ) | ||||||||
| } | ||||||||
|
|
||||||||
|
||||||||
| data.user.repositoriesContributedTo ??= { totalCount: 0 } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -91,6 +91,12 @@ inputs: | |
| type: boolean | ||
| default: no | ||
|
|
||
| repositories_owned: | ||
| description: | | ||
| Include your own repositories in the "Contributed to X repositories" count | ||
| type: boolean | ||
| default: yes | ||
|
Comment on lines
+94
to
+98
|
||
|
|
||
| repositories_affiliations: | ||
| description: | | ||
| Repositories affiliations | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,9 +1,13 @@ | ||
| query BaseContributions { | ||
| user(login: "$login") { | ||
| contributionsCollection$range { | ||
| $field | ||
| totalRepositoriesWithContributedCommits | ||
| totalCommitContributions | ||
| restrictedContributionsCount | ||
| totalIssueContributions | ||
| totalPullRequestContributions | ||
| totalPullRequestReviewContributions | ||
| $indepthFields | ||
| } | ||
| } | ||
| } | ||
|
|
||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,8 @@ | ||
| query BaseFieldRepositories{ | ||
| $account(login: "$login") { | ||
| repositories(last: 0 $affiliations) { | ||
| $field | ||
| totalCount | ||
| totalDiskUsage | ||
| } | ||
| } | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The new
repositories.ownedinput is used here to controlincludeUserRepositoriesin unitfieldqueries and in the indepth lifetime aggregation, but the bulkBaseUserXquery (source/plugins/base/queries/user.x.graphql:30) still hardcodesrepositoriesContributedTo(includeUserRepositories: true). This means that when indepth mode is disabled and the bulk query succeeds, togglingrepositories_ownedhas no effect on the "Contributed to X repositories" count; to align behaviour with the option description, the bulk query should also be parameterised to respect_owned.