feat(plugins/base): add indepth mode for more accurate stats (#999) [skip ci]
This commit is contained in:
@@ -7,7 +7,8 @@
|
|||||||
export default async function({login, graphql, rest, data, q, queries, imports}, conf) {
|
export default async function({login, graphql, rest, data, q, queries, imports}, conf) {
|
||||||
//Load inputs
|
//Load inputs
|
||||||
console.debug(`metrics/compute/${login}/base > started`)
|
console.debug(`metrics/compute/${login}/base > started`)
|
||||||
let {"repositories.forks":_forks, "repositories.affiliations":_affiliations, "repositories.batch":_batch} = imports.metadata.plugins.base.inputs({data, q, account:"bypass"})
|
let {indepth, "repositories.forks":_forks, "repositories.affiliations":_affiliations, "repositories.batch":_batch} = imports.metadata.plugins.base.inputs({data, q, account:"bypass"})
|
||||||
|
const extras = conf.settings.extras?.features ?? conf.settings.extras?.default
|
||||||
const repositories = conf.settings.repositories || 100
|
const repositories = conf.settings.repositories || 100
|
||||||
const forks = _forks ? "" : ", isFork: false"
|
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(", ")}]` : ""}` : ""
|
const affiliations = _affiliations?.length ? `, ownerAffiliations: [${_affiliations.map(x => x.toLocaleUpperCase()).join(", ")}]${conf.authenticated === login ? `, affiliations: [${_affiliations.map(x => x.toLocaleUpperCase()).join(", ")}]` : ""}` : ""
|
||||||
@@ -67,7 +68,7 @@ export default async function({login, graphql, rest, data, q, queries, imports},
|
|||||||
const fields = ["totalRepositoriesWithContributedCommits", "totalCommitContributions", "restrictedContributionsCount", "totalIssueContributions", "totalPullRequestContributions", "totalPullRequestReviewContributions"]
|
const fields = ["totalRepositoriesWithContributedCommits", "totalCommitContributions", "restrictedContributionsCount", "totalIssueContributions", "totalPullRequestContributions", "totalPullRequestReviewContributions"]
|
||||||
for (const field of fields) {
|
for (const field of fields) {
|
||||||
try {
|
try {
|
||||||
Object.assign(data.user.contributionsCollection, (await graphql(queries.base.contributions({login, account, field})))[account].contributionsCollection)
|
Object.assign(data.user.contributionsCollection, (await graphql(queries.base.contributions({login, account, field, range:""})))[account].contributionsCollection)
|
||||||
}
|
}
|
||||||
catch {
|
catch {
|
||||||
console.debug(`metrics/compute/${login}/base > failed to retrieve contributionsCollection.${field}`)
|
console.debug(`metrics/compute/${login}/base > failed to retrieve contributionsCollection.${field}`)
|
||||||
@@ -85,6 +86,55 @@ 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)&&(extras)) {
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
data.user.contributionsCollection[field] = Math.max(collection[field], data.user.contributionsCollection[field])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//Fallback to load whole commit history rather than last year
|
||||||
|
else {
|
||||||
|
try {
|
||||||
|
console.debug(`metrics/compute/${login}/base > loading user commits history`)
|
||||||
|
const {data:{total_count:total = 0}} = await rest.search.commits({q:`author:${login}`})
|
||||||
|
data.user.contributionsCollection.totalCommitContributions = Math.max(total, data.user.contributionsCollection.totalCommitContributions)
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
console.debug(`metrics/compute/${login}/base > falling back to last year commits history`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
//Query repositories from GitHub API
|
//Query repositories from GitHub API
|
||||||
for (const type of ({user:["repositories", "repositoriesContributedTo"], organization:["repositories"]}[account] ?? [])) {
|
for (const type of ({user:["repositories", "repositoriesContributedTo"], organization:["repositories"]}[account] ?? [])) {
|
||||||
//Iterate through repositories
|
//Iterate through repositories
|
||||||
@@ -123,17 +173,6 @@ export default async function({login, graphql, rest, data, q, queries, imports},
|
|||||||
data.user[type].nodes.splice(repositories)
|
data.user[type].nodes.splice(repositories)
|
||||||
console.debug(`metrics/compute/${login}/base > loaded ${data.user[type].nodes.length} ${type}`)
|
console.debug(`metrics/compute/${login}/base > loaded ${data.user[type].nodes.length} ${type}`)
|
||||||
}
|
}
|
||||||
//For user accounts, attempt to load whole commit history rather than last year
|
|
||||||
if (account === "user") {
|
|
||||||
try {
|
|
||||||
console.debug(`metrics/compute/${login}/base > loading user commits history`)
|
|
||||||
const {data:{total_count:total = 0}} = await rest.search.commits({q:`author:${login}`})
|
|
||||||
data.user.contributionsCollection.totalCommitContributions = Math.max(total, data.user.contributionsCollection.totalCommitContributions)
|
|
||||||
}
|
|
||||||
catch {
|
|
||||||
console.debug(`metrics/compute/${login}/base > falling back to last year commits history`)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//Shared options
|
//Shared options
|
||||||
let {"repositories.skipped":skipped, "users.ignored":ignored, "commits.authoring":authoring} = imports.metadata.plugins.base.inputs({data, q, account:"bypass"})
|
let {"repositories.skipped":skipped, "users.ignored":ignored, "commits.authoring":authoring} = imports.metadata.plugins.base.inputs({data, q, account:"bypass"})
|
||||||
data.shared = {"repositories.skipped":skipped, "users.ignored":ignored, "commits.authoring":authoring, "repositories.batch":_batch}
|
data.shared = {"repositories.skipped":skipped, "users.ignored":ignored, "commits.authoring":authoring, "repositories.batch":_batch}
|
||||||
|
|||||||
@@ -35,6 +35,21 @@ inputs:
|
|||||||
- repositories
|
- repositories
|
||||||
- metadata
|
- metadata
|
||||||
|
|
||||||
|
base_indepth:
|
||||||
|
extras: yes
|
||||||
|
description: |
|
||||||
|
Indepth mode
|
||||||
|
|
||||||
|
Enabling this will consume additional API queries to fetch more data.
|
||||||
|
This currently improves the accuracy of the following statistics:
|
||||||
|
- total commits
|
||||||
|
- total issues
|
||||||
|
- total pull requests
|
||||||
|
- total pull requests reviews
|
||||||
|
- total repositories contributed to
|
||||||
|
type: boolean
|
||||||
|
default: no
|
||||||
|
|
||||||
repositories:
|
repositories:
|
||||||
description: |
|
description: |
|
||||||
Repositories to fetch
|
Repositories to fetch
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
query BaseContributions {
|
query BaseContributions {
|
||||||
user(login: "$login") {
|
user(login: "$login") {
|
||||||
contributionsCollection {
|
contributionsCollection$range {
|
||||||
$field
|
$field
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user