The great refactor (#82)
This commit is contained in:
38
source/plugins/base/README.md
Normal file
38
source/plugins/base/README.md
Normal file
@@ -0,0 +1,38 @@
|
||||
### 🗃️ Base content
|
||||
|
||||
The *base* content is all metrics enabled by default.
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<img src="https://github.com/lowlighter/lowlighter/blob/master/metrics.classic.svg">
|
||||
<img width="900" height="1" alt="">
|
||||
</td>
|
||||
<td align="center">
|
||||
<img src="https://github.com/lowlighter/lowlighter/blob/master/metrics.organization.svg">
|
||||
<img width="900" height="1" alt="">
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
It contains the following sections:
|
||||
* `header`, which usually contains your username, your two-week commits calendars and a few additional data
|
||||
* `activity`, which contains your recent activity (commits, pull requests, issues, etc.)
|
||||
* `community`, which contains your community stats (following, sponsors, organizations, etc.)
|
||||
* `repositories`, which contains your repositories stats (license, forks, stars, etc.)
|
||||
* `metadata`, which contains informations about generated metrics
|
||||
|
||||
These are all enabled by default, but you can explicitely opt out from them.
|
||||
|
||||
#### ℹ️ Examples workflows
|
||||
|
||||
[➡️ Available options for this plugin](metadata.yml)
|
||||
|
||||
```yaml
|
||||
- uses: lowlighter/metrics@latest
|
||||
with:
|
||||
# ... other options
|
||||
base: header, repositories # Only display "header" and "repositories" sections
|
||||
repositories: 100 # Query only last 100 repositories
|
||||
repositories_forks: no # Don't include forks
|
||||
```
|
||||
89
source/plugins/base/index.mjs
Normal file
89
source/plugins/base/index.mjs
Normal file
@@ -0,0 +1,89 @@
|
||||
/**
|
||||
* Base plugin is a special plugin because of historical reasons.
|
||||
* It populates initial data object directly instead of returning a result like others plugins
|
||||
*/
|
||||
|
||||
//Setup
|
||||
export default async function ({login, graphql, data, q, queries, imports}, conf) {
|
||||
//Load inputs
|
||||
console.debug(`metrics/compute/${login}/base > started`)
|
||||
let {repositories, repositories_forks:forks} = imports.metadata.plugins.base.inputs({data, q, account:"bypass"}, {repositories:conf.settings.repositories ?? 100})
|
||||
|
||||
//Base parts (legacy handling for web instance)
|
||||
const defaulted = ("base" in q) ? !!q.base : true
|
||||
for (const part of conf.settings.plugins.base.parts)
|
||||
data.base[part] = `base.${part}` in q ? !!q[ `base.${part}`] : defaulted
|
||||
|
||||
//Iterate through account types
|
||||
for (const account of ["user", "organization"]) {
|
||||
try {
|
||||
//Query data from GitHub API
|
||||
console.debug(`metrics/compute/${login}/base > account ${account}`)
|
||||
const queried = await graphql(queries.base[account]({login, "calendar.from":new Date(Date.now()-14*24*60*60*1000).toISOString(), "calendar.to":(new Date()).toISOString(), forks:forks ? "" : ", isFork: false"}))
|
||||
Object.assign(data, {user:queried[account]})
|
||||
postprocess?.[account]({login, data})
|
||||
//Query repositories from GitHub API
|
||||
{
|
||||
//Iterate through repositories
|
||||
let cursor = null
|
||||
let pushed = 0
|
||||
do {
|
||||
console.debug(`metrics/compute/${login}/base > retrieving repositories after ${cursor}`)
|
||||
const {[account]:{repositories:{edges, nodes}}} = await graphql(queries.base.repositories({login, account, after:cursor ? `after: "${cursor}"` : "", repositories:Math.min(repositories, {user:100, organization:25}[account]), forks:forks ? "" : ", isFork: false"}))
|
||||
cursor = edges?.[edges?.length-1]?.cursor
|
||||
data.user.repositories.nodes.push(...nodes)
|
||||
pushed = nodes.length
|
||||
} while ((pushed)&&(cursor)&&(data.user.repositories.nodes.length < repositories))
|
||||
//Limit repositories
|
||||
console.debug(`metrics/compute/${login}/base > keeping only ${repositories} repositories`)
|
||||
data.user.repositories.nodes.splice(repositories)
|
||||
console.debug(`metrics/compute/${login}/base > loaded ${data.user.repositories.nodes.length} repositories`)
|
||||
}
|
||||
//Success
|
||||
console.debug(`metrics/compute/${login}/base > graphql query > account ${account} > success`)
|
||||
return {}
|
||||
} catch (error) {
|
||||
console.debug(`metrics/compute/${login}/base > account ${account} > failed : ${error}`)
|
||||
console.debug(`metrics/compute/${login}/base > checking next account`)
|
||||
}
|
||||
}
|
||||
//Not found
|
||||
console.debug(`metrics/compute/${login}/base > no more account type`)
|
||||
throw new Error("user not found")
|
||||
}
|
||||
|
||||
//Query post-processing
|
||||
const postprocess = {
|
||||
//User
|
||||
user({login, data}) {
|
||||
console.debug(`metrics/compute/${login}/base > applying postprocessing`)
|
||||
data.account = "user"
|
||||
Object.assign(data.user, {
|
||||
isVerified:false,
|
||||
})
|
||||
},
|
||||
//Organization
|
||||
organization({login, data}) {
|
||||
console.debug(`metrics/compute/${login}/base > applying postprocessing`)
|
||||
data.account = "organization",
|
||||
Object.assign(data.user, {
|
||||
isHireable:false,
|
||||
starredRepositories:{totalCount:0},
|
||||
watching:{totalCount:0},
|
||||
contributionsCollection:{
|
||||
totalRepositoriesWithContributedCommits:0,
|
||||
totalCommitContributions:0,
|
||||
restrictedContributionsCount:0,
|
||||
totalIssueContributions:0,
|
||||
totalPullRequestContributions:0,
|
||||
totalPullRequestReviewContributions:0,
|
||||
},
|
||||
calendar:{contributionCalendar:{weeks:[]}},
|
||||
repositoriesContributedTo:{totalCount:0},
|
||||
followers:{totalCount:0},
|
||||
following:{totalCount:0},
|
||||
issueComments:{totalCount:0},
|
||||
organizations:{totalCount:0},
|
||||
})
|
||||
}
|
||||
}
|
||||
34
source/plugins/base/metadata.yml
Normal file
34
source/plugins/base/metadata.yml
Normal file
@@ -0,0 +1,34 @@
|
||||
name: "🗃️ Base content"
|
||||
cost: 1 GraphQL request
|
||||
supports:
|
||||
- user
|
||||
- organization
|
||||
- repository
|
||||
inputs:
|
||||
|
||||
# Base content
|
||||
base:
|
||||
description: Metrics base content
|
||||
type: array
|
||||
format: comma-separated
|
||||
default: header, activity, community, repositories, metadata
|
||||
values:
|
||||
- header # name, commits calendar, ...
|
||||
- activity # commits, issues/pull requests opened, ...
|
||||
- community # following, stars, sponsors, ...
|
||||
- repositories # license, stars, forks, ...
|
||||
- metadata # svg generation metadata
|
||||
|
||||
# Number of repositories to use to computes metrics
|
||||
# Using more will result in more accurate metrics, but you may hit GitHub rate-limit more easily if you use a lot of plugins
|
||||
repositories:
|
||||
description: Number of repositories to use
|
||||
type: number
|
||||
default: 100
|
||||
min: 0
|
||||
|
||||
# Include forked repositories into metrics
|
||||
repositories_forks:
|
||||
description: Include forks in metrics
|
||||
type: boolean
|
||||
default: no
|
||||
31
source/plugins/base/queries/organization.graphql
Normal file
31
source/plugins/base/queries/organization.graphql
Normal file
@@ -0,0 +1,31 @@
|
||||
query BaseOrganization {
|
||||
organization(login: "$login") {
|
||||
databaseId
|
||||
name
|
||||
login
|
||||
createdAt
|
||||
avatarUrl
|
||||
websiteUrl
|
||||
isVerified
|
||||
twitterUsername
|
||||
repositories(last: 0) {
|
||||
totalCount
|
||||
totalDiskUsage
|
||||
nodes {
|
||||
name
|
||||
}
|
||||
}
|
||||
packages {
|
||||
totalCount
|
||||
}
|
||||
sponsorshipsAsSponsor {
|
||||
totalCount
|
||||
}
|
||||
sponsorshipsAsMaintainer {
|
||||
totalCount
|
||||
}
|
||||
membersWithRole {
|
||||
totalCount
|
||||
}
|
||||
}
|
||||
}
|
||||
50
source/plugins/base/queries/repositories.graphql
Normal file
50
source/plugins/base/queries/repositories.graphql
Normal file
@@ -0,0 +1,50 @@
|
||||
query BaseRepositories {
|
||||
$account(login: "$login") {
|
||||
repositories($after first: $repositories $forks, orderBy: {field: UPDATED_AT, direction: DESC}) {
|
||||
edges {
|
||||
cursor
|
||||
}
|
||||
nodes {
|
||||
name
|
||||
owner {
|
||||
login
|
||||
}
|
||||
isFork
|
||||
watchers {
|
||||
totalCount
|
||||
}
|
||||
stargazers {
|
||||
totalCount
|
||||
}
|
||||
languages(first: 8) {
|
||||
edges {
|
||||
size
|
||||
node {
|
||||
color
|
||||
name
|
||||
}
|
||||
}
|
||||
}
|
||||
issues_open: issues(states: OPEN) {
|
||||
totalCount
|
||||
}
|
||||
issues_closed: issues(states: CLOSED) {
|
||||
totalCount
|
||||
}
|
||||
pr_open: pullRequests(states: OPEN) {
|
||||
totalCount
|
||||
}
|
||||
pr_merged: pullRequests(states: MERGED) {
|
||||
totalCount
|
||||
}
|
||||
releases {
|
||||
totalCount
|
||||
}
|
||||
forkCount
|
||||
licenseInfo {
|
||||
spdxId
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
48
source/plugins/base/queries/repository.graphql
Normal file
48
source/plugins/base/queries/repository.graphql
Normal file
@@ -0,0 +1,48 @@
|
||||
query BaseRepository {
|
||||
$account(login: "$login") {
|
||||
repository(name: "$repo") {
|
||||
name
|
||||
owner {
|
||||
login
|
||||
}
|
||||
isFork
|
||||
createdAt
|
||||
diskUsage
|
||||
homepageUrl
|
||||
watchers {
|
||||
totalCount
|
||||
}
|
||||
stargazers {
|
||||
totalCount
|
||||
}
|
||||
languages(first: 8) {
|
||||
edges {
|
||||
size
|
||||
node {
|
||||
color
|
||||
name
|
||||
}
|
||||
}
|
||||
}
|
||||
issues_open: issues(states: OPEN) {
|
||||
totalCount
|
||||
}
|
||||
issues_closed: issues(states: CLOSED) {
|
||||
totalCount
|
||||
}
|
||||
pr_open: pullRequests(states: OPEN) {
|
||||
totalCount
|
||||
}
|
||||
pr_merged: pullRequests(states: MERGED) {
|
||||
totalCount
|
||||
}
|
||||
releases {
|
||||
totalCount
|
||||
}
|
||||
forkCount
|
||||
licenseInfo {
|
||||
spdxId
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
66
source/plugins/base/queries/user.graphql
Normal file
66
source/plugins/base/queries/user.graphql
Normal file
@@ -0,0 +1,66 @@
|
||||
query BaseUser {
|
||||
user(login: "$login") {
|
||||
databaseId
|
||||
name
|
||||
login
|
||||
createdAt
|
||||
avatarUrl
|
||||
websiteUrl
|
||||
isHireable
|
||||
twitterUsername
|
||||
repositories(last: 0 $forks) {
|
||||
totalCount
|
||||
totalDiskUsage
|
||||
nodes {
|
||||
name
|
||||
}
|
||||
}
|
||||
packages {
|
||||
totalCount
|
||||
}
|
||||
starredRepositories {
|
||||
totalCount
|
||||
}
|
||||
watching {
|
||||
totalCount
|
||||
}
|
||||
sponsorshipsAsSponsor {
|
||||
totalCount
|
||||
}
|
||||
sponsorshipsAsMaintainer {
|
||||
totalCount
|
||||
}
|
||||
contributionsCollection {
|
||||
totalRepositoriesWithContributedCommits
|
||||
totalCommitContributions
|
||||
restrictedContributionsCount
|
||||
totalIssueContributions
|
||||
totalPullRequestContributions
|
||||
totalPullRequestReviewContributions
|
||||
}
|
||||
calendar:contributionsCollection(from: "$calendar.from", to: "$calendar.to") {
|
||||
contributionCalendar {
|
||||
weeks {
|
||||
contributionDays {
|
||||
color
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
repositoriesContributedTo {
|
||||
totalCount
|
||||
}
|
||||
followers {
|
||||
totalCount
|
||||
}
|
||||
following {
|
||||
totalCount
|
||||
}
|
||||
issueComments {
|
||||
totalCount
|
||||
}
|
||||
organizations {
|
||||
totalCount
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user