import { mkdir, readFile, rm, writeFile, } from "node:fs/promises"; import path from "node:path"; import { filesBelow, prepareRemovalFixture, pruneRemovalFixtureCiContract, pruneScriptOrchestration, regenerateRemovalFixtureWorkflow, requireRemovalFixtureEnvironment, runRemovalFixturePnpm, } from "./lib/removal-fixture.ts"; const fixtureRoot = path.resolve(".tmp/optional-recipe-removal"); const pnpmCli = requireRemovalFixtureEnvironment("npm_execpath"); function runPnpm(script: string): boolean { return runRemovalFixturePnpm(fixtureRoot, pnpmCli, script); } await prepareRemovalFixture(fixtureRoot); for (const rootOnlyTest of [ "tests/unit/ci-workflow-generation.test.ts", "tests/unit/__snapshots__/ci-workflow-generation.test.ts.snap", ]) { await rm(path.join(fixtureRoot, rootOnlyTest), { force: true }); } await rm(path.join(fixtureRoot, "recipes"), { recursive: true, force: true }); await rm(path.join(fixtureRoot, "tests/recipes"), { recursive: true, force: true, }); const removedCiScripts = new Set([ "check:types:recipes", "test:recipes", "check:optional-recipes", "check:optional-recipes:source", "check:optional-recipe-fixtures", "test:optional-recipe-removal", ]); const fixturePackagePath = path.join(fixtureRoot, "package.json"); const fixturePackage = JSON.parse(await readFile(fixturePackagePath, "utf8")) as { scripts: Record; }; pruneScriptOrchestration(fixturePackage.scripts, "check:types", removedCiScripts); pruneScriptOrchestration(fixturePackage.scripts, "test:all", removedCiScripts); await writeFile(fixturePackagePath, `${JSON.stringify(fixturePackage, null, 2)}\n`); await pruneRemovalFixtureCiContract({ root: fixtureRoot, removedScripts: removedCiScripts, removedEvidencePathFragments: [ "optional-recipes", "optional-recipe-fixtures", "optional-recipe-removal", ], }); await regenerateRemovalFixtureWorkflow(fixtureRoot); const checks: Array<[string, boolean]> = [ ["typecheck", runPnpm("check:types")], ["architecture", runPnpm("check:architecture")], ["test", runPnpm("test:all")], ["build", runPnpm("build")], ["ci-contract", runPnpm("check:ci")], ]; const residue: string[] = []; for (const file of await filesBelow(path.join(fixtureRoot, "dist"))) { if (!/\.(?:js|css|html|json)$/.test(file)) continue; const content = await readFile(file, "utf8"); if (content.includes("frontend-optional-recipe-must-not-reach-production")) { residue.push(path.relative(fixtureRoot, file)); } } checks.push(["bundle-residue", residue.length === 0]); const passed = checks.every(([, result]) => result); await mkdir("artifacts/tests", { recursive: true }); await writeFile( "artifacts/tests/optional-recipe-removal.xml", `\n` + `` + checks .map( ([name, result]) => `${result ? "" : `${residue.join(", ")}`}`, ) .join("") + `\n`, ); await rm(fixtureRoot, { recursive: true, force: true }); if (!passed) { process.stderr.write( `Optional recipe removal failed: ${checks .filter(([, result]) => !result) .map(([name]) => name) .join(", ")}\n`, ); process.exit(1); } process.stdout.write( `Optional recipe removal: PASS (${checks.length} base checks)\n`, );