runtime/entrypoints/rule.entrypoint.ts
runtime/entrypoints/rule.entrypoint.ts is a file in GovLab Quality. 186 lines of code and 48 definitions.
import { RULE_DERIVATION_CLEAN, ruleDerivationFailed } from "#configuration/strings/validation.strings";
import { ROOT as WORKSPACE_ROOT, absolutePath } from "@ssot/paths";
import { existsSync, readFileSync, readdirSync, statSync } from "node:fs";
import { defineCheck } from "@govlab/context/check";
import { join } from "node:path";
import { pathToFileURL } from "node:url";
defineCheck({ detects: ["architecture:hardcoded-configuration"], enforces: ["architecture:single-source-of-truth"] });
interface Finding {
rule: string;
line: number;
value: string;
kind: "concern" | "folder" | "path";
tag: string;
}
const RULE_HOST = absolutePath("govlabHost.rules");
const TAXONOMY_CONFIG = absolutePath("govlabHost.taxonomy");
const GOVERNED_SRC = absolutePath("app.member");
const MIN_PATH_SEGMENTS = 2;
const posix = function posix(value: string): string {
return value.split("\\").join("/");
};
const collectDirs = function collectDirs(): Set<string> {
const dirs = new Set<string>();
const walk = function walk(absDir: string): void {
for (const name of readdirSync(absDir)) {
const p = join(absDir, name);
if (!statSync(p).isDirectory()) {
continue;
}
dirs.add(`${posix(p.slice(WORKSPACE_ROOT.length + 1))}/`);
walk(p);
}
};
if (existsSync(GOVERNED_SRC)) {
walk(GOVERNED_SRC);
}
return dirs;
};
const isRecord = function isRecord(value: unknown): value is Record<string, unknown> {
return typeof value === "object" && value !== null;
};
const stringField = function stringField(value: unknown, key: string): string {
return isRecord(value) && typeof value[key] === "string" ? value[key] : "";
};
const arrayField = function arrayField(value: unknown, key: string): unknown[] {
const declared = isRecord(value) ? value[key] : undefined;
return Array.isArray(declared) ? declared : [];
};
const tagsOf = function tagsOf(rows: unknown[], key: string): Set<string> {
return new Set(rows.map((row) => stringField(row, key)).filter((tag) => tag.length > 0));
};
const loadTaxonomy = async function loadTaxonomy(): Promise<{
concerns: Set<string>;
folders: Set<string>;
markers: Set<string>;
}> {
const loaded: unknown = await import(pathToFileURL(TAXONOMY_CONFIG).href);
const taxonomy = isRecord(loaded) ? loaded["taxonomy"] : undefined;
const rows = arrayField(taxonomy, "concerns");
const grammar = isRecord(taxonomy) ? taxonomy["grammar"] : undefined;
return {
concerns: tagsOf(rows, "tag"),
folders: tagsOf(rows, "folder"),
markers: new Set(
arrayField(grammar, "compoundMarkers").filter((marker): marker is string => typeof marker === "string"),
),
};
};
const DIRS = collectDirs();
const { concerns, folders, markers } = await loadTaxonomy();
const concernFolderSegment = function concernFolderSegment(value: string): string | null {
if (!value.includes("/")) {
return null;
}
for (const segment of posix(value).split("/")) {
if (segment !== "" && folders.has(segment)) {
return segment;
}
}
return null;
};
const structuralPath = function structuralPath(value: string): boolean {
if (!value.includes("/")) {
return false;
}
const norm = posix(value);
if (norm.split("/").filter((s) => s.length > 0).length < MIN_PATH_SEGMENTS) {
return false;
}
const trimmed = norm.startsWith("/") ? norm.slice(1) : norm;
const withSlash = trimmed.endsWith("/") ? trimmed : `${trimmed}/`;
for (const dir of DIRS) {
if (dir === withSlash || dir.endsWith(`/${withSlash}`) || dir.endsWith(withSlash)) {
return true;
}
}
return false;
};
const concernSuffix = function concernSuffix(value: string): string | null {
if (!value.endsWith(".ts") && !value.endsWith(".css")) {
return null;
}
const head = value.slice(0, value.lastIndexOf("."));
const tag = head.slice(head.lastIndexOf(".") + 1);
if (tag === "" || tag === head || markers.has(tag) || !concerns.has(tag)) {
return null;
}
return tag;
};
const QUOTE = '"';
const doubleQuoted = function doubleQuoted(line: string): string[] {
const out: string[] = [];
let at = line.indexOf(QUOTE);
while (at !== -1) {
const close = line.indexOf(QUOTE, at + 1);
if (close === -1) {
return out;
}
const body = line.slice(at + 1, close);
if (body.length > 0 && !body.includes("\\")) {
out.push(body);
}
at = line.indexOf(QUOTE, close + 1);
}
return out;
};
const isRuleFile = function isRuleFile(name: string, text: string): boolean {
if (!name.endsWith(".ts") || name.startsWith("_") || name.endsWith(".generated.ts")) {
return false;
}
return text.includes("meta:") && text.includes("create(");
};
const literalFinding = function literalFinding(value: string): { kind: Finding["kind"]; tag: string } | null {
if (value.includes(" ")) {
return null;
}
if (structuralPath(value)) {
return { kind: "path", tag: "" };
}
const tag = concernSuffix(value);
if (tag !== null) {
return { kind: "concern", tag };
}
const folder = concernFolderSegment(value);
return folder === null ? null : { kind: "folder", tag: folder };
};
const findingsInLine = function findingsInLine(rule: string, line: string, index: number): Finding[] {
if (line.trimStart().startsWith("import ") || line.includes('from "')) {
return [];
}
return doubleQuoted(line).flatMap((value): Finding[] => {
const found = literalFinding(value);
return found === null ? [] : [{ kind: found.kind, line: index + 1, rule, tag: found.tag, value }];
});
};
const ruleFiles = function ruleFiles(): { name: string; text: string }[] {
const files: { name: string; text: string }[] = [];
for (const name of readdirSync(RULE_HOST).sort((a, b) => a.localeCompare(b))) {
const abs = join(RULE_HOST, name);
const text = statSync(abs).isDirectory() ? "" : readFileSync(abs, "utf8");
if (isRuleFile(name, text)) {
files.push({ name, text });
}
}
return files;
};
const scan = function scan(): Finding[] {
return ruleFiles().flatMap(({ name, text }) =>
text.split("\n").flatMap((line, index) => findingsInLine(name, line, index)),
);
};
const findings = scan();
if (findings.length === 0) {
process.stdout.write(RULE_DERIVATION_CLEAN);
process.exit(0);
}
process.stderr.write(ruleDerivationFailed(findings.length));
for (const f of findings) {
const why = {
concern: `builds a filename from declared concern tag '${f.tag}' — key on parseFilename instead`,
folder: `embeds the declared concern folder '${f.tag}' — derive it with concernFolders('${f.tag}')`,
path: `names a real directory in the governed tree — walk for it`,
}[f.kind];
process.stderr.write(` ${f.rule}:${f.line} "${f.value}" ${why}\n`);
}
process.exit(1);