Files
a-share-analysis/tools/governance/finish.mjs
T

81 lines
2.7 KiB
JavaScript
Raw Permalink 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.
import { execFileSync } from 'node:child_process';
import { existsSync, readFileSync, writeFileSync } from 'node:fs';
import path from 'node:path';
import {
getFeatureDirectory,
getRequiredFeatureFiles,
getUnpassedReviewFiles,
validateFeatureId,
} from './feature-record.mjs';
const [featureId, slug] = process.argv.slice(2);
const repositoryRoot = process.cwd();
if (!featureId || !slug || !validateFeatureId(featureId)) {
throw new Error('用法:npm run governance:finish -- <功能编号> <英文短名称>');
}
const featureDirectory = getFeatureDirectory(repositoryRoot, featureId, slug);
if (!existsSync(featureDirectory)) {
throw new Error(`功能档案不存在:${featureDirectory}`);
}
function run(command, args) {
return execFileSync(command, args, {
cwd: repositoryRoot,
encoding: 'utf8',
stdio: ['ignore', 'pipe', 'pipe'],
}).trim();
}
/**
* 完成门禁先验证仓库自身的治理测试,再刷新 GitNexus。业务项目接入后,
* 根目录 verify 脚本会继续串联前端和后端测试,而不需要改变本门禁入口。
*/
run('npm', ['run', 'test:governance']);
run('npx', ['gitnexus', 'analyze']);
const status = run('npx', ['gitnexus', 'status']);
const diffSummary = run('git', ['diff', '--stat']) || '(没有未提交差异)';
const worktreeSummary = run('git', ['status', '--short']) || '(工作区干净)';
const afterReport = path.join(featureDirectory, 'gitnexus', 'after.md');
if (!existsSync(afterReport) || readFileSync(afterReport, 'utf8').trim().length === 0) {
writeFileSync(
afterReport,
`# GitNexus 开发后基线\n\n` +
`## GitNexus 状态\n\n\`\`\`text\n${status}\n\`\`\`\n\n` +
`## Git 已跟踪变更摘要\n\n\`\`\`text\n${diffSummary}\n\`\`\`\n\n` +
`## Git 工作区摘要\n\n\`\`\`text\n${worktreeSummary}\n\`\`\`\n`,
'utf8',
);
}
const missingFiles = getRequiredFeatureFiles().filter((relativeFile) => {
const file = path.join(featureDirectory, relativeFile);
return !existsSync(file) || readFileSync(file, 'utf8').trim().length === 0;
});
if (missingFiles.length > 0) {
throw new Error(`完成门禁未通过,缺少或为空:\n- ${missingFiles.join('\n- ')}`);
}
const reviewReports = new Map(
['review/code-review.md', 'review/standards-review.md'].map((relativeFile) => [
relativeFile,
readFileSync(path.join(featureDirectory, relativeFile), 'utf8'),
]),
);
const unpassedReviews = getUnpassedReviewFiles(reviewReports);
if (unpassedReviews.length > 0) {
throw new Error(
`完成门禁未通过,Review 最终结论不是 passed\n- ${unpassedReviews.join('\n- ')}`,
);
}
process.stdout.write(
`基础门禁已通过。提交前仍须人工确认 GitNexus 影响报告、业务测试、视觉 QA 和回退说明。\n`,
);