Skip to content

refactor(tool): 接入 invocation 构建状态#115

Merged
ZR233 merged 1 commit into
drivercraft:mainfrom
MRNIU:feature/invocation-build-state-boundaries
May 29, 2026
Merged

refactor(tool): 接入 invocation 构建状态#115
ZR233 merged 1 commit into
drivercraft:mainfrom
MRNIU:feature/invocation-build-state-boundaries

Conversation

@MRNIU
Copy link
Copy Markdown
Contributor

@MRNIU MRNIU commented May 27, 2026

Summary

  • 将 build config 激活后的运行时状态接入 InvocationState,让 active build、变量作用域和 runtime artifacts 有明确的内部 source of truth。
  • 保持 InvocationStateActiveBuildContextActiveCargoBuildActiveCustomBuild 为 crate-private 实现细节,避免把可变运行状态扩成公共 API。
  • 增加临时 legacy_context 胶水层,把 InvocationState 镜像到旧 AppContext,集中 Tool::ctx* 过渡期同步逻辑。
  • CargoBuildPipeline&mut Tool 中解耦,改为接收显式 CargoBuildInput,由 orchestration 层消费 build outcome 并写回 runtime artifacts。
  • 保留 menuconfig 的编辑语义:默认 build config 编辑完成后只记录配置,不提前校验或激活 Cargo package,避免配置修复流程被 stale/missing package 阻断。
  • 将 CLI --package/--bin selector 处理留在二进制入口私有逻辑中,内部 selector / activation helper 不作为 public API 暴露。

Approach

这次变更继续保留 Tool 作为 public compatibility facade,但把可变运行状态的源头迁移到 invocation 边界。build pipeline 只负责构造/执行 Cargo 命令并返回 build facts;build orchestration 负责消费 outcome、准备 runtime artifacts,并写回 InvocationState

InvocationState 和 active build context 现在只在 crate 内部可见。对外仍保留 Invocation / InvocationOptions / Tool 这类入口,但不暴露可变状态容器本身,避免形成新的长期 public API 负担。

legacy_context 是临时兼容层:InvocationState 是 source of truth,AppContext 只服务现有 Tool::ctxTool::ctx_mutTool::into_context 调用。后续删除旧兼容 API 时,应优先删除这个模块。

配置加载和配置编辑不再默认 eager 激活 build state。真正需要变量作用域、Cargo package 目录或 runtime artifact 的 build/run/runner config 路径会在消费具体 build config 时同步 active build。CLI selector 则保持在 ostool 二进制内私有应用,并在读取 .board.toml 前更新 legacy context,确保 ${package} 仍按选中 package 展开。

Changed Modules

  • ostool/src/invocation.rs: 增加 invocation runtime state 和 active build context,并将这些状态类型收窄为 crate-private。
  • ostool/src/legacy_context.rs: 增加临时 InvocationState <-> AppContext 兼容桥接层。
  • ostool/src/build/mod.rs: 增加 build context activation 和 CargoBuildInput 构造路径;将 selector 辅助类型保持为内部实现细节。
  • ostool/src/build/cargo_pipeline.rs: 让 pipeline 接收显式 build input,不再持有可变 Tool
  • ostool/src/tool.rs: 将 Tool 收缩为状态同步和兼容 facade;加载 build config 时只记录 legacy config,实际消费时再同步 active build。
  • ostool/src/main.rs: CLI selector 改为二进制内私有处理,并补充 board config scope 回归测试。
  • ostool/src/menuconfig.rs: 默认 build config 编辑后只记录配置,不提前验证选中的 Cargo package。
  • ostool/tests/public_api.rs, ostool/tests/ui/fail_invocation_state.rs, ostool/tests/ui/fail_build_activation_api.rs: 增加 public API 边界回归测试。

Compatibility

  • CLI、配置格式和 runner 调用模型保持不变。
  • ToolToolConfigManifestContextctx::OutputArtifacts 继续保留为兼容 API。
  • InvocationState / ActiveBuildContext / active build structs 不作为 public API 暴露。
  • CargoSelector、selector 应用函数和 build activation helper 也不作为 public API 暴露。
  • Tool::ctx_mut() 仍保留,但新代码应优先使用 state-aware Tool 方法;直接修改旧 AppContext 不会反向更新 InvocationState
  • ostool menuconfig 仍允许用户打开并修复默认 build config,不会因为配置中的 Cargo package 暂时不存在而在编辑后立即失败。

Verification

