Compute processed files/commits from analyzers (#380)

This commit is contained in:
Simon Lecoq
2021-06-10 20:05:31 +02:00
committed by GitHub
parent cba14f5cdb
commit e5f91d56a8
3 changed files with 22 additions and 9 deletions

View File

@@ -5,7 +5,7 @@ export async function indepth({login, data, imports, repositories}, {skipped}) {
throw new Error("Feature requires github-linguist") throw new Error("Feature requires github-linguist")
//Compute repositories stats from fetched repositories //Compute repositories stats from fetched repositories
const results = {total:0, lines:{}, stats:{}} const results = {total:0, lines:{}, stats:{}, commits:0, files:0, missed:0}
for (const repository of repositories) { for (const repository of repositories) {
//Skip repository if asked //Skip repository if asked
if ((skipped.includes(repository.name.toLocaleLowerCase())) || (skipped.includes(`${repository.owner.login}/${repository.name}`.toLocaleLowerCase()))) { if ((skipped.includes(repository.name.toLocaleLowerCase())) || (skipped.includes(`${repository.owner.login}/${repository.name}`.toLocaleLowerCase()))) {
@@ -52,7 +52,7 @@ export async function recent({login, data, imports, rest, account}, {skipped = [
//Get user recent activity //Get user recent activity
console.debug(`metrics/compute/${login}/plugins > languages > querying api`) console.debug(`metrics/compute/${login}/plugins > languages > querying api`)
const commits = [], pages = Math.ceil(load/100), results = {total:0, lines:{}, stats:{}, commits:0, files:0, days} const commits = [], pages = Math.ceil(load/100), results = {total:0, lines:{}, stats:{}, commits:0, files:0, missed:0, days}
try { try {
for (let page = 1; page <= pages; page++) { for (let page = 1; page <= pages; page++) {
console.debug(`metrics/compute/${login}/plugins > languages > loading page ${page}`) console.debug(`metrics/compute/${login}/plugins > languages > loading page ${page}`)
@@ -68,7 +68,6 @@ export async function recent({login, data, imports, rest, account}, {skipped = [
console.debug(`metrics/compute/${login}/plugins > languages > no more page to load`) console.debug(`metrics/compute/${login}/plugins > languages > no more page to load`)
} }
console.debug(`metrics/compute/${login}/plugins > languages > ${commits.length} commits loaded`) console.debug(`metrics/compute/${login}/plugins > languages > ${commits.length} commits loaded`)
results.commits = commits.length
results.latest = Math.round((new Date().getTime() - new Date(commits.slice(-1).shift()?.created_at).getTime()) / (1000 * 60 * 60 * 24)) results.latest = Math.round((new Date().getTime() - new Date(commits.slice(-1).shift()?.created_at).getTime()) / (1000 * 60 * 60 * 24))
//Retrieve edited files and filter edited lines (those starting with +/-) from patches //Retrieve edited files and filter edited lines (those starting with +/-) from patches
@@ -91,7 +90,6 @@ export async function recent({login, data, imports, rest, account}, {skipped = [
//Temporary directory //Temporary directory
const path = imports.paths.join(imports.os.tmpdir(), `${data.user.databaseId}-${tempdir}`) const path = imports.paths.join(imports.os.tmpdir(), `${data.user.databaseId}-${tempdir}`)
console.debug(`metrics/compute/${login}/plugins > languages > creating temp dir ${path} with ${patches.length} files`) console.debug(`metrics/compute/${login}/plugins > languages > creating temp dir ${path} with ${patches.length} files`)
results.files = patches.length
//Process //Process
try { try {
@@ -125,6 +123,9 @@ export async function recent({login, data, imports, rest, account}, {skipped = [
//Analyze repository //Analyze repository
await analyze(arguments[0], {results, path:imports.paths.join(path, directory)}) await analyze(arguments[0], {results, path:imports.paths.join(path, directory)})
//Since we reproduce a "partial repository" with a single commit, use number of commits retrieved instead
results.commits = commits.length
} }
} }
catch { catch {
@@ -146,10 +147,11 @@ async function analyze({login, imports, data}, {results, path}) {
//Processing diff //Processing diff
const per_page = 1 const per_page = 1
const edited = new Set()
console.debug(`metrics/compute/${login}/plugins > languages > indepth > checking git log`) console.debug(`metrics/compute/${login}/plugins > languages > indepth > checking git log`)
for (let page = 0; ; page++) { for (let page = 0; ; page++) {
try { try {
const stdout = await imports.run(`git log ${data.shared["commits.authoring"].map(authoring => `--author="${authoring}"`).join(" ")} --regexp-ignore-case --format="" --patch --max-count=${per_page} --skip=${page*per_page}`, {cwd:path}, {log:false}) const stdout = await imports.run(`git log ${data.shared["commits.authoring"].map(authoring => `--author="${authoring}"`).join(" ")} --regexp-ignore-case --format=short --patch --max-count=${per_page} --skip=${page*per_page}`, {cwd:path}, {log:false})
let file = null, lang = null let file = null, lang = null
if (!stdout.trim().length) { if (!stdout.trim().length) {
console.debug(`metrics/compute/${login}/plugins > languages > indepth > no more commits`) console.debug(`metrics/compute/${login}/plugins > languages > indepth > no more commits`)
@@ -157,6 +159,11 @@ async function analyze({login, imports, data}, {results, path}) {
} }
console.debug(`metrics/compute/${login}/plugins > languages > indepth > processing commits ${page*per_page} from ${(page+1)*per_page}`) console.debug(`metrics/compute/${login}/plugins > languages > indepth > processing commits ${page*per_page} from ${(page+1)*per_page}`)
for (const line of stdout.split("\n").map(line => line.trim())) { for (const line of stdout.split("\n").map(line => line.trim())) {
//Commits counter
if (/^commit [0-9a-f]{40}$/.test(line)) {
results.commits++
continue
}
//Ignore empty lines or unneeded lines //Ignore empty lines or unneeded lines
if ((!/^[+]/.test(line))||(!line.length)) if ((!/^[+]/.test(line))||(!line.length))
continue continue
@@ -164,6 +171,7 @@ async function analyze({login, imports, data}, {results, path}) {
if (/^[+]{3}\sb[/](?<file>[\s\S]+)$/.test(line)) { if (/^[+]{3}\sb[/](?<file>[\s\S]+)$/.test(line)) {
file = line.match(/^[+]{3}\sb[/](?<file>[\s\S]+)$/)?.groups?.file ?? null file = line.match(/^[+]{3}\sb[/](?<file>[\s\S]+)$/)?.groups?.file ?? null
lang = files[file] ?? null lang = files[file] ?? null
edited.add(file)
continue continue
} }
//Ignore unkonwn languages //Ignore unkonwn languages
@@ -180,9 +188,10 @@ async function analyze({login, imports, data}, {results, path}) {
} }
catch { catch {
console.debug(`metrics/compute/${login}/plugins > languages > indepth > an error occured on page ${page}, skipping...`) console.debug(`metrics/compute/${login}/plugins > languages > indepth > an error occured on page ${page}, skipping...`)
results.missed += per_page
} }
} }
results.files += edited.size
} }
//import.meta.main //import.meta.main
@@ -201,7 +210,7 @@ if (/languages.analyzers.mjs$/.test(process.argv[1])) {
//Prepare call //Prepare call
const imports = await import("../../app/metrics/utils.mjs") const imports = await import("../../app/metrics/utils.mjs")
const results = {total:0, lines:{}, stats:{}} const results = {total:0, lines:{}, stats:{}, missed:0}
console.debug = log => /exited with code null/.test(log) ? console.error(log.replace(/^.*--max-count=(?<step>\d+) --skip=(?<start>\d+).*$/, (_, step, start) => `error: skipped commits ${start} from ${Number(start)+Number(step)}`)) : null console.debug = log => /exited with code null/.test(log) ? console.error(log.replace(/^.*--max-count=(?<step>\d+) --skip=(?<start>\d+).*$/, (_, step, start) => `error: skipped commits ${start} from ${Number(start)+Number(step)}`)) : null
//Analyze repository //Analyze repository

View File

@@ -38,7 +38,7 @@ export default async function({login, data, imports, q, rest, account}, {enabled
//Iterate through user's repositories and retrieve languages data //Iterate through user's repositories and retrieve languages data
console.debug(`metrics/compute/${login}/plugins > languages > processing ${data.user.repositories.nodes.length} repositories`) console.debug(`metrics/compute/${login}/plugins > languages > processing ${data.user.repositories.nodes.length} repositories`)
const languages = {unique, sections, details, colors:{}, total:0, stats:{}, "stats.recent":{}} const languages = {unique, sections, details, indepth, colors:{}, total:0, stats:{}, "stats.recent":{}}
for (const repository of data.user.repositories.nodes) { for (const repository of data.user.repositories.nodes) {
//Skip repository if asked //Skip repository if asked
if ((skipped.includes(repository.name.toLocaleLowerCase())) || (skipped.includes(`${repository.owner.login}/${repository.name}`.toLocaleLowerCase()))) { if ((skipped.includes(repository.name.toLocaleLowerCase())) || (skipped.includes(`${repository.owner.login}/${repository.name}`.toLocaleLowerCase()))) {
@@ -63,6 +63,7 @@ export default async function({login, data, imports, q, rest, account}, {enabled
if (indepth) { if (indepth) {
console.debug(`metrics/compute/${login}/plugins > languages > switching to indepth mode (this may take some time)`) console.debug(`metrics/compute/${login}/plugins > languages > switching to indepth mode (this may take some time)`)
Object.assign(languages, await indepth_analyzer({login, data, imports, repositories}, {skipped})) Object.assign(languages, await indepth_analyzer({login, data, imports, repositories}, {skipped}))
console.log(`metrics/compute/${login}/plugins > languages > indepth analysis missed ${languages.missed} commits`)
} }
//Compute languages stats //Compute languages stats
@@ -79,7 +80,6 @@ export default async function({login, data, imports, q, rest, account}, {enabled
} }
} }
console.log(aliases)
//Apply aliases //Apply aliases
for (const section of ["favorites", "recent"]) { for (const section of ["favorites", "recent"]) {
for (const language of languages[section]) { for (const language of languages[section]) {

View File

@@ -22,6 +22,10 @@
<small> <small>
estimation from <%= plugins.languages["stats.recent"]?.files %> edited file<%= s(plugins.languages["stats.recent"]?.files) %> from <%= plugins.languages["stats.recent"]?.commits %> commit<%= s(plugins.languages["stats.recent"]?.commits) %> over last <%= plugins.languages["stats.recent"]?.latest ?? plugins.languages["stats.recent"]?.days %> day<%= s(plugins.languages["stats.recent"]?.latest ?? plugins.languages["stats.recent"]?.days) %> estimation from <%= plugins.languages["stats.recent"]?.files %> edited file<%= s(plugins.languages["stats.recent"]?.files) %> from <%= plugins.languages["stats.recent"]?.commits %> commit<%= s(plugins.languages["stats.recent"]?.commits) %> over last <%= plugins.languages["stats.recent"]?.latest ?? plugins.languages["stats.recent"]?.days %> day<%= s(plugins.languages["stats.recent"]?.latest ?? plugins.languages["stats.recent"]?.days) %>
</small> </small>
<% } else if ((section === "most-used")&&(plugins.languages.indepth)) { %>
<small>
estimation from <%= plugins.languages.files %> edited file<%= s(plugins.languages.files) %> from <%= plugins.languages.commits %> commit<%= s(plugins.languages.commits) %>
</small>
<% } %> <% } %>
<svg class="bar" xmlns="http://www.w3.org/2000/svg" width="<%= width %>" height="8"> <svg class="bar" xmlns="http://www.w3.org/2000/svg" width="<%= width %>" height="8">
<mask id="languages-bar"> <mask id="languages-bar">