feat(plugins/notables): advanced filters (#789)

This commit is contained in:
Simon Lecoq
2022-01-19 14:24:33 +01:00
committed by GitHub
parent a7079285f3
commit 3df178d997
3 changed files with 30 additions and 5 deletions

View File

@@ -309,15 +309,25 @@ export function ghfilter(text, object) {
console.debug(`metrics/svg/ghquery > checking ${text} against ${JSON.stringify(object)}`)
const result = text.split(/(?<!NOT) /).map(x => x.trim()).filter(x => x).map(criteria => {
const [key, filters] = criteria.split(":")
const value = object[/^NOT /.test(key) ? key.substring(3).trim() : key.trim()]
const value = object[/^NOT /.test(key) ? key.substring(3).trim() : /^-/.test(key) ? key.substring(1).trim() : key.trim()]
console.debug(`metrics/svg/ghquery > checking ${criteria} against ${value}`)
if (value === undefined) {
console.debug(`metrics/svg/ghquery > value for ${criteria} is undefined, considering it truthy`)
return true
}
return filters?.split(",").map(x => x.trim()).filter(x => x).map(filter => {
if (!Number.isFinite(Number(value))) {
if (/^NOT /.test(filter))
return value !== filter.substring(3).trim()
if (/^-/.test(key))
return value !== filter
return value === filter.trim()
}
switch (true) {
case /^true$/.test(filter):
return value === true
case /^false$/.test(filter):
return value === false
case /^>\d+$/.test(filter):
return value > Number(filter.substring(1))
case /^>=\d+$/.test(filter):

View File

@@ -7,7 +7,8 @@ export default async function({login, q, imports, rest, graphql, data, account,
return null
//Load inputs
let {filter, repositories, from, indepth} = imports.metadata.plugins.notable.inputs({data, account, q})
let {filter, skipped, repositories, from, indepth} = imports.metadata.plugins.notable.inputs({data, account, q})
skipped.push(...data.shared["repositories.skipped"])
//Iterate through contributed repositories
const commits = []
@@ -19,6 +20,7 @@ export default async function({login, q, imports, rest, graphql, data, account,
const {user:{repositoriesContributedTo:{edges}}} = await graphql(queries.notable.contributions({login, 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}))
@@ -79,7 +81,7 @@ export default async function({login, q, imports, rest, graphql, data, account,
if (aggregated.has(key)) {
const aggregate = aggregated.get(key)
aggregate.aggregated++
if (extras) {
if (indepth) {
const {history = 0, user:{commits = 0, percentage = 0, maintainer = false} = {}} = _extras
aggregate.history = aggregate.history ?? 0
aggregate.history += history
@@ -94,9 +96,11 @@ export default async function({login, q, imports, rest, graphql, data, account,
}
contributions = [...aggregated.values()]
if (extras) {
if (indepth) {
//Normalize contribution percentage
contributions.map(aggregate => aggregate.user ? aggregate.user.percentage /= aggregate.aggregated : null)
//Additional filtering (no user commits means that API wasn't able to answer back, considering it as matching by default)
contributions = contributions.filter(({handle, user}) => !user?.commits ? true : imports.ghfilter(filter, {handle, commits:contributions.history, "commits.user":user.commits, "commits.user%":user.percentage*100, maintainer:user.maintainer}))
//Sort contribution by maintainer first and then by contribution percentage
contributions = contributions.sort((a, b) => ((b.user?.percentage + b.user?.maintainer) || 0) - ((a.user?.percentage + a.user?.maintainer) || 0))
}

View File

@@ -22,9 +22,20 @@ inputs:
Based on [GitHub search syntax](https://docs.github.com/en/search-github/getting-started-with-searching-on-github/understanding-the-search-syntax).
Supported fields are `stars`, `forks` and `watchers`
If `plugin_notable_indepth` is enabled, `commits`, `commits.user`, `commits.user%` and `maintainer` fields are also supported.
Some repositories may not be able to reported advanced stats and in the case the default behaviour will be to bypass filtering
type: string
default: ""
example: stars:>500 forks:>100
example: stars:>500 forks:>100 maintainer:true commits.user%:>5
plugin_notable_skipped:
description: Skipped repositories
type: array
format: comma-separated
default: ""
example: my-repo-1, my-repo-2, owner/repo-3, ...
inherits: repositories_skipped
plugin_notable_from:
description: |