已运行并通过:

  • cargo fmt --all -- --check
  • cargo test -p ostool --test public_api --target x86_64-unknown-linux-gnu -- --nocapture
  • cargo test -p ostool --target x86_64-unknown-linux-gnu -- --nocapture
  • cargo clippy -p ostool --target x86_64-unknown-linux-gnu --all-features
  • cargo build -p ostool --target x86_64-unknown-linux-gnu --all-features
  • git diff --check
  • cargo clippy --target x86_64-unknown-linux-gnu --all-features
  • cargo build --target x86_64-unknown-linux-gnu --all-features
  • cargo test --target x86_64-unknown-linux-gnu -- --nocapture

Risks / Follow-up

  • Tool 仍是兼容 facade;runner/board entrypoint 的显式输入迁移可以作为后续切片继续做。
  • legacy_context 是临时过渡层,应在 Tool::ctx / ctx_mut / into_context 兼容面退休后删除。
  • 本 PR 保留现有 someboot build config 注入语义,不处理后续 cleanup。

让 Tool 继续作为兼容 facade,同时把 build config 激活、Cargo 构建输入和 runtime artifact 写回迁移到 invocation state 边界。CargoBuildPipeline 不再持有可变 Tool 引用,build orchestration 负责消费明确的 build outcome,并通过临时 legacy_context 胶水层把 InvocationState 镜像到旧 AppContext。

InvocationState 是 active build、变量作用域和 runtime artifacts 的 source of truth;AppContext 仅作为 Tool::ctx/ctx_mut/into_context 的兼容镜像保留。加载或编辑 build config 只记录 legacy build_config,不再在 menuconfig 或纯加载路径 eager 激活 state,真正 build/run 和 runner config 读取路径再同步 active build。

CLI 的 --package/--bin selector 保持在二进制入口私有处理,并在读取 .board.toml 前更新 legacy ctx 作用域,保持 ${package} 按选中 package 展开。内部 CargoSelector、selector helper 和 build activation helper 不作为 public API 暴露,避免 R1 重构辅助面变成长期外部契约。

补充 menuconfig 回归测试,覆盖默认 build config 编辑不会验证暂时缺失的 Cargo package;补充 trybuild public API 负向用例,防止 build activation API 从内部边界泄漏。CLI、配置格式和 runner 入口保持通过 Tool facade 调用。

Co-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
@MRNIU MRNIU marked this pull request as ready for review May 27, 2026 05:15
Copy link
Copy Markdown

@mai-team-app mai-team-app Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

审查总结

本次重构将 build config 激活后的运行时状态迁移到 InvocationState,并引入 ActiveBuildContext 作为构建上下文的内部 source of truth。整体架构清晰、层次分明,API 可见性约束合理。

验证结果

  • cargo check -p ostool 编译通过
  • cargo test -p ostool 全部通过(包括 trybuild UI 回归测试)
  • cargo clippy -p ostool 无警告
  • cargo fmt --all -- --check 格式正确
  • git diff --check 无空白字符问题

代码质量评价

架构设计(良好)

  • InvocationState 作为 mutable runtime state 的单一 source of truth,ActiveBuildContext 区分 Cargo/Custom 两种构建路径,设计合理。
  • CargoBuildPipeline&mut Tool 解耦为接收显式 CargoBuildInput,消除了 pipeline 对 Tool 的可变借用依赖,使构建编排层职责更清晰。
  • legacy_context 模块作为临时兼容桥接层,集中管理 InvocationStateAppContext 的同步逻辑,文档清晰标注了删除时机。

API 可见性(正确)

  • InvocationStateActiveBuildContextActiveCargoBuildActiveCustomBuild 均为 pub(crate),不暴露为公共 API。
  • CargoSelectorapply_cargo_selectorbuild/mod.rs 中为 crate-private,CargoSelector::new 仅在 #[cfg(test)] 下可用。
  • CargoBuildPipeline::buildpub 收窄为 pub(super)
  • UI 回归测试(fail_invocation_state.rsfail_build_activation_api.rs)正确验证了公共 API 边界。

menuconfig 语义(正确)

  • record_default_build_config_edit 仅记录配置到 ctx.build_config,不触发 sync_build_context,避免了配置修复流程被 stale/missing Cargo package 阻断。

兼容性(完整)

  • sync_cargo_context 返回类型从 () 变为 anyhow::Result<()>,所有内部调用点(board/mod.rsrun/qemu.rsrun/uboot.rs)均已正确更新为使用 ?
  • Tool::ctx_mut() 保留但补充了文档说明,明确告知直接修改 AppContext 不会反向更新 InvocationState

