Files
menav/scripts/format-check-changed.js
rbetree 48609b86de feat: 分类锚点&质量检查&依赖治理
- 分类生成唯一 slug,模板/子菜单/滚动/扩展定位统一使用 data-id
- lint 覆盖 src/scripts/test,CI 增量格式检查
- 清理冗余依赖,升级 esbuild,overrides 修复审计项
- 补充单测并更新修复清单
2026-01-04 20:39:42 +08:00

132 lines
4.0 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
const fs = require('node:fs');
const path = require('node:path');
const { execFileSync } = require('node:child_process');
function runGit(args, cwd) {
return execFileSync('git', args, { cwd, encoding: 'utf8' }).trim();
}
function tryReadGithubEvent(eventPath) {
if (!eventPath) return null;
try {
const raw = fs.readFileSync(eventPath, 'utf8');
return JSON.parse(raw);
} catch {
return null;
}
}
function isAllZerosSha(value) {
return typeof value === 'string' && /^0{40}$/.test(value);
}
function getDiffRangeFromGithubEvent(event) {
if (!event || typeof event !== 'object') return null;
if (event.pull_request && event.pull_request.base && event.pull_request.head) {
const base = event.pull_request.base.sha;
const head = event.pull_request.head.sha;
if (base && head) return { base, head };
}
if (event.before && (event.after || event.head_commit)) {
const base = event.before;
const head = event.after || (event.head_commit && event.head_commit.id);
if (base && head && !isAllZerosSha(base)) return { base, head };
}
return null;
}
function collectChangedFiles(repoRoot, range) {
if (!range) return [];
const output = runGit(
['diff', '--name-only', '--diff-filter=ACMR', `${range.base}..${range.head}`],
repoRoot
);
return output
? output
.split('\n')
.map((line) => line.trim())
.filter(Boolean)
: [];
}
function collectWorkingTreeChangedFiles(repoRoot) {
const files = new Set();
const unstaged = runGit(['diff', '--name-only', '--diff-filter=ACMR', 'HEAD'], repoRoot);
const staged = runGit(['diff', '--cached', '--name-only', '--diff-filter=ACMR'], repoRoot);
[unstaged, staged].forEach((block) => {
if (!block) return;
block
.split('\n')
.map((line) => line.trim())
.filter(Boolean)
.forEach((filePath) => files.add(filePath));
});
return Array.from(files).sort();
}
function shouldCheckFile(filePath) {
const normalized = filePath.split(path.sep).join('/');
if (normalized === 'package-lock.json') return false;
// 这两个文件历史上未统一为 Prettier 风格;避免为了启用检查产生巨量格式化 diff
if (normalized === 'src/generator.js' || normalized === 'src/script.js') return false;
// 与现有 npm scripts 的检查范围对齐:不检查 docs/ 与 templates/
const allowedRoots = ['src/', 'scripts/', 'test/', '.github/', 'config/'];
const isRootFile = !normalized.includes('/');
const hasAllowedRoot = allowedRoots.some((prefix) => normalized.startsWith(prefix));
const isAllowedPath =
hasAllowedRoot || (isRootFile && (normalized.endsWith('.md') || normalized.endsWith('.json')));
if (!isAllowedPath) return false;
const ext = path.extname(normalized).toLowerCase();
return ['.js', '.json', '.md', '.yml', '.yaml'].includes(ext);
}
function resolvePrettierBin(repoRoot) {
const base = path.join(repoRoot, 'node_modules', '.bin', 'prettier');
if (fs.existsSync(base)) return base;
if (fs.existsSync(`${base}.cmd`)) return `${base}.cmd`;
return null;
}
function main() {
const repoRoot = path.resolve(__dirname, '..');
const event = tryReadGithubEvent(process.env.GITHUB_EVENT_PATH);
const range = getDiffRangeFromGithubEvent(event);
const candidateFiles = range
? collectChangedFiles(repoRoot, range)
: collectWorkingTreeChangedFiles(repoRoot);
const filesToCheck = candidateFiles.filter(shouldCheckFile);
if (filesToCheck.length === 0) {
console.log('格式检查:未发现需要检查的文件,跳过。');
return;
}
const prettierBin = resolvePrettierBin(repoRoot);
if (!prettierBin) {
console.error('格式检查失败:未找到 prettier可先运行 npm ci / npm install。');
process.exitCode = 1;
return;
}
console.log(`格式检查:共 ${filesToCheck.length} 个文件`);
filesToCheck.forEach((filePath) => console.log(`- ${filePath}`));
execFileSync(prettierBin, ['--check', ...filesToCheck], { cwd: repoRoot, stdio: 'inherit' });
}
main();