MatchMaster/tools/coin-madness/check-types.cjs

29 lines
1.7 KiB
JavaScript

// Compare client diagnostics against HEAD without changing the working tree.
const ts = require('typescript');
const cp = require('node:child_process');
const path = require('node:path');
const root = path.resolve(__dirname, '../..');
const config = ts.readConfigFile(path.join(root, 'tsconfig.json'), ts.sys.readFile).config;
config.include = ['assets/**/*.ts', 'creator.d.ts']; config.exclude = ['node_modules', 'server'];
config.compilerOptions.noEmit = true;
const parsed = ts.parseJsonConfigFileContent(config, ts.sys, root);
const tracked = new Set(cp.execFileSync('git', ['ls-files'], { cwd: root, encoding: 'utf8' }).trim().split('\n'));
const relative = file => path.relative(root, file).replaceAll('\\', '/');
function check(baseline) {
const host = ts.createCompilerHost(parsed.options);
if (baseline) {
const read = host.readFile;
host.readFile = file => {
const key = relative(file);
if (key.endsWith('.ts') && tracked.has(key)) return cp.execFileSync('git', ['show', 'HEAD:' + key], { cwd: root, encoding: 'utf8', maxBuffer: 8 * 1024 * 1024 });
return read(file);
};
}
const program = ts.createProgram(parsed.fileNames.filter(f => !baseline || tracked.has(relative(f))), parsed.options, host);
return ts.getPreEmitDiagnostics(program).map(d => (d.file ? relative(d.file.fileName) : '') + ':' + d.code + ':' + ts.flattenDiagnosticMessageText(d.messageText, ' ')).sort();
}
const current = check(false), baseline = check(true);
const added = current.filter(d => !baseline.includes(d));
console.log(JSON.stringify({ current: current.length, baseline: baseline.length, added }, null, 2));
process.exitCode = added.length ? 1 : 0;