From 21037b17f3e1174d581a95ab4462025ac87f699d Mon Sep 17 00:00:00 2001 From: Integer Limit <103940576+IntegerLimit@users.noreply.github.com> Date: Sun, 29 Oct 2023 21:05:47 +1100 Subject: [PATCH] Add More Ignore Tag Options (#500) [COMBINE] commits = ["fbd1584e7baed4a3603e3c810066603185f1b230"] [COMBINE] [FIXUP] [[fixes]] sha = "8fc1c45080f3247f973308aa8824629b98b18a91" newTitle = "Fix Draconic Evolution Crash (#484)" newBody = """ [BUG] [IGNORE] checks = { compareNot = \"1.7-alpha-1\" } [IGNORE] """ [FIXUP] --- tools/tasks/changelog/definitions.ts | 39 ++++++++++++- tools/tasks/changelog/specialParser.ts | 77 ++++++++++++++++++++++---- tools/types/changelogTypes.ts | 19 ++++++- 3 files changed, 120 insertions(+), 15 deletions(-) diff --git a/tools/tasks/changelog/definitions.ts b/tools/tasks/changelog/definitions.ts index 527e382..1be4de4 100644 --- a/tools/tasks/changelog/definitions.ts +++ b/tools/tasks/changelog/definitions.ts @@ -1,4 +1,4 @@ -import { Category, Commit, Ignored, Parser, SubCategory } from "../../types/changelogTypes"; +import { Category, Commit, IgnoreCheck, Ignored, IgnoreLogic, Parser, SubCategory } from "../../types/changelogTypes"; import { modpackManifest } from "../../globals"; import { parseCommitBody } from "./parser"; import { parseFixUp } from "./specialParser"; @@ -218,3 +218,40 @@ export const modChangesAllocations: Record template: "{{ modName }}: *v{{ oldVersion }}*", }, }; + +// Ignore Allocations + +/* Ignore Checks */ +const beforeCheck: IgnoreCheck = (tag, data) => !data.tags.has(tag); +const afterCheck: IgnoreCheck = (tag, data) => data.tags.has(tag); +const compareIsCheck: IgnoreCheck = (tag, data) => data.since === tag; +const compareNotCheck: IgnoreCheck = (tag, data) => data.since !== tag; +const targetIsCheck: IgnoreCheck = (tag, data) => data.to === tag; +const targetNotCheck: IgnoreCheck = (tag, data) => data.to !== tag; + +/* Ignore Checks Map */ +export const ignoreChecks: Record = { + before: beforeCheck, + after: afterCheck, + compareIs: compareIsCheck, + compareNot: compareNotCheck, + targetIs: targetIsCheck, + targetNot: targetNotCheck, +}; + +/* Ignore Logic */ +const andLogic: IgnoreLogic = (checkResults) => checkResults.filter((result) => result === false).length === 0; +const orLogic: IgnoreLogic = (checkResults) => checkResults.filter((result) => result === true).length > 0; +const nandLogic: IgnoreLogic = (checkResults) => !andLogic(checkResults); +const norLogic: IgnoreLogic = (checkResults) => !orLogic(checkResults); + +/* Ignore Logic Map */ +export const ignoreLogics: Record = { + and: andLogic, + or: orLogic, + nand: nandLogic, + nor: norLogic, +}; + +/* Default Ignore Logic */ +export const defaultIgnoreLogic: IgnoreLogic = andLogic; diff --git a/tools/tasks/changelog/specialParser.ts b/tools/tasks/changelog/specialParser.ts index be474e6..7fccca8 100644 --- a/tools/tasks/changelog/specialParser.ts +++ b/tools/tasks/changelog/specialParser.ts @@ -5,6 +5,7 @@ import { FixUpInfo, Ignored, IgnoreInfo, + IgnoreLogic, Parser, } from "../../types/changelogTypes"; import dedent from "dedent-js"; @@ -13,13 +14,16 @@ import toml from "@ltd/j-toml"; import { combineKey, combineList, + defaultIgnoreLogic, detailsKey, detailsList, expandKey, expandList, fixUpKey, fixUpList, + ignoreChecks, ignoreKey, + ignoreLogics, indentationLevel, } from "./definitions"; import { findCategories, findSubCategory } from "./parser"; @@ -40,28 +44,77 @@ export async function parseIgnore(commitBody: string, commitObject: Commit): Pro if (!commitBody.includes(ignoreKey)) return undefined; const info = await parseTOML(commitBody, commitObject, ignoreKey); if (!info) return undefined; - if (!info.before && !info.after) { + + if (!info.checks) { console.error(dedent` Ignore Info in body: \`\`\` ${commitBody}\`\`\` - of commit object ${commitObject.hash} (${commitObject.message}) is missing both keys 'before' and 'after'! - At least one of these values must be set!`); - if (data.isTest) throw new Error("Failed Parsing Ignore Info. See Above."); + of commit object ${commitObject.hash} (${commitObject.message}) is missing check info (key 'checks').`); return undefined; } - let isBefore = undefined, - isAfter = undefined; + let infoKeys: string[]; + try { + infoKeys = Object.keys(info.checks); + } catch (err) { + console.error(dedent` + Could not get the keys in Ignore Info of body: + \`\`\` + ${commitBody}\`\`\` + of commit object ${commitObject.hash} (${commitObject.message})!`); + if (data.isTest) throw err; + return undefined; + } - if (info.before) isBefore = !data.tags.has(info.before); - if (info.after) isAfter = data.tags.has(info.after); + /* Find Checks */ + const ignoreKeys = new Set(Object.keys(ignoreChecks)); + const checkResults: boolean[] = []; + infoKeys.forEach((key) => { + if (ignoreKeys.has(key)) checkResults.push(ignoreChecks[key].call(this, info.checks[key], data)); + else { + console.error(dedent` + Ignore Check with key '${key}' in body: + \`\`\` + ${commitBody}\`\`\` + of commit object ${commitObject.hash} (${commitObject.message}) is not accepted! + Only accepts keys: ${Array.from(ignoreKeys) + .map((key) => `'${key}'`) + .join(", ")}.`); + if (data.isTest) throw new Error("Failed Parsing Ignore Check. See Above."); + } + }); + if (checkResults.length === 0) { + console.error(dedent` + No Ignore Checks found in body: + \`\`\` + ${commitBody}\`\`\` + of commit object ${commitObject.hash} (${commitObject.message})! + Only accepts keys: ${Array.from(ignoreKeys) + .map((key) => `'${key}'`) + .join(", ")}.`); + if (data.isTest) throw new Error("Failed Parsing Ignore Checks. See Above."); + return undefined; + } - // Return Ignores - if (isBefore === undefined || isAfter === undefined) { - if (isBefore || isAfter) return new Ignored(info.addCommitList); - } else if (isBefore && isAfter) return new Ignored(info.addCommitList); + /* Find Logic */ + let logic: IgnoreLogic; + if (info.logic === undefined) logic = defaultIgnoreLogic; + else if (Object.keys(ignoreLogics).includes(info.logic)) logic = ignoreLogics[info.logic]; + else { + console.error(dedent` + Ignore Logic '${info.logic}' in body: + \`\`\` + ${commitBody}\`\`\` + of commit object ${commitObject.hash} (${commitObject.message})! + Only accepts keys: ${Object.keys(ignoreLogics) + .map((key) => `'${key}'`) + .join(", ")}.`); + if (data.isTest) throw new Error("Failed Parsing Ignore Logic. See Above."); + logic = defaultIgnoreLogic; + } + if (logic.call(this, checkResults)) return new Ignored(info.addCommitList); return undefined; } diff --git a/tools/types/changelogTypes.ts b/tools/types/changelogTypes.ts index 3c241d9..feac347 100644 --- a/tools/types/changelogTypes.ts +++ b/tools/types/changelogTypes.ts @@ -1,3 +1,5 @@ +import ChangelogData from "../tasks/changelog/changelogData"; + export interface Commit { hash: string; date: string; @@ -205,11 +207,24 @@ export interface Parser { } export interface IgnoreInfo { - before?: string; - after?: string; + checks: Record; + logic?: string; addCommitList?: boolean; } +/** + * Check to determine whether to ignore. + * @return ignore True to Ignore (if check is true), False to continue + */ +export type IgnoreCheck = (tag: string, data: ChangelogData) => boolean; + +/** + * Ignore Logic + * @param checkResults The results of the checks. + * @return ignore True to ignore, false to continue + */ +export type IgnoreLogic = (checkResults: boolean[]) => boolean; + export class Ignored { private readonly addCommitList: boolean | undefined;