diff --git a/source/plugins/notable/index.mjs b/source/plugins/notable/index.mjs index 7da5bebd..6a3cb514 100644 --- a/source/plugins/notable/index.mjs +++ b/source/plugins/notable/index.mjs @@ -7,29 +7,29 @@ export default async function({login, q, imports, rest, graphql, data, account, return null //Load inputs - let {filter, skipped, repositories, from, indepth} = imports.metadata.plugins.notable.inputs({data, account, q}) + let {filter, skipped, repositories, types, from, indepth} = imports.metadata.plugins.notable.inputs({data, account, q}) skipped.push(...data.shared["repositories.skipped"]) //Iterate through contributed repositories - const commits = [] + let contributions = [] { let cursor = null let pushed = 0 do { console.debug(`metrics/compute/${login}/plugins > notable > retrieving contributed repositories after ${cursor}`) - const {user:{repositoriesContributedTo:{edges}}} = await graphql(queries.notable.contributions({login, after:cursor ? `after: "${cursor}"` : "", repositories:data.shared["repositories.batch"] || 100})) + const {user:{repositoriesContributedTo:{edges}}} = await graphql(queries.notable.contributions({login, types:types.map(x => x.toLocaleUpperCase()).join(", "), after:cursor ? `after: "${cursor}"` : "", repositories:data.shared["repositories.batch"] || 100})) cursor = edges?.[edges?.length - 1]?.cursor edges .filter(({node}) => !((skipped.includes(node.nameWithOwner.toLocaleLowerCase())) || (skipped.includes(node.nameWithOwner.split("/")[1].toLocaleLowerCase())))) .filter(({node}) => ({all:true, organization:node.isInOrganization, user:!node.isInOrganization}[from])) .filter(({node}) => imports.ghfilter(filter, {name:node.nameWithOwner, user:node.owner.login, stars:node.stargazers.totalCount, watchers:node.watchers.totalCount, forks:node.forks.totalCount})) - .map(({node}) => commits.push({handle:node.nameWithOwner, stars:node.stargazers.totalCount, organization:node.isInOrganization, avatarUrl:node.owner.avatarUrl})) + .map(({node}) => contributions.push({handle:node.nameWithOwner, stars:node.stargazers.totalCount, issues:node.issues.totalCount, pulls:node.pullRequests.totalCount, organization:node.isInOrganization, avatarUrl:node.owner.avatarUrl})) pushed = edges.length } while ((pushed) && (cursor)) } //Set contributions - let contributions = (await Promise.all(commits.map(async ({handle, stars, avatarUrl, organization}) => ({name:handle.split("/").shift(), handle, stars, avatar:await imports.imgb64(avatarUrl), organization})))).sort((a, b) => a.name.localeCompare(b.name)) + contributions = (await Promise.all(contributions.map(async ({handle, stars, issues, pulls, avatarUrl, organization}) => ({name:handle.split("/").shift(), handle, stars, issues, pulls, avatar:await imports.imgb64(avatarUrl), organization})))).sort((a, b) => a.name.localeCompare(b.name)) console.debug(`metrics/compute/${login}/plugins > notable > found ${contributions.length} notable contributions`) //Extras features @@ -37,6 +37,36 @@ export default async function({login, q, imports, rest, graphql, data, account, //Indepth if (indepth) { console.debug(`metrics/compute/${login}/plugins > notable > indepth`) + + //Fetch issues + const issues = {} + if (types.includes("issue")) { + let cursor = null + let pushed = 0 + do { + console.debug(`metrics/compute/${login}/plugins > notable > retrieving user issues after ${cursor}`) + const {user:{issues:{edges}}} = await graphql(queries.notable.issues({login, type:"issues", after:cursor ? `after: "${cursor}"` : ""})) + cursor = edges?.[edges?.length - 1]?.cursor + edges.map(({node:{repository:{nameWithOwner:repository}}}) => issues[repository] = (issues[repositories] ?? 0) + 1) + pushed = edges.length + } while ((pushed) && (cursor)) + } + + //Fetch pull requests + const pulls = {} + if (types.includes("pull_request")) { + let cursor = null + let pushed = 0 + do { + console.debug(`metrics/compute/${login}/plugins > notable > retrieving user pull requests after ${cursor}`) + const {user:{pullRequests:{edges}}} = await graphql(queries.notable.issues({login, type:"pullRequests", after:cursor ? `after: "${cursor}"` : ""})) + cursor = edges?.[edges?.length - 1]?.cursor + edges.map(({node:{repository:{nameWithOwner:repository}}}) => pulls[repository] = (pulls[repositories] ?? 0) + 1) + pushed = edges.length + } while ((pushed) && (cursor)) + } + + //Fetch commits for (const contribution of contributions) { //Prepare data const {handle, stars} = contribution @@ -59,8 +89,10 @@ export default async function({login, q, imports, rest, graphql, data, account, commits, percentage:commits / contribution.history, maintainer:maintainers.includes(login), + issues:issues[handle] ?? 0, + pulls:pulls[handle] ?? 0, get stars() { - return this.maintainer ? stars : this.percentage * stars + return Math.round(this.maintainer ? stars : this.percentage * stars) }, } console.debug(`metrics/compute/${login}/plugins > notable > indepth > successfully processed ${owner}/${repo}`) @@ -106,7 +138,7 @@ export default async function({login, q, imports, rest, graphql, data, account, } //Results - return {contributions} + return {contributions, types} } //Handle errors catch (error) { diff --git a/source/plugins/notable/metadata.yml b/source/plugins/notable/metadata.yml index de4b4ef2..a87875d7 100644 --- a/source/plugins/notable/metadata.yml +++ b/source/plugins/notable/metadata.yml @@ -63,3 +63,20 @@ inputs: type: boolean default: no extras: yes + + plugin_notable_types: + description: | + Contribution types filter + + Use a combination of below values to include repositories where: + - `commit`: a commit on default branch was made + - `pull_request`: a pull request was opened + - `issue`: an issue was opened + type: array + format: comma-separated + default: commit + example: commit, pull_request + values: + - commit + - pull_request + - issue diff --git a/source/plugins/notable/queries/contributions.graphql b/source/plugins/notable/queries/contributions.graphql index fd70cef9..6bc04695 100644 --- a/source/plugins/notable/queries/contributions.graphql +++ b/source/plugins/notable/queries/contributions.graphql @@ -1,6 +1,6 @@ query NotableContributions { user(login: "$login") { - repositoriesContributedTo($after first: $repositories, contributionTypes: COMMIT, orderBy: { field: STARGAZERS, direction: DESC }) { + repositoriesContributedTo($after first: $repositories, contributionTypes: [$types], orderBy: { field: STARGAZERS, direction: DESC }) { edges { cursor node { @@ -19,6 +19,12 @@ query NotableContributions { stargazers { totalCount } + issues { + totalCount + } + pullRequests { + totalCount + } } } } diff --git a/source/plugins/notable/queries/issues.graphql b/source/plugins/notable/queries/issues.graphql new file mode 100644 index 00000000..3b75dffd --- /dev/null +++ b/source/plugins/notable/queries/issues.graphql @@ -0,0 +1,15 @@ +query NotableIssues { + user(login: "$login") { + $type($after first: 100, orderBy: {field: CREATED_AT, direction: DESC}) { + totalCount + edges { + cursor + node { + repository { + nameWithOwner + } + } + } + } + } +} \ No newline at end of file diff --git a/source/templates/classic/partials/notable.ejs b/source/templates/classic/partials/notable.ejs index 403ed8d2..8e922fc0 100644 --- a/source/templates/classic/partials/notable.ejs +++ b/source/templates/classic/partials/notable.ejs @@ -16,7 +16,7 @@ <% } else { %> <% if (plugins.notable.contributions.length) { %>