mirror of
https://github.com/pezkuwichain/pezkuwi-dev.git
synced 2026-10-22 11:46:18 +00:00
Add pezkuwi-dev-migrate-eslint10, and fix the Deno map's disable comment
Moving a repository to 0.86 renames rules (formatting rules to @stylistic, import/* to import-x/*, deprecation/deprecation to @typescript-eslint/no-deprecated, and typescript-eslint 8's removals). A disable comment that still names the old rule disables nothing: eslint reports it unused, --fix deletes it, and the rule it held back applies. Measured on pezkuwi-apps: the generated typesBundle.ts carries /* eslint-disable quotes */, and without a rename --fix rewrote all 188k lines of it. pezkuwi-dev-migrate-eslint10 renames the rules in eslint-disable / eslint-enable comments across the tracked files, before the first lint on 0.86, including such comments inside string literals, which is how generators emit them. Core renames come from eslint's own rule metadata (meta.deprecated.replacedBy); the rest are the mappings of #9. --check reports without writing and exits 1 when there is work. Run on this repository it found one: pezkuwi-dev-deno-map writes /* eslint-disable import/extensions */ into the Deno mod.ts it generates. The spec runs the tool in a scratch git repository: every kind of rename, descriptions kept, duplicates merged, a directive inside a string, current names and bare disables left alone, and --check. Its fixture is spelt so the tool, run here, cannot rewrite it.
This commit is contained in:
1 parent
568f735610
commit
f10614dd7d
4 files changed
+223
-1
No files matched your search
@@ -0,0 +1,87 @@
|
||||
// Copyright 2017-2026 @pezkuwi/dev authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
/// <reference types="@pezkuwi/dev-test/globals.d.ts" />
|
||||
|
||||
import { execFileSync } from 'node:child_process';
|
||||
import fs from 'node:fs';
|
||||
import os from 'node:os';
|
||||
import path from 'node:path';
|
||||
|
||||
const SCRIPT = path.join(process.cwd(), 'packages/dev/scripts/pezkuwi-dev-migrate-eslint10.mjs');
|
||||
|
||||
// Spelt so that the tool, run on this repository, does not rewrite its own
|
||||
// fixture: the source never contains the directive it is testing.
|
||||
const D = 'eslint-' + 'disable';
|
||||
|
||||
const BEFORE = `/* ${D} quotes */
|
||||
/* ${D} quote-props */
|
||||
// ${D}-next-line deprecation/deprecation
|
||||
// ${D}-next-line import/export -- types and values share the name
|
||||
// ${D}-next-line @typescript-eslint/no-empty-interface,no-use-before-define
|
||||
// ${D}-next-line indent, @typescript-eslint/indent
|
||||
// ${D}-next-line react/jsx-max-props-per-line
|
||||
const header = '/* ${D} quotes */';
|
||||
/* ${D} */
|
||||
// ${D}-next-line @typescript-eslint/no-explicit-any
|
||||
`;
|
||||
|
||||
const AFTER = `/* eslint-disable @stylistic/quotes */
|
||||
/* eslint-disable @stylistic/quote-props */
|
||||
// eslint-disable-next-line @typescript-eslint/no-deprecated
|
||||
// eslint-disable-next-line import-x/export -- types and values share the name
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-object-type, no-use-before-define
|
||||
// eslint-disable-next-line @stylistic/indent
|
||||
// eslint-disable-next-line @stylistic/jsx-max-props-per-line
|
||||
const header = '/* eslint-disable @stylistic/quotes */';
|
||||
/* eslint-disable */
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
`;
|
||||
|
||||
function inRepo (content: string, args: string[] = []): { out: string; code: number; file: string } {
|
||||
const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'migrate-eslint10-'));
|
||||
const file = path.join(dir, 'sample.ts');
|
||||
|
||||
try {
|
||||
fs.writeFileSync(file, content);
|
||||
execFileSync('git', ['init', '-q'], { cwd: dir });
|
||||
execFileSync('git', ['add', 'sample.ts'], { cwd: dir });
|
||||
|
||||
let code = 0;
|
||||
let out = '';
|
||||
|
||||
try {
|
||||
out = execFileSync(process.execPath, [SCRIPT, ...args], { cwd: dir, encoding: 'utf-8' });
|
||||
} catch (error) {
|
||||
code = (error as { status: number }).status;
|
||||
out = (error as { stdout: string }).stdout;
|
||||
}
|
||||
|
||||
return { code, file: fs.readFileSync(file, 'utf-8'), out };
|
||||
} finally {
|
||||
fs.rmSync(dir, { force: true, recursive: true });
|
||||
}
|
||||
}
|
||||
|
||||
describe('pezkuwi-dev-migrate-eslint10', (): void => {
|
||||
it('renames rules in disable comments, and in strings that emit them', (): void => {
|
||||
const { file, out } = inRepo(BEFORE);
|
||||
|
||||
expect(file).toEqual(AFTER);
|
||||
expect(out.includes('rewrote 8 directive(s) in 1 file(s)')).toEqual(true);
|
||||
});
|
||||
|
||||
it('leaves current rule names and bare disables alone', (): void => {
|
||||
const { file, out } = inRepo(AFTER);
|
||||
|
||||
expect(file).toEqual(AFTER);
|
||||
expect(out.includes('rewrote 0 directive(s) in 0 file(s)')).toEqual(true);
|
||||
});
|
||||
|
||||
it('--check reports and changes nothing, exiting 1 when there is work', (): void => {
|
||||
const { code, file } = inRepo(BEFORE, ['--check']);
|
||||
|
||||
expect(file).toEqual(BEFORE);
|
||||
expect(code).toEqual(1);
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user