增加提交前 TypeScript 自动格式化
接入 Husky 与 lint-staged,仅格式化暂存的 TS/TSX 文件 补充部分暂存和未暂存内容隔离回归测试 更新共享开发工作流中的提交前格式化规则
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
import assert from 'node:assert/strict';
|
||||
import { execFileSync, spawnSync } from 'node:child_process';
|
||||
import { mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
|
||||
import { tmpdir } from 'node:os';
|
||||
import { delimiter, dirname, join, resolve } from 'node:path';
|
||||
import { test } from 'node:test';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
|
||||
const repoRoot = resolve(dirname(fileURLToPath(import.meta.url)), '..');
|
||||
const packageJson = JSON.parse(
|
||||
readFileSync(join(repoRoot, 'package.json'), 'utf8'),
|
||||
);
|
||||
|
||||
test('pre-commit hook 仅格式化暂存的 TypeScript 快照', () => {
|
||||
assert.equal(packageJson.scripts.prepare, 'husky');
|
||||
assert.equal(packageJson.scripts['format:staged'], 'lint-staged');
|
||||
assert.deepEqual(packageJson['lint-staged'], {
|
||||
'*.{ts,tsx}': 'prettier --write',
|
||||
});
|
||||
assert.equal(
|
||||
readFileSync(join(repoRoot, '.husky', 'pre-commit'), 'utf8'),
|
||||
'npm run format:staged\n',
|
||||
);
|
||||
|
||||
const tempRepo = mkdtempSync(
|
||||
join(tmpdir(), 'genarrative-pre-commit-format-'),
|
||||
);
|
||||
try {
|
||||
git(tempRepo, 'init', '--quiet');
|
||||
git(tempRepo, 'config', 'user.email', 'pre-commit-test@example.invalid');
|
||||
git(tempRepo, 'config', 'user.name', 'Pre-commit Test');
|
||||
|
||||
const sourcePath = join(tempRepo, 'sample.ts');
|
||||
writeFileSync(sourcePath, 'const original = 1;\nconst keep = 2;\n');
|
||||
git(tempRepo, 'add', 'sample.ts');
|
||||
git(
|
||||
tempRepo,
|
||||
'-c',
|
||||
'commit.gpgsign=false',
|
||||
'commit',
|
||||
'--quiet',
|
||||
'-m',
|
||||
'baseline',
|
||||
);
|
||||
|
||||
writeFileSync(sourcePath, 'const original={value:1}\nconst keep = 2;\n');
|
||||
git(tempRepo, 'add', 'sample.ts');
|
||||
writeFileSync(
|
||||
sourcePath,
|
||||
'const original={value:1}\nconst keep={unstaged:true}\n',
|
||||
);
|
||||
|
||||
const lintStaged = spawnSync(
|
||||
process.execPath,
|
||||
[
|
||||
join(repoRoot, 'node_modules', 'lint-staged', 'bin', 'lint-staged.js'),
|
||||
'--config',
|
||||
'-',
|
||||
],
|
||||
{
|
||||
cwd: tempRepo,
|
||||
encoding: 'utf8',
|
||||
env: {
|
||||
...process.env,
|
||||
PATH: `${join(repoRoot, 'node_modules', '.bin')}${delimiter}${process.env.PATH ?? ''}`,
|
||||
},
|
||||
input: JSON.stringify(packageJson['lint-staged']),
|
||||
},
|
||||
);
|
||||
|
||||
assert.equal(
|
||||
lintStaged.status,
|
||||
0,
|
||||
`${lintStaged.stdout ?? ''}${lintStaged.stderr ?? ''}`,
|
||||
);
|
||||
assert.equal(
|
||||
git(tempRepo, 'show', ':sample.ts'),
|
||||
'const original = { value: 1 };\nconst keep = 2;\n',
|
||||
);
|
||||
assert.equal(
|
||||
readFileSync(sourcePath, 'utf8'),
|
||||
'const original = { value: 1 };\nconst keep={unstaged:true}\n',
|
||||
);
|
||||
} finally {
|
||||
rmSync(tempRepo, { force: true, recursive: true });
|
||||
}
|
||||
});
|
||||
|
||||
function git(cwd, ...args) {
|
||||
return execFileSync('git', args, { cwd, encoding: 'utf8' });
|
||||
}
|
||||
Reference in New Issue
Block a user