Skip to content

refactor(tool): 拆分构建与运行产物边界#111

Merged
ZR233 merged 2 commits into
drivercraft:mainfrom
MRNIU:refactor/tool-artifact-boundaries
May 26, 2026
Merged

refactor(tool): 拆分构建与运行产物边界#111
ZR233 merged 2 commits into
drivercraft:mainfrom
MRNIU:refactor/tool-artifact-boundaries

Conversation

@MRNIU
Copy link
Copy Markdown
Contributor

@MRNIU MRNIU commented May 23, 2026

摘要

  • 将 Cargo 可执行产物选择逻辑从 Cargo 构建流程中拆出。
  • CargoBuildPipeline::execute() 只返回 CargoBuildOutcome,不直接准备 runtime artifact 或写回 Tool 状态。
  • 将运行时 ELF/BIN 准备逻辑移动到独立的内部 artifact 模块,并由 build orchestration 层消费 outcome 后调用。
  • 保留现有 Tool artifact 状态作为兼容桥接,避免影响当前 runner 行为。
  • 补充常见 AI/agent 本地状态目录的 .gitignore 规则,包含 .Codex/,降低生成目录误入 review diff 的概率。

整体思路

构建路径现在拆成两个更清晰的内部职责:Cargo JSON message 解析负责选择最终可执行产物;运行时产物准备负责 ELF canonicalize、架构识别、生成 stripped ELF,以及按需生成 BIN。

CargoBuildPipeline::execute() 只负责运行 Cargo、解析 JSON message,并返回 CargoBuildOutcome。运行时 ELF/BIN 准备由 build orchestration 层在拿到 outcome 后调用 runtime artifact helper,再写回现有 Tool artifact state。

Tool 仍然持有现有运行时状态。新 helper 返回准备好的 artifact 数据,再由兼容桥接路径写回既有 context 字段,因此外部 CLI、配置和 runner 语义保持不变。

PR diff 只包含代码、测试和通用 ignore 规则更新,不包含 fork-only 计划资料。

文件说明

  • .gitignore:新增 .Codex/.claude/.codex/.cursor/.continue/.windsurf/.aider/.cline/.roo/.gemini/.serena/ 等常见 AI/agent 本地状态目录。
  • ostool/src/build/artifact_selector.rs:新增 Cargo executable artifact 选择器,覆盖 explicit bin、package-name fallback、default_run、single-binary fallback 和 ambiguity error。
  • ostool/src/build/cargo_pipeline.rs:将原 CargoBuilder 调整为更明确的 Cargo 构建流水线,并在解析 Cargo JSON 输出后返回 CargoBuildOutcome,不再直接处理 runtime artifact state。
  • ostool/src/build/mod.rs:消费 CargoBuildOutcome,在 orchestration 层调用 runtime artifact helper,并保持 post-build hook 的执行位置。
  • ostool/src/artifact/runtime.rs:集中处理 ELF canonicalization、架构识别、stripped ELF 生成、可选 BIN 转换,以及 runtime artifact 目录记录。
  • ostool/src/tool.rs:将 artifact 准备委托给新的 runtime artifact helper,同时保留现有 ctx::OutputArtifacts 写回路径。
  • ostool/tests/public_api.rs 和 trybuild fixtures:更新内部类型名相关的 compile-fail 覆盖。

兼容性

  • 不改变 CLI 行为。
  • 不改变配置格式。
  • 不改变 runner contract。
  • 新增模块仍然是内部实现细节。

验证

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

说明:cargo clippy -p ostool --all-targets --all-features 当前会在既有 ostool/tests/qemu_byte_stream.rs 集成测试上报 can't find crate for ostool,不属于本 PR 改动范围;本 PR 使用覆盖本次改动的 lib clippy 和 package check 作为验证。

MRNIU and others added 2 commits May 23, 2026 13:29
Split Cargo artifact selection from runtime artifact preparation so build output resolution, ELF stripping, and optional BIN conversion each live behind focused internal helpers.

