feat(addon): M111 整合包导入管线(CF / mrpack / MultiMC)+ ull pack import
接 M110 的 pack 模型与安全闸,做导入:三格式 → 实例目录,落 D10 §2 三条硬要求。 core(`addon::import`): - 三方合并:`merge::decide` 判据表(磁盘 × 基线 × 包内),base 侧落在 `<实例根>/.ULL/pack-baseline.json`;无基线时磁盘同名文件算用户已有内容 ⇒ 不覆盖。 冲突逐条进报告(user_modified / user_deleted / pre_existing + 可选处置)。 - 两阶段:先 overrides 再补远端;失败分级只有一条判据(是不是"某个文件搞不到"): 缺文件 ⇒ Partial;穿越/符号链接/限额/清单坏/摘要不符/IO ⇒ Failed 且整包回滚。 - 事务:`Staging` 临时目录 + `CommitGuard`(全新导入 rename 整目录、合并态 journal 逆序 回滚、Drop 即回滚),基线作为最后一个暂存文件同生共死。 - 三格式语义:mrpack `client-overrides` 胜 `overrides`、`server-overrides` 不解压; `.disabled`/`.old` 按路径后缀识别并原样保留;MultiMC `formatVersion != 1` 整份拒绝、 非加载器 component 逐项进报告;CF `classId` 认不出就不猜。 - 加载器只做翻译(`LoaderTarget`:kind + 原版 + 加载器版本 + 版本 id,含 CF NeoForge `1.20.1-47.1.106` 的 MC 前缀剥离),网络全部经注入的 `PackFetcher` (生产实现 `DownloadEngineFetcher` 只走 core::download,无第二个 reqwest client)。 - 报告:三态 + 逐项原因 + 稳定文案 key 表(`report::keys`,含 ALL 守门表)。 CLI(`ull pack import <file> [--target] [--name] [--overwrite] [--no-register]`): - 退出码三态 0 / 3 / 1(`Outcome::exit_code` + runner 透传,其它命令仍 0); - `--json` 恒有信封(`data.status` / `data.error.code` / `data.stages`),Failed 不抛栈。 测试:29 条 core(三格式端到端、合并 6 条、必须先失败 8 条含双检互补样本与确定性 提交失败回滚、报告契约 5 条)+ 5 条 CLI(三态退出码、JSON 契约、既有命令回归、help)。 fmt / clippy(core+cli, -D warnings) 绿;文件全部 ≤400 行。
This commit is contained in:
1 parent
78bcc3038b
commit
4760714743
32 files changed
+5044
-5
No files matched your search
@@ -37,6 +37,13 @@ pub struct Outcome {
|
||||
pub report: Report,
|
||||
/// 环境级提示(人类模式进 stderr,JSON 模式进信封的 `warnings`)。
|
||||
pub warnings: Vec<String>,
|
||||
/// 命令自定义的退出码;`None` = 0(绝大多数命令)。
|
||||
///
|
||||
/// 只有"结果多态且脚本要分流"的命令才用得上:`ull pack import` 的三态是
|
||||
/// `0` 成功 / `3` 部分成功 / `1` 失败,光靠 0/1 分不出来。加这个字段而不是让命令
|
||||
/// 自己 `std::process::exit`,是为了让**输出照常刷新**(绕过 runner 的输出刷新会把
|
||||
/// "输出没刷完就退出"这种 bug 装进 CLI)。
|
||||
pub exit_code: Option<i32>,
|
||||
}
|
||||
|
||||
impl Outcome {
|
||||
@@ -46,6 +53,7 @@ impl Outcome {
|
||||
Self {
|
||||
report,
|
||||
warnings: Vec::new(),
|
||||
exit_code: None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,8 +66,16 @@ impl Outcome {
|
||||
.into_iter()
|
||||
.map(|line| fill_program(&line))
|
||||
.collect(),
|
||||
exit_code: None,
|
||||
}
|
||||
}
|
||||
|
||||
/// 指定进程退出码(不指定 = 0)。
|
||||
#[must_use]
|
||||
pub fn with_exit_code(mut self, code: i32) -> Self {
|
||||
self.exit_code = Some(code);
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
/// 打印成功结果。
|
||||
|
||||
Reference in new issue
Block a user