Files
TREK/client/scripts/lib/format.mjs
T
Maurice 0344a86aec style(client): format the ratchet scripts with Prettier
The checker scripts were written without semicolons, against the
semi: true in .prettierrc, so every one of them failed the formatting
rule lint:format enforces on src/ and tests/. This is prettier --write
over the scripts this branch added or rewrote, nothing else.
2026-10-08 13:04:40 +02:00

84 lines
2.7 KiB
JavaScript

/*
* The comparison behind lint:format (scripts/format-lint.mjs): which files
* Prettier would rewrite, against the list of files that were unformatted
* when the check came in.
*/
import { join } from 'node:path';
import * as prettier from 'prettier';
import {
fileList,
listFiles,
lowerList,
RatchetError,
readBaseline,
readText,
toKey,
writeBaseline,
} from './ratchet.mjs';
export const DIRS = ['src', 'tests'];
export const accepts = (key) => /\.(?:tsx?|css)$/.test(key);
/**
* Whether Prettier leaves the file as it is, with the config that applies to
* it. The text is read with LF line ends, so a Windows checkout agrees with CI
* about endOfLine. A file Prettier cannot parse is not formatted.
*/
export async function isFormatted(path) {
const options = await prettier.resolveConfig(path);
if (!options) throw new RatchetError(`no Prettier config applies to ${path}`);
try {
return await prettier.check(readText(path), { ...options, filepath: path });
} catch {
return false;
}
}
/** The files under root that Prettier would rewrite, keyed by their path from root. */
export async function unformatted(root) {
const found = [];
for (const path of listFiles(root, DIRS, accepts)) if (!(await isFormatted(path))) found.push(toKey(root, path));
return found;
}
/**
* Runs the check against the list at baselinePath. A file outside the list
* must be formatted. A listed file that is formatted now, or gone, fails the
* check as well until --update takes it out: the list only shrinks, and a
* stale entry would let the next file at that path in unformatted. Returns
* the exit code.
*/
export async function check({
root,
baselinePath = join(root, 'scripts/format-baseline.json'),
update = false,
list = false,
log = console.log,
error = console.error,
}) {
const found = await unformatted(root);
let baseline = readBaseline(baselinePath, fileList);
if (update) {
baseline = lowerList(baseline, found);
writeBaseline(baselinePath, baseline);
}
const allowed = new Set(baseline);
const fresh = found.filter((key) => !allowed.has(key));
const now = new Set(found);
const stale = baseline.filter((key) => !now.has(key));
if (list) for (const key of found) log(`${allowed.has(key) ? 'listed' : 'new '} ${key}`);
for (const key of fresh) {
error(`FAIL ${key} is not formatted. Run: npx prettier --write ${key}`);
}
for (const key of stale) {
error(`FAIL ${key} is listed in scripts/format-baseline.json but is formatted now or gone.`);
}
if (stale.length) error('Run npm run lint:format -- --update to take the formatted files off the list.');
log(`format: ${found.length} unformatted file(s), ${baseline.length} listed in the baseline`);
return fresh.length || stale.length ? 1 : 0;
}