The Cargo pipeline now resolves executable artifacts from JSON messages before handing them to runtime artifact preparation, while Tool keeps the existing public artifact state as a compatibility bridge.

Also ignore common local AI/agent tool state directories so generated workspace metadata is less likely to enter review diffs.

Validation: cargo fmt --all -- --check; cargo test -p ostool -- --nocapture; cargo check -p ostool; cargo clippy -p ostool --all-targets --all-features; git diff --check.

Co-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
让 CargoBuildPipeline::execute() 只返回 CargoBuildOutcome,不再直接准备 runtime artifact 或写回 Tool runtime state。

runtime artifact 写回和 post-build hook 调用移动到 build orchestration 层,保持现有 cargo build/run 行为,同时让 R1d 的 build facts seam 与 R1e runtime helper 解耦。

验证:

- docker exec devbox sh -lc 'cd /workspace/GitHub/MRNIU/ostool && cargo fmt --all -- --check && cargo test -p ostool --lib -- --nocapture && cargo test -p ostool --test public_api -- --nocapture && cargo check -p ostool'

- docker exec devbox sh -lc 'cd /workspace/GitHub/MRNIU/ostool && cargo clippy -p ostool --lib --all-features'

- docker exec devbox sh -lc 'cd /workspace/GitHub/MRNIU/ostool && cargo check -p ostool --target x86_64-unknown-linux-gnu'

- git diff --check

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 24, 2026 03:48
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.

Review: refactor(tool): 拆分构建与运行产物边界

总体评价

本 PR 将 Cargo 构建流水线与运行时产物准备逻辑做了清晰的职责拆分,重构方向正确,代码质量良好。推荐合并


架构改动分析

核心拆分思路:

  • CargoBuildPipeline::execute() 现在只返回 CargoBuildOutcome(仅包含 ResolvedCargoArtifact),不再产生 Tool 副作用。
  • 运行时 ELF/BIN 准备逻辑移至独立模块 artifact::runtime,由 orchestration 层(cargo_buildcargo_runprepare_cargo_runtime_artifacts)消费 outcome 后调用。
  • Tool::apply_prepared_runtime_artifacts() 作为统一的桥接方法,将 PreparedRuntimeArtifacts 写回既有 Tool.ctx.artifacts 状态。

三个新模块职责清晰:

  1. build::artifact_selector — Cargo JSON 消息解析与产物选择(210 行,含 7 个单元测试)
  2. artifact::runtime — ELF canonicalize、架构识别、strip、BIN 转换(298 行,含 2 个集成风格测试)
  3. build::cargo_pipeline — 精简后的 Cargo 构建流水线(execute() 仅返回 outcome)

行为兼容性分析

执行顺序保持一致 ✅

旧流程 (CargoBuilder::execute):

pre-build → cargo → handle_output (set_elf + objcopy) → post-build

新流程:

pre-build (pipeline内部) → cargo (pipeline内部) → apply_cargo_build_outcome → run_cargo_post_build_cmds

post-build hook 始终在 runtime artifact 准备之后执行,顺序与旧代码一致。

cargo_build 路径的行为差异 ⚠️

旧的 cargo_build() 直接调用 CargoBuilder::build_auto(...).execute(),其中 execute() 内部会调用 handle_output() 来设置 ELF 路径、objcopy 输出 BIN,以及运行 post-build 命令。

新的 cargo_build()apply_cargo_build_outcome() 中调用 prepare_runtime_artifacts()strip_elf 参数始终传 false。而旧代码在 cargo_build 路径中走的也是 handle_output(不做 strip),因此行为一致。✅

prepare_elf_artifact 行为保持一致 ✅

旧:set_elf_artifact_pathobjcopy_elf(strip)→ 可选 objcopy_output_bin
新:直接调用 prepare_runtime_artifactsstrip_elf: true

