mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-07-26 09:52:11 +03:00
Collapse duplicate CI spend while keeping each gate's existence reason: - quality.yml: TIA __RUN_ALL__ defers full unit to fast-unit 4-shard (#6781); path filters via classify-pr-changes; docs-gates split; draft skip - ci.yml: wire docs/i18n/code path filters; ESLint JSON artifact for quality-gate; drop advisory typecheck:noimplicit; float actions/cache@v6 - TIA parity: memory/usage/combo/serial; **/*.test.mjs any depth; electron/bin no longer force unit __RUN_ALL__ - check:complexity-ratchets: one ESLint walk, ruleId-isolated baselines + cache - check:api-docs-refs + lib/apiRoutes: shared API route inventory - husky pre-push: intentionally light (gates live in pre-commit); CLAUDE.md + QUALITY_GATES.md docs synced - collect-metrics / lint:json: path.resolve cache path; Windows-safe eslint bin - env-doc allowlist for ESLINT_RESULTS_JSON / COMPLEXITY_ESLINT_REPORT - release-green --full-ci expects check:api-docs-refs (not docs-symbols alone) Tests: select-impacted, classify-pr-changes, api-routes lib, complexity-rule-count, validate-release-green. Reconciled after #6781 (fast-unit 2→4 shards) per maintainer request on #6716. Co-authored-by: Diego Rodrigues de Sa e Souza <8016841+diegosouzapw@users.noreply.github.com>
106 lines
3.7 KiB
JavaScript
106 lines
3.7 KiB
JavaScript
#!/usr/bin/env node
|
|
/**
|
|
* One ESLint walk → both complexity ratchets.
|
|
*
|
|
* Existence reasons (unchanged):
|
|
* - cyclomatic + max-lines vs complexity-baseline.json
|
|
* - cognitive-complexity vs quality-baseline metrics.cognitiveComplexity
|
|
*
|
|
* CI should call this instead of sequential check:complexity + check:cognitive
|
|
* so PR→release / quality-gate pay for one tree walk, not two.
|
|
*/
|
|
import fs from "node:fs";
|
|
import path from "node:path";
|
|
import { pathToFileURL } from "node:url";
|
|
import { evaluateComplexity } from "./check-complexity.mjs";
|
|
import { evaluateCognitiveComplexity } from "./check-cognitive-complexity.mjs";
|
|
import {
|
|
countCognitiveViolations,
|
|
countComplexityViolations,
|
|
getComplexityEslintReport,
|
|
} from "./complexityEslintReport.mjs";
|
|
|
|
const ROOT = process.cwd();
|
|
const UPDATE = process.argv.includes("--update");
|
|
|
|
const COMPLEXITY_BASELINE = path.resolve(
|
|
process.argv.includes("--baseline")
|
|
? process.argv[process.argv.indexOf("--baseline") + 1]
|
|
: path.join(ROOT, "config/quality/complexity-baseline.json")
|
|
);
|
|
const QUALITY_BASELINE = path.join(ROOT, "config/quality/quality-baseline.json");
|
|
|
|
function main() {
|
|
if (!fs.existsSync(COMPLEXITY_BASELINE)) {
|
|
console.error(`[complexity-ratchets] FAIL — complexity-baseline.json ausente.`);
|
|
process.exit(2);
|
|
}
|
|
if (!fs.existsSync(QUALITY_BASELINE)) {
|
|
console.error(`[complexity-ratchets] FAIL — quality-baseline.json ausente.`);
|
|
process.exit(2);
|
|
}
|
|
|
|
const report = getComplexityEslintReport();
|
|
const complexityCount = countComplexityViolations(report);
|
|
const cognitiveCount = countCognitiveViolations(report);
|
|
|
|
// Machine-readable lines for collect-metrics / scripts
|
|
console.log(`complexity=${complexityCount}`);
|
|
console.log(`cognitiveComplexity=${cognitiveCount}`);
|
|
|
|
const complexityBaseline = JSON.parse(fs.readFileSync(COMPLEXITY_BASELINE, "utf8"));
|
|
const qualityBaseline = JSON.parse(fs.readFileSync(QUALITY_BASELINE, "utf8"));
|
|
const cognitiveMetric = qualityBaseline.metrics?.cognitiveComplexity;
|
|
if (!cognitiveMetric || typeof cognitiveMetric.value !== "number") {
|
|
console.error(
|
|
"[complexity-ratchets] FAIL — metrics.cognitiveComplexity ausente em quality-baseline.json."
|
|
);
|
|
process.exit(2);
|
|
}
|
|
|
|
const cyc = evaluateComplexity(complexityCount, complexityBaseline.count);
|
|
const cog = evaluateCognitiveComplexity(cognitiveCount, cognitiveMetric.value);
|
|
|
|
if (UPDATE && cyc.improved) {
|
|
console.log(
|
|
`[complexity] baseline ratcheado: ${complexityCount} (era ${complexityBaseline.count})`
|
|
);
|
|
complexityBaseline.count = complexityCount;
|
|
fs.writeFileSync(COMPLEXITY_BASELINE, JSON.stringify(complexityBaseline, null, 2) + "\n");
|
|
}
|
|
if (UPDATE && cog.improved) {
|
|
console.log(
|
|
`[cognitive-complexity] baseline ratcheado: ${cognitiveCount} (era ${cognitiveMetric.value})`
|
|
);
|
|
qualityBaseline.metrics.cognitiveComplexity.value = cognitiveCount;
|
|
fs.writeFileSync(QUALITY_BASELINE, JSON.stringify(qualityBaseline, null, 2) + "\n");
|
|
}
|
|
|
|
let failed = false;
|
|
if (cyc.regressed) {
|
|
console.error(
|
|
`[complexity] REGRESSÃO — ${complexityCount} violações > baseline ${complexityBaseline.count}`
|
|
);
|
|
failed = true;
|
|
} else {
|
|
console.log(
|
|
`[complexity] OK — ${complexityCount} violações (baseline ${complexityBaseline.count})`
|
|
);
|
|
}
|
|
|
|
if (cog.regressed) {
|
|
console.error(
|
|
`[cognitive-complexity] REGRESSÃO — ${cognitiveCount} violações > baseline ${cognitiveMetric.value}`
|
|
);
|
|
failed = true;
|
|
} else {
|
|
console.log(
|
|
`[cognitive-complexity] OK — ${cognitiveCount} violações (baseline ${cognitiveMetric.value})`
|
|
);
|
|
}
|
|
|
|
process.exit(failed ? 1 : 0);
|
|
}
|
|
|
|
if (import.meta.url === pathToFileURL(process.argv[1] || "").href) main();
|