diff --git a/source/plugins/languages/analyzer/recent.mjs b/source/plugins/languages/analyzer/recent.mjs index 927c91a7189..31e1331fb35 100644 --- a/source/plugins/languages/analyzer/recent.mjs +++ b/source/plugins/languages/analyzer/recent.mjs @@ -30,7 +30,7 @@ export class RecentAnalyzer extends Analyzer { async patches() { //Fetch commits from recent activity this.debug(`fetching patches from last ${this.days || ""} days up to ${this.load || "∞"} events`) - const commits = [], pages = Math.ceil((this.load || Infinity) / 100) + const pages = Math.ceil((this.load || Infinity) / 100) if (this.context.mode === "repository") { try { const {data: {default_branch: branch}} = await this.rest.repos.get(this.context) @@ -42,10 +42,11 @@ export class RecentAnalyzer extends Analyzer { this.debug(`failed to get default branch for ${this.context.owner}/${this.context.repo} (${error})`) } } + const events = [] try { for (let page = 1; page <= pages; page++) { this.debug(`fetching events page ${page}`) - commits.push( + events.push( ...(await (this.context.mode === "repository" ? this.rest.activity.listRepoEvents(this.context) : this.rest.activity.listEventsForAuthenticatedUser({username: this.login, per_page: 100, page}))).data .filter(({type, payload}) => (type === "PushEvent") && ((this.context.mode !== "repository") || ((this.context.mode === "repository") && (payload?.ref?.includes?.(`refs/heads/${this.context.branch}`))))) .filter(({actor}) => (this.account === "organization") || (this.context.mode === "repository") ? true : !filters.text(actor.login, [this.login], {debug: false})) @@ -57,8 +58,47 @@ export class RecentAnalyzer extends Analyzer { catch { this.debug("no more page to load") } + this.debug(`fetched ${events.length} events`) + + const wanted = new Map() + events.forEach(event => { + let key = `${event.repo.name}@${event.payload.ref}` + let item = wanted.get(key) ?? {commits: []} + item.repo = event.repo.name + item.ref = event.payload.ref + item.commits.push(event.payload.before) + item.commits.push(event.payload.head) + wanted.set(key, item) + }) + + const commits = [] + for (const item of wanted.values()) { + try { + for (let page = 1; page <= pages; page++) { + this.debug(`fetching commits page ${page}`) + this.debug(`https://api.github.com/repos/${item.repo}/commits?sha=${item.ref}&per_page=20&page=${page}`) + commits.push( + ...(await this.rest.request(`https://api.github.com/repos/${item.repo}/commits?sha=${item.ref}&per_page=20&page=${page}`)).data + .map(x => { + item.commits = item.commits.filter(c => c !== x.sha) + return x + }) + .filter(({committer}) => (this.account === "organization") || (this.context.mode === "repository") ? true : !filters.text(committer.login, [this.login], {debug: false})) + .filter(({commit}) => ((!this.days) || (new Date(commit.committer.date) > new Date(Date.now() - this.days * 24 * 60 * 60 * 1000)))), + ) + if (item.commits < 1) { + this.debug("found expected commits") + break + } + } + } + catch { + this.debug("no more page to load") + } + } + this.debug(`fetched ${commits.length} commits`) - this.results.latest = Math.round((new Date().getTime() - new Date(commits.slice(-1).shift()?.created_at).getTime()) / (1000 * 60 * 60 * 24)) + this.results.latest = Math.round((new Date().getTime() - new Date(events.slice(-1).shift()?.created_at).getTime()) / (1000 * 60 * 60 * 24)) this.results.commits = commits.length //Retrieve edited files and filter edited lines (those starting with +/-) from patches @@ -66,7 +106,6 @@ export class RecentAnalyzer extends Analyzer { const patches = [ ...await Promise.allSettled( commits - .flatMap(({payload}) => payload.commits) .filter(({committer}) => filters.text(committer?.email, this.authoring, {debug: false})) .map(commit => commit.url) .map(async commit => (await this.rest.request(commit)).data), @@ -75,9 +114,9 @@ export class RecentAnalyzer extends Analyzer { .filter(({status}) => status === "fulfilled") .map(({value}) => value) .filter(({parents}) => parents.length <= 1) - .map(({sha, commit: {message, committer}, verification, files}) => ({ + .map(({sha, commit: {message, author}, verification, files}) => ({ sha, - name: `${message} (authored by ${committer.name} on ${committer.date})`, + name: `${message} (authored by ${author.name} on ${author.date})`, verified: verification?.verified ?? null, editions: files.map(({filename, patch = ""}) => { const edition = {