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]
This commit is contained in:
Integer Limit 2023-10-29 21:05:47 +11:00 committed by GitHub
parent 542655bcfb
commit 21037b17f3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 120 additions and 15 deletions

View File

@ -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<ModChangesType, ModChangesAllocation>
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<string, IgnoreCheck> = {
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<string, IgnoreLogic> = {
and: andLogic,
or: orLogic,
nand: nandLogic,
nor: norLogic,
};
/* Default Ignore Logic */
export const defaultIgnoreLogic: IgnoreLogic = andLogic;

View File

@ -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<IgnoreInfo>(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<string>(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;
}

View File

@ -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<string, string>;
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;