iter(g104): 留痕校验回查提交真实性
This commit is contained in:
@@ -1017,6 +1017,18 @@ function cmdCommitLint(args) {
|
||||
console.log(`commit-lint OK (${type}${scope ? `(${scope})` : ''})`);
|
||||
}
|
||||
|
||||
/*** 提交主题索引:一次 git log 换「短哈希 → 主题」表,供留痕回查,避免逐行起进程 ***/
|
||||
function commitSubjects() {
|
||||
const r = spawnSync('git', ['log', '--all', '--pretty=%h|%s'], { cwd: ROOT, encoding: 'utf8' });
|
||||
if (r.status !== 0) return null; // 非 git 环境(打包分发等)跳过该维度,不让整条门禁失效
|
||||
const pairs = [];
|
||||
for (const line of String(r.stdout ?? '').split('\n')) {
|
||||
const cut = line.indexOf('|');
|
||||
if (cut > 0) pairs.push([line.slice(0, cut), line.slice(cut + 1)]);
|
||||
}
|
||||
return pairs;
|
||||
}
|
||||
|
||||
/*** 迭代留痕校验:.ua/iterations.log 每行 JSON 字段与格式必须符合 ITERATION.md 规范 ***/
|
||||
function cmdLintIterations() {
|
||||
const file = path.join(INDEX_DIR, 'iterations.log');
|
||||
@@ -1041,6 +1053,23 @@ function cmdLintIterations() {
|
||||
if (o.result === 'aborted' && commit && !/^[0-9a-f]{7,40}$/.test(commit)) issues.push(`${tag} aborted 条目 commit 须为空或哈希`);
|
||||
if (!String(o.summary ?? '').trim()) issues.push(`${tag} summary 不能为空`);
|
||||
});
|
||||
// —— 留痕 ↔ 提交双向核对:哈希必须真实存在,且主题要指向同一条目(防伪造 / 防抄错哈希)——
|
||||
const pairs = commitSubjects();
|
||||
if (pairs) {
|
||||
lines.forEach((line, i) => {
|
||||
const tag = `iterations.log:${i + 1}`;
|
||||
let o;
|
||||
try { o = JSON.parse(line); } catch { return; } // 行格式问题已在上轮报过
|
||||
const hash = String(o.commit ?? '');
|
||||
if (!hash) return; // aborted 允许留空
|
||||
const hit = pairs.find(([h]) => h.startsWith(hash));
|
||||
if (!hit) { issues.push(`${tag} commit ${hash} 不在仓库历史中`); return; }
|
||||
const legacy = `iter: ${o.id}`; // 早期提交用「iter: <id> 描述」,无 scope
|
||||
if (!hit[1].startsWith(`iter(${o.id})`) && !hit[1].startsWith(legacy)) {
|
||||
issues.push(`${tag} commit ${hash} 的主题「${hit[1]}」没有指向条目 ${o.id}`);
|
||||
}
|
||||
});
|
||||
}
|
||||
if (issues.length) {
|
||||
for (const it of issues) console.error('lint-iterations: ' + it);
|
||||
console.error(`${issues.length} violation(s)`);
|
||||
|
||||
Reference in New Issue
Block a user