rules/eslint/no-hardcoded-exclusions.eslint.rule.ts
rules/eslint/no-hardcoded-exclusions.eslint.rule.ts is a file in GovLab Extension Host. 130 lines of code and 21 definitions.
import type { LocalRule, RuleContext, RuleListener } from "../../types/rule.types.ts";
import {
argumentAt,
calleeName,
isType,
literalString,
locOf,
nameOf,
nodeAt,
nodesAt,
recordAt,
stringIn,
} from "../../shared/selectors/syntax.selector.ts";
import type { AstNode } from "../../types/syntax.types.ts";
import { absolutePath } from "@ssot/paths";
import { defineCheck } from "@govlab/context/check";
import { listener } from "../../shared/factories/listener.factory.ts";
import { normalizePath } from "../../shared/resolvers/anchor.resolver.ts";
const EXCLUSION_NAME_PARTS = ["skip", "ignore", "prune", "exclude", "runtime_root", "runtimeroot"];
const SSOT_CALLEES = new Set([
"masterExcludeMarkers",
"masterExclude",
"withMasterExclude",
"relativePath",
"absolutePath",
]);
const INFRASTRUCTURE_HINTS = [
"node_modules",
"dist",
"build",
"coverage",
"target",
".git",
".cache",
".vite",
".registry",
".vscode",
".next",
".tmp",
];
const MASTER_LIST_OWNER = normalizePath(absolutePath("govlabHost.config"));
const isExemptFile = function isExemptFile(filename: string): boolean {
return normalizePath(filename) === MASTER_LIST_OWNER;
};
const namesAnExclusion = function namesAnExclusion(name: string): boolean {
const lowered = name.toLowerCase();
return EXCLUSION_NAME_PARTS.some((part) => lowered.includes(part));
};
const literalsIn = function literalsIn(element: AstNode): string[] {
const literal = literalString(element);
if (literal !== null) {
return [literal];
}
if (element.type !== "TemplateLiteral") {
return [];
}
return nodesAt(element, "quasis")
.map((quasi) => stringIn(recordAt(quasi, "value"), "cooked"))
.filter((cooked) => cooked.trim().length > 0);
};
const literalsOf = function literalsOf(node: AstNode | null): string[] {
return nodesAt(node, "elements").flatMap(literalsIn);
};
const holdsSsotCall = function holdsSsotCall(node: AstNode | null): boolean {
return nodesAt(node, "elements").some((element) => {
const inner = element.type === "SpreadElement" ? nodeAt(element, "argument") : element;
return isType(inner, "CallExpression") && SSOT_CALLEES.has(calleeName(inner));
});
};
const WRAPPERS = new Set(["NewExpression", "CallExpression"]);
const arrayOf = function arrayOf(init: AstNode | null): AstNode | null {
if (init === null) {
return null;
}
if (init.type === "ArrayExpression") {
return init;
}
return WRAPPERS.has(init.type) ? argumentAt(init, 0) : null;
};
export default {
create(context: RuleContext): RuleListener {
if (isExemptFile(context.filename)) {
return {};
}
return listener({
variableDeclarator(view) {
const id = nodeAt(view, "id");
const name = isType(id, "Identifier") ? nameOf(id) : "";
if (name === "" || !namesAnExclusion(name)) {
return;
}
const array = arrayOf(nodeAt(view, "init"));
if (array === null) {
return;
}
const first = literalsOf(array).find((value) =>
INFRASTRUCTURE_HINTS.some((hint) => value.includes(hint)),
);
if (first === undefined) {
return;
}
const payload = { name, value: first };
if (holdsSsotCall(array)) {
context.report({ data: payload, loc: locOf(view), messageId: "partialExclusion" });
} else {
context.report({ data: payload, loc: locOf(view), messageId: "hardcodedExclusion" });
}
},
});
},
meta: {
docs: {
checks: defineCheck({
detects: ["architecture:hardcoded-configuration"],
enforces: ["architecture:single-source-of-truth"],
}),
description:
"An exclusion set is declared once, in the quality config, and reached through the master-exclude surface. A list spelled in source drifts from that one silently, and every tool then walks a slightly different tree — which is how a directory ends up skipped by one check and scanned by another. A genuinely tool-specific exclusion is declared under the tool's key in the config and requested by name, so the addition is still data rather than code.",
workspaceWide: true,
},
messages: {
hardcodedExclusion:
"`{{ name }}` spells its own exclusion set — `{{ value }}`. Take it from the master exclude surface, and declare any tool-specific addition under that tool's key in the quality config.",
partialExclusion:
"`{{ name }}` reads the master exclude surface and then appends `{{ value }}` in source. The appended entry is invisible to every other tool — declare it under this tool's key in the quality config instead.",
},
schema: [],
type: "problem",
},
} satisfies LocalRule;