feat: add multi-engine regex flavour support

This commit is contained in:
2026-07-27 11:43:51 +02:00
parent 7079cde15f
commit 7f3a91ad37
340 changed files with 643286 additions and 483 deletions

View File

@@ -1,28 +1,89 @@
import { lstat, readFile, readdir } from "node:fs/promises";
import path from "node:path";
import { fileURLToPath } from "node:url";
import { verifyCppPack } from "./cpp-engine-pack.mjs";
import { verifyDotNetPack } from "./dotnet-engine-pack.mjs";
import { verifyGoPack } from "./go-engine-pack.mjs";
import { verifyJavaPack } from "./java-engine-pack.mjs";
import { verifyPerlPack } from "./perl-engine-pack.mjs";
import { verifyPcre2Pack } from "./pcre2-engine-pack.mjs";
import { verifyPhpPack } from "./php-engine-pack.mjs";
import { verifyPythonPack } from "./python-engine-pack.mjs";
import { verifyRubyPack } from "./ruby-engine-pack.mjs";
import { verifyRustPack } from "./rust-engine-pack.mjs";
const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
const arguments_ = process.argv.slice(2);
const enginePacks = [
{
id: "cpp",
argument: "--cpp-pack",
verify: (pack) => verifyCppPack(pack, root),
},
{
id: "dotnet",
argument: "--dotnet-pack",
verify: (pack) => verifyDotNetPack(pack, root),
},
{
id: "go",
argument: "--go-pack",
verify: (pack) => verifyGoPack(pack, root),
},
{
id: "java",
argument: "--java-pack",
verify: (pack) => verifyJavaPack(pack, root),
},
{
id: "pcre2",
argument: "--pcre2-pack",
verify: (pack) => verifyPcre2Pack(pack, root),
},
{
id: "perl",
argument: "--perl-pack",
verify: (pack) => verifyPerlPack(pack, root),
},
{
id: "php",
argument: "--php-pack",
verify: (pack) => verifyPhpPack(pack, root),
},
{
id: "python",
argument: "--python-pack",
verify: (pack) => verifyPythonPack(pack, root),
},
{
id: "ruby",
argument: "--ruby-pack",
verify: (pack) => verifyRubyPack(pack, root),
},
{
id: "rust",
argument: "--rust-pack",
verify: (pack) => verifyRustPack(pack, root),
},
];
if (arguments_.length > 0) {
const verifiers = new Map([
["--java-pack", verifyJavaPack],
["--pcre2-pack", verifyPcre2Pack],
["--python-pack", verifyPythonPack],
]);
const verifier = verifiers.get(arguments_[0]);
if (arguments_.length !== 2 || !verifier) {
const selected = enginePacks.find(
({ argument }) => argument === arguments_[0],
);
if (arguments_.length !== 2 || !selected) {
throw new Error(
"Usage: node scripts/verify-engine-assets.mjs [--java-pack|--pcre2-pack|--python-pack PATH]",
`Usage: node scripts/verify-engine-assets.mjs [${enginePacks
.map(({ argument }) => argument)
.join("|")} PATH]`,
);
}
const pack = path.resolve(root, arguments_[1]);
const metadata = await verifier(pack, root);
console.log(`Verified staged ${metadata.engineVersion} engine pack.`);
const metadata = await selected.verify(pack);
console.log(
`Verified staged ${metadata.engineVersion ?? metadata.semanticIdentity} ${selected.id} engine pack.`,
);
process.exit(0);
}
@@ -36,35 +97,58 @@ const entries = (await readdir(engineDirectory, { withFileTypes: true })).sort(
(left, right) =>
left.name < right.name ? -1 : left.name > right.name ? 1 : 0,
);
const expectedEntries = [
{ name: "README.md", directory: false },
...enginePacks.map(({ id }) => ({ name: id, directory: true })),
].sort((left, right) =>
left.name < right.name ? -1 : left.name > right.name ? 1 : 0,
);
if (
entries.length !== 4 ||
!entries[0]?.isFile() ||
entries[0].name !== "README.md" ||
!entries[1]?.isDirectory() ||
entries[1].name !== "java" ||
!entries[2]?.isDirectory() ||
entries[2].name !== "pcre2" ||
!entries[3]?.isDirectory() ||
entries[3].name !== "python"
entries.length !== expectedEntries.length ||
entries.some((entry, index) => {
const expected = expectedEntries[index];
return (
!expected ||
entry.name !== expected.name ||
(expected.directory ? !entry.isDirectory() : !entry.isFile())
);
})
) {
throw new Error(
"The production build must contain only README.md and the declared Java, PCRE2 and Python packs.",
`The production build must contain only README.md and the declared engine packs: ${enginePacks
.map(({ id }) => id)
.join(", ")}.`,
);
}
const notice = await readFile(path.join(engineDirectory, "README.md"), "utf8");
if (
!notice.includes("native `RegExp`") ||
!notice.includes("PCRE2 10.47") ||
!notice.includes("Pyodide 314.0.3") ||
!notice.includes("TeaVM 0.15.0")
) {
throw new Error("The engine asset notice does not describe this release.");
for (const identity of [
"native `RegExp`",
"PCRE2 10.47",
"PHP 8.5.8",
"Perl 5.28.1",
"Pyodide 314.0.3",
"CRuby 4.0.0",
"TeaVM 0.15.0",
"Emscripten 6.0.4",
"Go 1.26.5",
"Rust `regex` crate 1.13.1",
".NET 10.0.10",
"Scala",
]) {
if (!notice.includes(identity)) {
throw new Error(
`The engine asset notice does not describe ${identity} in this release.`,
);
}
}
for (const engine of enginePacks) {
await engine.verify(path.join(engineDirectory, engine.id));
}
await verifyPcre2Pack(path.join(engineDirectory, "pcre2"), root);
await verifyPythonPack(path.join(engineDirectory, "python"), root);
await verifyJavaPack(path.join(engineDirectory, "java"), root);
console.log(
"Verified native ECMAScript and bundled PCRE2, CPython/Pyodide and TeaVM Java engine assets.",
`Verified native ECMAScript plus ${enginePacks
.map(({ id }) => id)
.join(", ")} checked-in engine packs.`,
);