From 134146f5859adc8b85a0b830b0f479f6cedf2252 Mon Sep 17 00:00:00 2001 From: Integer Limit <103940576+IntegerLimit@users.noreply.github.com> Date: Mon, 7 Oct 2024 13:57:42 +1100 Subject: [PATCH] Allow Specifying Co-Authors in Changelog (#1037) [SKIP] --- tools/tasks/changelog/changelogData.ts | 6 ++++ tools/tasks/changelog/definitions.ts | 2 ++ tools/tasks/changelog/parser.ts | 5 +++ tools/tasks/changelog/pusher.ts | 50 ++++++++++++++++---------- tools/tasks/changelog/specialParser.ts | 26 ++++++++++++++ tools/types/changelogTypes.ts | 5 +++ 6 files changed, 76 insertions(+), 18 deletions(-) diff --git a/tools/tasks/changelog/changelogData.ts b/tools/tasks/changelog/changelogData.ts index e1b2f94..2b88c5c 100644 --- a/tools/tasks/changelog/changelogData.ts +++ b/tools/tasks/changelog/changelogData.ts @@ -1,4 +1,5 @@ import { + AuthorInfo, Commit, FixUpInfo, InputReleaseType, @@ -30,6 +31,9 @@ export default class ChangelogData { // Map of project IDs to info text and/or details modInfoList: Map; + // Map of commit sha to specified coauthors for that commit + coAuthorList: Map; + /** * Constructor. Non-Async Inits are performed here. */ @@ -70,6 +74,7 @@ export default class ChangelogData { this.combineList = new Map(); this.modInfoList = new Map(); + this.coAuthorList = new Map(); // Init Tag Sets for Now, so we don't have to deal with nullable params this.tags = new Set(); @@ -116,6 +121,7 @@ export default class ChangelogData { this.combineList = new Map(); this.modInfoList = new Map(); + this.coAuthorList = new Map(); // Tags list is fine because the 'to' (Target) stays the same // Other Tags list is generated at setup diff --git a/tools/tasks/changelog/definitions.ts b/tools/tasks/changelog/definitions.ts index 33ed54d..0b668b7 100644 --- a/tools/tasks/changelog/definitions.ts +++ b/tools/tasks/changelog/definitions.ts @@ -41,6 +41,8 @@ export const ignoreKey = "[IGNORE]"; export const modInfoKey = "[MOD INFO]"; export const modInfoList = "infos"; export const priorityKey = "[PRIORITY]"; +export const coAuthorsKey = "[AUTHORS]"; +export const coAuthorsList = "authors"; /* Sub Category Keys */ // Mode Category Keys diff --git a/tools/tasks/changelog/parser.ts b/tools/tasks/changelog/parser.ts index 5f07e37..76eaeaf 100644 --- a/tools/tasks/changelog/parser.ts +++ b/tools/tasks/changelog/parser.ts @@ -8,6 +8,7 @@ import { } from "#types/changelogTypes.ts"; import { categories, + coAuthorsKey, combineKey, defaultIndentation, detailsKey, @@ -18,6 +19,7 @@ import { priorityKey, } from "./definitions.ts"; import { + parseCoAuthor, parseCombine, parseDetails, parseExpand, @@ -111,6 +113,9 @@ export async function parseCommitBody( if (commitBody.includes(modInfoKey)) await parseModInfo(commitBody, commitObject); + if (commitBody.includes(coAuthorsKey)) + await parseCoAuthor(commitBody, commitObject); + if (commitBody.includes(expandKey)) { await parseExpand(commitBody, commitObject, parser); return true; diff --git a/tools/tasks/changelog/pusher.ts b/tools/tasks/changelog/pusher.ts index d047c63..e80f3d5 100644 --- a/tools/tasks/changelog/pusher.ts +++ b/tools/tasks/changelog/pusher.ts @@ -287,43 +287,57 @@ export async function formatMessage( return `${indentation}* ${message} - ${author} (${formattedCommit})`; } - // Sort original array so newest commits appear at the end instead of start of commit string - sortCommitListReverse(commits); - const formattedCommits: string[] = []; const authors: string[] = []; - const retrievedAuthors: { commit: Commit; formatted: string }[] = + const retrievedAuthors: { commit: Commit; name: string; email: string }[] = await Promise.all( commits.map((commit) => - formatAuthor(commit).then((formatted) => { - return { commit, formatted }; + formatAuthor(commit).then((name) => { + return { commit, name, email: commit.author_email }; }), ), ); + const processedSHAs: Set = new Set(); + + sortCommitList(commits, (commit) => commit); + + // Co-Authors for Each Commit, Format Commits + commits.forEach((commit) => { + if (processedSHAs.has(commit.hash)) return; + formattedCommits.push( + `[\`${commit.hash.substring(0, 7)}\`](${repoLink}commit/${commit.hash})`, + ); + processedSHAs.add(commit.hash); + + const authors = data.coAuthorList.get(commit.hash); + if (!authors || authors.length === 0) return; + + retrievedAuthors.push( + ...authors.map((author) => { + return { commit, name: `@${author.name}`, email: author.email }; + }), + ); + }); + const processedAuthors: Set = new Set(); const processedEmails: Set = new Set(); - const processedSHAs: Set = new Set(); sortCommitList( retrievedAuthors, (author) => author.commit, - (a, b) => a.formatted.localeCompare(b.formatted), + (a, b) => a.name.localeCompare(b.name), ); retrievedAuthors.forEach((pAuthor) => { - if (processedSHAs.has(pAuthor.commit.hash)) return; + // Author if ( - !processedAuthors.has(pAuthor.formatted) && - !processedEmails.has(pAuthor.commit.author_email) + !processedAuthors.has(pAuthor.name) && + !processedEmails.has(pAuthor.email) ) { - authors.push(pAuthor.formatted); - processedAuthors.add(pAuthor.formatted); - processedEmails.add(pAuthor.commit.author_email); + authors.push(pAuthor.name); + processedAuthors.add(pAuthor.name); + processedEmails.add(pAuthor.email); } - formattedCommits.push( - `[\`${pAuthor.commit.hash.substring(0, 7)}\`](${repoLink}commit/${pAuthor.commit.hash})`, - ); - processedSHAs.add(pAuthor.commit.hash); }); // Delete all Formatted Commits after MaxIncludeCommits elements, replace with '...' diff --git a/tools/tasks/changelog/specialParser.ts b/tools/tasks/changelog/specialParser.ts index a43d989..9de2d39 100644 --- a/tools/tasks/changelog/specialParser.ts +++ b/tools/tasks/changelog/specialParser.ts @@ -1,4 +1,5 @@ import { + AuthorInfo, ChangelogMessage, Commit, ExpandedMessage, @@ -14,6 +15,8 @@ import { import dedent from "dedent-js"; import matter, { GrayMatterFile } from "gray-matter"; import { + coAuthorsKey, + coAuthorsList, combineKey, combineList, combineRoot, @@ -165,6 +168,29 @@ export async function parseIgnore( return undefined; } +/** + * Parses a commit with coauthor info. + */ +export async function parseCoAuthor( + commitBody: string, + commitObject: Commit, +): Promise { + if (!commitBody.includes(coAuthorsKey)) return; + await parseTOMLWithRootToList( + commitBody, + commitObject, + coAuthorsKey, + coAuthorsList, + (item) => !item.email || !item.name, + async (item) => { + const authors = data.coAuthorList.get(commitObject.hash) ?? []; + authors.push(item); + data.coAuthorList.set(commitObject.hash, authors); + }, + (item) => item as unknown as AuthorInfo, + ); +} + /** * Parses a commit with 'Fixup'. */ diff --git a/tools/types/changelogTypes.ts b/tools/types/changelogTypes.ts index fe35c83..ae236e6 100644 --- a/tools/types/changelogTypes.ts +++ b/tools/types/changelogTypes.ts @@ -301,6 +301,11 @@ export interface PriorityInfo { priority: number; } +export interface AuthorInfo { + name: string; + email: string; +} + export type FixUpMode = "REPLACE" | "ADDITION"; export type InputReleaseType =