小建议(非阻断)

  1. legacy_context::runtime_artifacts 的 fallback 逻辑(state 为空时返回 ctx.artifacts)在当前过渡期是正确的,但建议在后续清理 Tool::ctx 兼容面时一并移除此 fallback,避免 state 和 ctx 之间出现不一致的边缘情况。
  2. Tool::objcopy_output_binself.runtime_artifacts().bin()self.runtime_artifacts().elf() 连续调用了两次 runtime_artifacts(),虽然功能正确,但可以考虑将结果绑定到局部变量以提高可读性。

这些都不影响正确性,仅作后续优化参考。

Powered by mimo-v2.5-pro

Copy link
Copy Markdown

@mai-team-app mai-team-app Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

代码审查:PR #115 — refactor(tool): 接入 invocation 构建状态

总体评价

这是一个高质量的内部重构 PR,将可变运行时状态的源头从分散的 Tool 字段迁移到明确的 InvocationState。变更范围清晰、边界收窄合理、文档完整、测试充分。建议合并。


✅ 优点

  1. 状态源统一InvocationState 成为 invocation 级别的 single source of truth,AppContext 降级为兼容镜像,避免了双向同步的复杂性。

  2. 所有权改进CargoBuildPipeline 不再借用 &mut Tool,改为接收显式 CargoBuildInput,彻底解耦了 build pipeline 和 tool facade 的生命周期。这提升了后续异步并行编排的可能性。

  3. 可见性收窄InvocationStateActiveBuildContextActiveCargoBuildActiveCustomBuildCargoSelectorapply_cargo_selector 均标记为 pub(crate),并通过 trybuild UI 测试回归保护。CargoBuildPipeline::build()pub 降为 pub(super)。API 面干净可控。

  4. 错误传播修正sync_cargo_context 返回类型从 () 改为 Result<()>,所有调用点(board/mod.rsrun/qemu.rsrun/uboot.rs)均已同步更新为 ? 传播,修复了之前静默忽略错误的问题。

  5. legacy_context 设计务实:兼容层显式标记为临时模块,runtime_artifactsruntime_arch 优先读取 state,仅在 state 为空时回退到 ctx,过渡语义清晰。文档注释中明确给出了删除时机。

  6. menuconfig 语义保留record_default_build_config_edit 只记录配置到 ctx,不触发 Cargo package 校验,保持了「编辑时允许 package 暂时不存在」的用户体验。

  7. PR 描述质量:Summary / Approach / Changed Modules / Compatibility / Verification / Risks 结构完整,是项目内 PR 描述的典范。

🔍 验证结果

  • cargo fmt --all -- --check ✅ 通过
  • cargo clippy -p ostool --all-features ✅ 无警告
  • cargo test -p ostool --lib ✅ 157 个单元测试全部通过
  • cargo test -p ostool --test public_api ✅ UI 回归测试通过(6 个 trybuild case)
  • cargo test -p ostool --doc ✅ 文档测试通过

💡 轻微观察(非阻塞)

  1. main.rsbuild/mod.rsapply_cargo_selector 重复main.rs 中的 CLI 版本额外处理 ctx_mut().build_config 更新,而 build/mod.rs 中的内部版本只修改 BuildConfig。两者的职责差异是合理的(CLI 需要同步 legacy context),但未来可以考虑让 build/mod.rs 版本也通过 legacy_context 桥接写回,减少 main.rs 直接操作 ctx_mut() 的频率。

  2. CargoBuildInput 的布尔快照debugenable_someboot_build_config 在构造时从 Tool 快照。这是有意为之的解耦设计,但如果同一个 Tool 在一次 invocation 中多次调用 build pipeline,需确保每次构造 CargoBuildInput 时传入当前值。当前所有调用点都是正确的。

结论

重构方向正确、实现干净、测试充分、兼容性无损。同意合并。

Powered by mimo-v2.5-pro

@MRNIU
Copy link
Copy Markdown
Contributor Author

MRNIU commented May 27, 2026

AI,轻而易举啊!

@MRNIU
Copy link
Copy Markdown
Contributor Author

MRNIU commented May 28, 2026

@ZR233 hi,麻烦 review

@ZR233 ZR233 merged commit 09a1297 into drivercraft:main May 29, 2026
1 check passed
MRNIU added a commit to MRNIU/ostool that referenced this pull request May 29, 2026
同步 fork 侧计划文档到 upstream/main 已合入 drivercraft#115 后的状态。

记录 drivercraft#108/drivercraft#111/drivercraft#114/drivercraft#115 已完成 R1 上游友好切片,并明确 InvocationState、ActiveBuildContext、artifact state 与 build config loader/menu hooks 已进入主路径。

保留完整 R1 终态尚未完成的边界:Tool/ctx 仍是兼容 API,runner/board entrypoints 仍依赖 Tool facade;下一步默认先做 R2 artifact/object-tools 窄切片,或另行切 R1g runner/board seam。

Co-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants