fix(addon): M111 r6 —— 失败文案按 rolled_back 分叉,补「回滚不完整」报告级用例

复审 r6 的两条(都在同两个文件里十来行):

1. 文案位自相矛盾
- 改前:`pipeline::failed()` **无条件**推「目标目录保持导入前的样子」,`record_rollback()`
  随后可能再推「有 N 项未能回滚(目标目录可能与导入前不同)」——同一份 warnings 自相矛盾;
  CLI `status_label` 也恒写「失败(已回滚)」。
- 改后:`failed()` 只落错误、**不宣称目标目录状态**;口径拆成两个具名入口——
  `abandoned()`(失败发生在碰目标目录之前,才说「目标目录未被写入」)与
  `record_rollback()`(完整 ⇒ `rolled_back=true` + 「恢复为导入前的样子」;不完整 ⇒
  `rolled_back=false` + 逐项列失败项)。CLI `status_label` 按 `rolled_back` 分叉成
  「失败(已回滚)」/「失败(回滚不完整)」;`keys.rs` 的状态文档与 pipeline 模块文档表
  同步改口径。

2. 新接线零测试(这是 fix-then-merge 的理由)
- 新增 `pipeline::tests` 三条报告级用例:
  `incomplete_rollback_never_claims_the_target_is_untouched`(`rolled_back=false` + warnings
  逐项列出 + **不含**任何「保持导入前的样子 / 未被写入 / 恢复为导入前」)、
  `complete_rollback_claims_consistency_exactly_once`、
  `pre_commit_failure_claims_untouched_only_via_abandoned`。

变异自证(本轮实测,均已还原):
- A:把 `record_rollback` 的分叉整体跳过(no-op)→ 2 条红(`失败项要逐条列出:[]`、
  `assertion failed: report.rolled_back`)。
- B:把 `failed()` 恢复成无条件推「保持导入前的样子」→ 2 条红,报错原文即自相矛盾现场:
  `["…目标目录保持导入前的样子…", "有 1 项未能回滚(目标目录可能与导入前不同)…"]`。
This commit is contained in:
AskaEth committed 2026-11-04 21:19:58 +08:00
1 parent 7f657d225c
commit 29f531db23
3 files changed
+151 -30

No files matched your search

+6 -4
View File
@@ -126,7 +126,7 @@ fn outcome(
}
human.push(format!(
"结果:{} 文件 新{} / 覆盖{} / 跳过{} / 保留{} 冲突 {} 缺文件 {}",
status_label(report.status),
status_label(report),
count_action(report, FileAction::Installed),
count_action(report, FileAction::Replaced),
count_action(report, FileAction::SkippedIdentical),
@@ -207,11 +207,13 @@ fn outcome(
Outcome::new(Report { data, human }).with_exit_code(report.status.exit_code())
}
fn status_label(status: ImportStatus) -> &'static str {
match status {
/// 状态的人读名。**失败要按回滚是否干净分叉**:不完整时不能说"已回滚"。
fn status_label(report: &ImportReport) -> &'static str {
match report.status {
ImportStatus::Success => "成功",
ImportStatus::Partial => "部分成功",
ImportStatus::Failed => "失败(已回滚)",
ImportStatus::Failed if report.rolled_back => "失败(已回滚)",
ImportStatus::Failed => "失败(回滚不完整)",
}
}