效果一致。

objcopy_output_bin 行为保持一致 ✅

旧代码直接在 Tool 上操作 objcopy,新代码委托给 prepare_runtime_artifacts,传入 strip_elf: false,仅做 BIN 转换。等价。


测试变更分析

被移除的测试

旧测试 原因 替代
select_executable_artifact_*(7 个,原在 cargo_builder.rs 函数移至 artifact_selector.rs 在新位置有完全等价的 7 个测试
handle_output_records_runtime_artifact_state_from_resolved_cargo_artifact handle_output 方法已删除 apply_cargo_build_outcome_records_runtime_artifact_statebuild/mod.rs)和 execute_returns_resolved_cargo_artifact_outcomecargo_pipeline.rs)联合覆盖
set_elf_artifact_path_updates_dirs_and_arch set_elf_artifact_path 方法已删除 改为 apply_prepared_runtime_artifacts_updates_dirs_and_arch

新增的测试

  1. artifact_selector.rs:7 个单元测试,覆盖 explicit bin、package name fallback、default_run、single binary fallback、空输出报错、多 binary 歧义报错 — 与旧测试一一对应,逻辑不变。
  2. artifact::runtime:2 个测试
    • prepares_stripped_elf_without_mutating_tool_state — 验证 strip 后 ELF 正确生成,且不修改 Tool 状态
    • prepares_optional_bin_in_custom_output_dir — 验证 BIN 转换到自定义目录
  3. build/mod.rsapply_cargo_build_outcome_records_runtime_artifact_state — 验证 outcome 写回 Tool artifact 状态
  4. cargo_pipeline.rsexecute_returns_resolved_cargo_artifact_outcome — 使用 fake cargo 二进制验证端到端流水线不产生 Tool 副作用

测试覆盖度评估

  • 测试总数:旧约 10 个 → 新约 12 个,覆盖度提升
  • 新增的端到端测试 execute_returns_resolved_cargo_artifact_outcome 使用了 fake cargo script,比旧的 handle_output 测试更健壮
  • artifact::runtime 测试也使用 fake objcopy,避免了依赖系统工具
  • 关键改进:新测试验证了 execute() 不产生 Tool.ctx.artifacts 副作用(assert!(tool.ctx.artifacts.elf.is_none())),这正是拆分的核心目标

trybuild fixture 更新

fail_cargo_pipeline.rs.stderr:仅更新了内部类型名 CargoBuilderCargoBuildPipeline、模块名 cargo_buildercargo_pipeline。compile-fail 断言(private module error)不变。


其他改动

  • .gitignore:新增常见 AI/agent 本地状态目录忽略规则(.Codex/.claude/.cursor/ 等),合理。
  • tool.rs:移除了 set_elf_artifact_pathobjcopy_elfcommand() 等方法,这些逻辑已迁移到 artifact::runtimeTool 的公共 API(prepare_elf_artifactobjcopy_output_bin)行为不变。

小建议(非阻塞)

  1. apply_cargo_build_outcomeobjcopy_program 硬编码为 "rust-objcopy",与 prepare_elf_artifact 一致,但未来可能需要从配置中读取。
  2. PreparedRuntimeArtifacts 的字段都是 private,只通过 getter 访问,设计良好。

结论

重构目标明确,将构建(Cargo JSON 解析)与运行时产物准备(ELF strip/BIN 转换)解耦为独立模块。测试充分,行为兼容,外部 API 不变。推荐合并。

Powered by glm-5.1

@MRNIU
Copy link
Copy Markdown
Contributor Author

MRNIU commented May 24, 2026

AI,轻而易举哇

@MRNIU
Copy link
Copy Markdown
Contributor Author

MRNIU commented May 25, 2026

@ZR233 hi,麻烦 review

@ZR233 ZR233 merged commit 9f61aac into drivercraft:main May 26, 2026
1 check passed
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