111 lines
2.5 KiB
JavaScript
111 lines
2.5 KiB
JavaScript
import { mkdir, readdir, writeFile } from "node:fs/promises";
|
|
import { spawnSync } from "node:child_process";
|
|
|
|
await mkdir("artifacts/quality", { recursive: true });
|
|
|
|
const pnpmCli = /** @type {string} */ (process.env.npm_execpath);
|
|
|
|
if (!pnpmCli) {
|
|
throw new Error("check:architecture must run through the pnpm script");
|
|
}
|
|
|
|
/** @param {string[]} arguments_ */
|
|
function runPnpm(arguments_) {
|
|
return spawnSync(process.execPath, [pnpmCli, ...arguments_], {
|
|
encoding: "utf8",
|
|
});
|
|
}
|
|
|
|
const production = runPnpm(
|
|
[
|
|
"exec",
|
|
"depcruise",
|
|
"src",
|
|
"--config",
|
|
".dependency-cruiser.cjs",
|
|
"--output-type",
|
|
"json",
|
|
],
|
|
);
|
|
|
|
await writeFile(
|
|
"artifacts/quality/dependency-report.json",
|
|
production.stdout || JSON.stringify({ summary: { errors: 1 } }),
|
|
);
|
|
|
|
if (production.status !== 0) {
|
|
process.stderr.write(
|
|
production.error?.message ?? production.stderr ?? production.stdout ?? "failed",
|
|
);
|
|
process.exit(production.status ?? 1);
|
|
}
|
|
|
|
const allowed = runPnpm(
|
|
[
|
|
"exec",
|
|
"eslint",
|
|
"tests/fixtures/architecture/allowed",
|
|
"--no-ignore",
|
|
"--max-warnings=0",
|
|
],
|
|
);
|
|
|
|
const forbidden = runPnpm(
|
|
[
|
|
"exec",
|
|
"eslint",
|
|
"tests/fixtures/architecture/forbidden",
|
|
"--no-ignore",
|
|
"--max-warnings=0",
|
|
],
|
|
);
|
|
|
|
/** @param {string} directory @returns {Promise<string[]>} */
|
|
async function fixtureFiles(directory) {
|
|
const entries = await readdir(directory, { withFileTypes: true });
|
|
const files = await Promise.all(
|
|
entries.map((entry) => {
|
|
const target = `${directory}/${entry.name}`;
|
|
return entry.isDirectory()
|
|
? fixtureFiles(target)
|
|
: /\.(?:js|jsx|mjs|ts|tsx|mts)$/.test(entry.name)
|
|
? [target]
|
|
: [];
|
|
}),
|
|
);
|
|
return files.flat();
|
|
}
|
|
|
|
const forbiddenResults = await Promise.all(
|
|
(await fixtureFiles("tests/fixtures/architecture/forbidden")).map((file) => ({
|
|
file,
|
|
result: runPnpm([
|
|
"exec",
|
|
"eslint",
|
|
file,
|
|
"--no-ignore",
|
|
"--max-warnings=0",
|
|
]),
|
|
})),
|
|
);
|
|
const acceptedForbidden = forbiddenResults.filter(
|
|
({ result }) => result.status === 0,
|
|
);
|
|
|
|
if (
|
|
allowed.status !== 0 ||
|
|
forbidden.status === 0 ||
|
|
acceptedForbidden.length > 0
|
|
) {
|
|
process.stderr.write(allowed.stderr || allowed.stdout);
|
|
process.stderr.write(forbidden.stderr || forbidden.stdout);
|
|
for (const { file } of acceptedForbidden) {
|
|
process.stderr.write(`Forbidden fixture was accepted: ${file}\n`);
|
|
}
|
|
process.exit(1);
|
|
}
|
|
|
|
process.stdout.write(
|
|
`Architecture fixtures: allowed PASS, ${forbiddenResults.length} forbidden rejected\n`,
|
|
);
|