@riddance/env
Version:
Too much code slows you down, creates risks, increases maintainability burdens, confuses AI. So let's commit less of it.
95 lines • 16.9 kB
JavaScript
import { ESLint } from 'eslint';
import { readFile, rename, writeFile } from 'node:fs/promises';
import { basename, dirname, extname, join, relative } from 'node:path';
import { ensureUnlinked } from './fs.js';
export function makeCache(path) {
return new ESLint({ cwd: path, globInputPaths: false });
}
export async function lint(reporter, path, files, cache) {
try {
const results = await cache.lintFiles(files);
let ignoredWarnings = 0;
if (reporter) {
for (const result of results) {
for (const msg of result.messages) {
if (ignore(msg)) {
++ignoredWarnings;
continue;
}
reporter.error(msg.message, relative(path, result.filePath), msg.line, msg.column);
}
}
const deprecations = results
.flatMap(r => r.usedDeprecatedRules)
.map(r => r.replacedBy.length === 0
? `${r.ruleId} deprecated`
: `${r.ruleId} deprecated, replaced by ${r.replacedBy.join(',')}`);
if (deprecations.length !== 0) {
for (const message of new Set(deprecations)) {
reporter.error(message);
}
}
}
return !results.some(r => {
if (r.messages.some(ignore)) {
return !r.messages.every(ignore);
}
return r.fatalErrorCount + r.errorCount + r.warningCount;
});
}
catch (e) {
if (e.messageTemplate === 'all-matched-files-ignored') {
return true;
}
throw e;
}
}
function ignore(msg) {
return (msg.ruleId === null &&
msg.message.startsWith('File ignored because of a matching ignore pattern.'));
}
export async function fixLints(path, globPattern) {
const cache = new ESLint({ cwd: path, fix: true });
const results = await cache.lintFiles(globPattern);
const fixables = results.filter(r => r.output);
if (fixables.length === 0) {
return [];
}
await ESLint.outputFixes(results);
const [changed, mapping] = await kebabCaseFiles(path, results.map(r => relative(path, r.filePath)));
return [...changed, ...fixables.map(r => relative(path, r.filePath))].map(f => mapping.reduce((pv, [, camel, kebab]) => pv.replace(camel, kebab), f));
}
async function kebabCaseFiles(path, files) {
const ext = '.ts';
const sourceFiles = files.filter(f => extname(f) === ext);
const renamed = sourceFiles
.map(f => [dirname(f), basename(f, ext)])
.map(([dir, base]) => {
const kebab = base.replaceAll(/[A-Z]+(?![a-z])|[A-Z]/gu, ($, ofs) => (ofs ? '-' : '') + $.toLowerCase());
return kebab === base ? undefined : [dir, base, kebab];
})
.filter(r => !!r);
if (renamed.length === 0) {
return [[], renamed];
}
const changed = await Promise.all(sourceFiles.map(f => updateImports(path, f, renamed)));
await Promise.all([
...renamed.map(([p, camel, kebab]) => rename(join(path, p, camel + ext), join(path, p, kebab + ext))),
...renamed.flatMap(([p, camel]) => ['.d.ts', '.js'].map(e => ensureUnlinked(join(path, p, camel + e)))),
]);
return [changed.filter(c => c !== undefined), renamed];
}
async function updateImports(path, file, renamed) {
const fp = join(path, file);
const text = await readFile(fp, 'utf-8');
let updated = text;
for (const [, camel, kebab] of renamed) {
updated = updated.replaceAll(new RegExp(`import (.+) from '\\.(.*)/${camel}.js'`, 'gu'), (_, i, p) => `import ${i} from '.${p}/${kebab}.js'`);
}
if (updated !== text) {
await writeFile(fp, updated, 'utf-8');
return file;
}
return undefined;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGludGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsibGludGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxRQUFRLENBQUE7QUFDL0IsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFFLE1BQU0sa0JBQWtCLENBQUE7QUFDOUQsT0FBTyxFQUFFLFFBQVEsRUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsTUFBTSxXQUFXLENBQUE7QUFDdEUsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLFNBQVMsQ0FBQTtBQUd4QyxNQUFNLFVBQVUsU0FBUyxDQUFDLElBQVk7SUFDbEMsT0FBTyxJQUFJLE1BQU0sQ0FBQyxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsY0FBYyxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUE7QUFDM0QsQ0FBQztBQUVELE1BQU0sQ0FBQyxLQUFLLFVBQVUsSUFBSSxDQUN0QixRQUE4QixFQUM5QixJQUFZLEVBQ1osS0FBZSxFQUNmLEtBQWE7SUFFYixJQUFJLENBQUM7UUFDRCxNQUFNLE9BQU8sR0FBRyxNQUFNLEtBQUssQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUE7UUFDNUMsSUFBSSxlQUFlLEdBQUcsQ0FBQyxDQUFBO1FBQ3ZCLElBQUksUUFBUSxFQUFFLENBQUM7WUFDWCxLQUFLLE1BQU0sTUFBTSxJQUFJLE9BQU8sRUFBRSxDQUFDO2dCQUMzQixLQUFLLE1BQU0sR0FBRyxJQUFJLE1BQU0sQ0FBQyxRQUFRLEVBQUUsQ0FBQztvQkFDaEMsSUFBSSxNQUFNLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQzt3QkFDZCxFQUFFLGVBQWUsQ0FBQTt3QkFDakIsU0FBUTtvQkFDWixDQUFDO29CQUNELFFBQVEsQ0FBQyxLQUFLLENBQ1YsR0FBRyxDQUFDLE9BQU8sRUFDWCxRQUFRLENBQUMsSUFBSSxFQUFFLE1BQU0sQ0FB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QztJQUU5QyxNQUFNLEVBQUUsR0FBRyxJQUFJLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFBO0lBQzNCLE1BQU0sSUFBSSxHQUFHLE1BQU0sUUFBUSxDQUFDLEVBQUUsRUFBRSxPQUFPLENBQUMsQ0FBQTtJQUN4QyxJQUFJLE9BQU8sR0FBRyxJQUFJLENBQUE7SUFDbEIsS0FBSyxNQUFNLENBQUMsRUFBRSxLQUFLLEVBQUUsS0FBSyxDQUFDLElBQUksT0FBTyxFQUFFLENBQUM7UUFDckMsT0FBTyxHQUFHLE9BQU8sQ0FBQyxVQUFVLENBQ3hCLElBQUksTUFBTSxDQUFDLDZCQUE2QixLQUFLLE1BQU0sRUFBRSxJQUFJLENBQUMsRUFDMUQsQ0FBQyxDQUFDLEVBQUUsQ0FBUyxFQUFFLENBQVMsRUFBRSxFQUFFLENBQUMsVUFBVSxDQUFDLFdBQVcsQ0FBQyxJQUFJLEtBQUssTUFBTSxDQUN0RSxDQUFBO0lBQ0wsQ0FBQztJQUNELElBQUksT0FBTyxLQUFLLElBQUksRUFBRSxDQUFDO1FBQ25CLE1BQU0sU0FBUyxDQUFDLEVBQUUsRUFBRSxPQUFPLEVBQUUsT0FBTyxDQUFDLENBQUE7UUFDckMsT0FBTyxJQUFJLENBQUE7SUFDZixDQUFDO0lBQ0QsT0FBTyxTQUFTLENBQUE7QUFDcEIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEVTTGludCB9IGZyb20gJ2VzbGludCdcbmltcG9ydCB7IHJlYWRGaWxlLCByZW5hbWUsIHdyaXRlRmlsZSB9IGZyb20gJ25vZGU6ZnMvcHJvbWlzZXMnXG5pbXBvcnQgeyBiYXNlbmFtZSwgZGlybmFtZSwgZXh0bmFtZSwgam9pbiwgcmVsYXRpdmUgfSBmcm9tICdub2RlOnBhdGgnXG5pbXBvcnQgeyBlbnN1cmVVbmxpbmtlZCB9IGZyb20gJy4vZnMuanMnXG5pbXBvcnQgeyBSZXBvcnRlciB9IGZyb20gJy4vcmVwb3J0ZXIuanMnXG5cbmV4cG9ydCBmdW5jdGlvbiBtYWtlQ2FjaGUocGF0aDogc3RyaW5nKSB7XG4gICAgcmV0dXJuIG5ldyBFU0xpbnQoeyBjd2Q6IHBhdGgsIGdsb2JJbnB1dFBhdGhzOiBmYWxzZSB9KVxufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gbGludChcbiAgICByZXBvcnRlcjogUmVwb3J0ZXIgfCB1bmRlZmluZWQsXG4gICAgcGF0aDogc3RyaW5nLFxuICAgIGZpbGVzOiBzdHJpbmdbXSxcbiAgICBjYWNoZTogRVNMaW50LFxuKSB7XG4gICAgdHJ5IHtcbiAgICAgICAgY29uc3QgcmVzdWx0cyA9IGF3YWl0IGNhY2hlLmxpbnRGaWxlcyhmaWxlcylcbiAgICAgICAgbGV0IGlnbm9yZWRXYXJuaW5ncyA9IDBcbiAgICAgICAgaWYgKHJlcG9ydGVyKSB7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IHJlc3VsdCBvZiByZXN1bHRzKSB7XG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCBtc2cgb2YgcmVzdWx0Lm1lc3NhZ2VzKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpZ25vcmUobXNnKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgKytpZ25vcmVkV2FybmluZ3NcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmVwb3J0ZXIuZXJyb3IoXG4gICAgICAgICAgICAgICAgICAgICAgICBtc2cubWVzc2FnZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlbGF0aXZlKHBhdGgsIHJlc3VsdC5maWxlUGF0aCksXG4gICAgICAgICAgICAgICAgICAgICAgICBtc2cubGluZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIG1zZy5jb2x1bW4sXG4gICAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCBkZXByZWNhdGlvbnMgPSByZXN1bHRzXG4gICAgICAgICAgICAgICAgLmZsYXRNYXAociA9PiByLnVzZWREZXByZWNhdGVkUnVsZXMpXG4gICAgICAgICAgICAgICAgLm1hcChyID0+XG4gICAgICAgICAgICAgICAgICAgIHIucmVwbGFjZWRCeS5sZW5ndGggPT09IDBcbiAgICAgICAgICAgICAgICAgICAgICAgID8gYCR7ci5ydWxlSWR9IGRlcHJlY2F0ZWRgXG4gICAgICAgICAgICAgICAgICAgICAgICA6IGAke3IucnVsZUlkfSBkZXByZWNhdGVkLCByZXBsYWNlZCBieSAke3IucmVwbGFjZWRCeS5qb2luKCcsJyl9YCxcbiAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICBpZiAoZGVwcmVjYXRpb25zLmxlbmd0aCAhPT0gMCkge1xuICAgICAgICAgICAgICAgIGZvciAoY29uc3QgbWVzc2FnZSBvZiBuZXcgU2V0KGRlcHJlY2F0aW9ucykpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVwb3J0ZXIuZXJyb3IobWVzc2FnZSlcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuICFyZXN1bHRzLnNvbWUociA9PiB7XG4gICAgICAgICAgICBpZiAoci5tZXNzYWdlcy5zb21lKGlnbm9yZSkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gIXIubWVzc2FnZXMuZXZlcnkoaWdub3JlKVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHIuZmF0YWxFcnJvckNvdW50ICsgci5lcnJvckNvdW50ICsgci53YXJuaW5nQ291bnRcbiAgICAgICAgfSlcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGlmICgoZSBhcyB7IG1lc3NhZ2VUZW1wbGF0ZT86IHN0cmluZyB9KS5tZXNzYWdlVGVtcGxhdGUgPT09ICdhbGwtbWF0Y2hlZC1maWxlcy1pZ25vcmVkJykge1xuICAgICAgICAgICAgcmV0dXJuIHRydWVcbiAgICAgICAgfVxuICAgICAgICB0aHJvdyBlXG4gICAgfVxufVxuXG5mdW5jdGlvbiBpZ25vcmUobXNnOiBFU0xpbnQuTGludFJlc3VsdFsnbWVzc2FnZXMnXVswXSkge1xuICAgIHJldHVybiAoXG4gICAgICAgIG1zZy5ydWxlSWQgPT09IG51bGwgJiZcbiAgICAgICAgbXNnLm1lc3NhZ2Uuc3RhcnRzV2l0aCgnRmlsZSBpZ25vcmVkIGJlY2F1c2Ugb2YgYSBtYXRjaGluZyBpZ25vcmUgcGF0dGVybi4nKVxuICAgIClcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGZpeExpbnRzKHBhdGg6IHN0cmluZywgZ2xvYlBhdHRlcm46IHN0cmluZykge1xuICAgIGNvbnN0IGNhY2hlID0gbmV3IEVTTGludCh7IGN3ZDogcGF0aCwgZml4OiB0cnVlIH0pXG4gICAgY29uc3QgcmVzdWx0cyA9IGF3YWl0IGNhY2hlLmxpbnRGaWxlcyhnbG9iUGF0dGVybilcbiAgICBjb25zdCBmaXhhYmxlcyA9IHJlc3VsdHMuZmlsdGVyKHIgPT4gci5vdXRwdXQpXG4gICAgaWYgKGZpeGFibGVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICByZXR1cm4gW11cbiAgICB9XG4gICAgYXdhaXQgRVNMaW50Lm91dHB1dEZpeGVzKHJlc3VsdHMpXG4gICAgY29uc3QgW2NoYW5nZWQsIG1hcHBpbmddID0gYXdhaXQga2ViYWJDYXNlRmlsZXMoXG4gICAgICAgIHBhdGgsXG4gICAgICAgIHJlc3VsdHMubWFwKHIgPT4gcmVsYXRpdmUocGF0aCwgci5maWxlUGF0aCkpLFxuICAgIClcbiAgICByZXR1cm4gWy4uLmNoYW5nZWQsIC4uLmZpeGFibGVzLm1hcChyID0+IHJlbGF0aXZlKHBhdGgsIHIuZmlsZVBhdGgpKV0ubWFwKGYgPT5cbiAgICAgICAgbWFwcGluZy5yZWR1Y2UoKHB2LCBbLCBjYW1lbCwga2ViYWJdKSA9PiBwdi5yZXBsYWNlKGNhbWVsLCBrZWJhYiksIGYpLFxuICAgIClcbn1cblxuYXN5bmMgZnVuY3Rpb24ga2ViYWJDYXNlRmlsZXMocGF0aDogc3RyaW5nLCBmaWxlczogc3RyaW5nW10pIHtcbiAgICBjb25zdCBleHQgPSAnLnRzJ1xuICAgIGNvbnN0IHNvdXJjZUZpbGVzID0gZmlsZXMuZmlsdGVyKGYgPT4gZXh0bmFtZShmKSA9PT0gZXh0KVxuICAgIGNvbnN0IHJlbmFtZWQgPSBzb3VyY2VGaWxlc1xuICAgICAgICAubWFwKGYgPT4gW2Rpcm5hbWUoZiksIGJhc2VuYW1lKGYsIGV4dCldIGFzIGNvbnN0KVxuICAgICAgICAubWFwKChbZGlyLCBiYXNlXSkgPT4ge1xuICAgICAgICAgICAgY29uc3Qga2ViYWIgPSBiYXNlLnJlcGxhY2VBbGwoXG4gICAgICAgICAgICAgICAgL1tBLVpdKyg/IVthLXpdKXxbQS1aXS9ndSxcbiAgICAgICAgICAgICAgICAoJCwgb2ZzKSA9PiAob2ZzID8gJy0nIDogJycpICsgJC50b0xvd2VyQ2FzZSgpLFxuICAgICAgICAgICAgKVxuICAgICAgICAgICAgcmV0dXJuIGtlYmFiID09PSBiYXNlID8gdW5kZWZpbmVkIDogKFtkaXIsIGJhc2UsIGtlYmFiXSBhcyBjb25zdClcbiAgICAgICAgfSlcbiAgICAgICAgLmZpbHRlcihyID0+ICEhcilcbiAgICBpZiAocmVuYW1lZC5sZW5ndGggPT09IDApIHtcbiAgICAgICAgcmV0dXJuIFtbXSBhcyBzdHJpbmdbXSwgcmVuYW1lZF0gYXMgY29uc3RcbiAgICB9XG4gICAgY29uc3QgY2hhbmdlZCA9IGF3YWl0IFByb21pc2UuYWxsKHNvdXJjZUZpbGVzLm1hcChmID0+IHVwZGF0ZUltcG9ydHMocGF0aCwgZiwgcmVuYW1lZCkpKVxuICAgIGF3YWl0IFByb21pc2UuYWxsKFtcbiAgICAgICAgLi4ucmVuYW1lZC5tYXAoKFtwLCBjYW1lbCwga2ViYWJdKSA9PlxuICAgICAgICAgICAgcmVuYW1lKGpvaW4ocGF0aCwgcCwgY2FtZWwgKyBleHQpLCBqb2luKHBhdGgsIHAsIGtlYmFiICsgZXh0KSksXG4gICAgICAgICksXG4gICAgICAgIC4uLnJlbmFtZWQuZmxhdE1hcCgoW3AsIGNhbWVsXSkgPT5cbiAgICAgICAgICAgIFsnLmQudHMnLCAnLmpzJ10ubWFwKGUgPT4gZW5zdXJlVW5saW5rZWQoam9pbihwYXRoLCBwLCBjYW1lbCArIGUpKSksXG4gICAgICAgICksXG4gICAgXSlcbiAgICByZXR1cm4gW2NoYW5nZWQuZmlsdGVyKGMgPT4gYyAhPT0gdW5kZWZpbmVkKSwgcmVuYW1lZF0gYXMgY29uc3Rcbn1cblxuYXN5bmMgZnVuY3Rpb24gdXBkYXRlSW1wb3J0cyhcbiAgICBwYXRoOiBzdHJpbmcsXG4gICAgZmlsZTogc3RyaW5nLFxuICAgIHJlbmFtZWQ6IChyZWFkb25seSBbc3RyaW5nLCBzdHJpbmcsIHN0cmluZ10pW10sXG4pIHtcbiAgICBjb25zdCBmcCA9IGpvaW4ocGF0aCwgZmlsZSlcbiAgICBjb25zdCB0ZXh0ID0gYXdhaXQgcmVhZEZpbGUoZnAsICd1dGYtOCcpXG4gICAgbGV0IHVwZGF0ZWQgPSB0ZXh0XG4gICAgZm9yIChjb25zdCBbLCBjYW1lbCwga2ViYWJdIG9mIHJlbmFtZWQpIHtcbiAgICAgICAgdXBkYXRlZCA9IHVwZGF0ZWQucmVwbGFjZUFsbChcbiAgICAgICAgICAgIG5ldyBSZWdFeHAoYGltcG9ydCAoLispIGZyb20gJ1xcXFwuKC4qKS8ke2NhbWVsfS5qcydgLCAnZ3UnKSxcbiAgICAgICAgICAgIChfLCBpOiBzdHJpbmcsIHA6IHN0cmluZykgPT4gYGltcG9ydCAke2l9IGZyb20gJy4ke3B9LyR7a2ViYWJ9LmpzJ2AsXG4gICAgICAgIClcbiAgICB9XG4gICAgaWYgKHVwZGF0ZWQgIT09IHRleHQpIHtcbiAgICAgICAgYXdhaXQgd3JpdGVGaWxlKGZwLCB1cGRhdGVkLCAndXRmLTgnKVxuICAgICAgICByZXR1cm4gZmlsZVxuICAgIH1cbiAgICByZXR1cm4gdW5kZWZpbmVkXG59XG4iXX0=