UNPKG

diffjam

Version:
100 lines (88 loc) 2.63 kB
import { equal } from "node:assert"; import { join } from "node:path"; import cluster from "node:cluster"; import { Config } from "./Config"; import { Match } from "./match"; import { Policy } from "./Policy"; import { readFile } from "fs"; import { FileMatcher } from "./FileMatcher"; export type Message = | { type: "match"; policyName: string; match: Match } | { type: "processedFile"; filePath: string }; export function processFile( filePath: string, cwd: string, config: Config, onMatch: (match: Match, policy: Policy) => void, onDone: (filePath: string) => void ) { readFile(join(cwd, filePath), { encoding: "utf8" }, (err, fileContents) => { if (err) { if (err.code === "ENOENT") { // File doesn't exist, so we'll just skip it. onDone(filePath); return; } throw err; } const file = new FileMatcher(filePath, fileContents); for (const policy of Object.values(config.policyMap)) { policy.processFile(file, onMatch); } onDone(filePath); }); } export function readyWorker( config: Config, cwd: string, onMatch: (match: Match, policy: Policy) => void, onDone: (filePath: string) => void ) { return { processFile(filePath: string) { processFile(filePath, cwd, config, onMatch, onDone); }, }; } export async function workerProcess() { equal( cluster.isPrimary || cluster.isMaster, false, "workerProcess() should only be called in a worker process" ); let confReady = false; const queued: string[] = []; equal(!!process.env.configFilePath, true, "configFilePath not set"); equal(!!process.env.cwd, true, "cwd not set"); const conf = Config.read(process.env.configFilePath!); const cwd = process.env.cwd!; // We may receive messages while still loading the config. // We'll queue them up and process them once the config is ready. process.on("message", (message: any) => { const { filePath } = message; if (!confReady) return queued.push(filePath); worker.processFile(filePath); }); // Errors in reading the config should be caught and logged by the parent process. let config: Config; try { config = await conf; } catch (err) { return; } confReady = true; const worker = readyWorker( config, cwd, (match: Match, policy: Policy) => { process.send!({ type: "match", policyName: policy.name, match }); }, (filePath: string) => { process.send!({ type: "processedFile", filePath }); } ); let filePath: string | undefined; while ((filePath = queued.shift())) { worker.processFile(filePath); } }