import path from "node:path"; import { readRiskCoverageInput, writeRiskCoverageArtifactAtomic, } from "./lib/risk-coverage-files.ts"; import { buildProductionModuleInventory, evaluateRiskCoverage, parseRepositoryRiskCoveragePolicy, } from "./lib/risk-coverage.ts"; function argumentValue(name: string, fallback?: string): string | undefined { const index = process.argv.indexOf(name); return index >= 0 ? process.argv[index + 1] : fallback; } function requiredArgument(name: string, fallback: string): string { const value = argumentValue(name, fallback); if (!value) throw new TypeError(`${name} requires a path`); return value; } const repositoryRoot = path.resolve( requiredArgument("--repository-root", process.cwd()), ); const policyInput = await readRiskCoverageInput({ repositoryRoot, relativePath: requiredArgument( "--policy", "config/testing/risk-coverage.json", ), label: "policy", }); const summaryInput = await readRiskCoverageInput({ repositoryRoot, relativePath: requiredArgument( "--summary", "artifacts/tests/coverage/coverage-summary.json", ), label: "summary", }); const artifactPath = requiredArgument( "--artifact", "artifacts/quality/risk-coverage.json", ); const policy = parseRepositoryRiskCoveragePolicy( JSON.parse(policyInput.text) as unknown, ); const inventory = await buildProductionModuleInventory({ repositoryRoot, generatedPaths: policy.generatedPaths, }); const result = evaluateRiskCoverage({ repositoryRoot, inventory, policy, summary: JSON.parse(summaryInput.text) as unknown, }); await writeRiskCoverageArtifactAtomic({ repositoryRoot, relativePath: artifactPath, inputPaths: [policyInput.relativePath, summaryInput.relativePath], value: { schemaVersion: 2, policy: policyInput.relativePath, summary: summaryInput.relativePath, ...result, }, }); if (result.failures.length > 0) { process.stderr.write(`Risk coverage failed:\n- ${result.failures.join("\n- ")}\n`); process.exit(1); } process.stdout.write( `Risk coverage: PASS (${result.selectedTotal}/${result.repositoryTotal} production modules, ${result.results.length} thresholds)\n`, );