Route Rust toolchain trampolines through soldr#54
Conversation
Replaces fbuild's hand-rolled PATH-munging trampolines with calls to soldr, which resolves each tool via \`rustup which\` so the rustup-managed toolchain is always used without per-call environment shaping. - \`ci/trampoline.py\`: cargo/rustc/rustfmt/clippy_driver functions now exec \`soldr [--no-cache] <subcommand>\` instead of discovering \`.cargo/bin\` and prepending it to PATH. \`cargo\` passes \`--no-cache\` so the previous bare-cargo semantics are preserved — soldr's own RUSTC_WRAPPER/zccache path is not inserted. \`_run_cargo_bin\` (backing \`run_fbuild\` / \`run_fbuild_daemon\`) also routes through soldr. - \`_cargo\` / \`_rustc\` / \`_rustfmt\` bash shims: one-liners that \`exec uv run soldr ...\`. Same user-facing behavior as before. - \`ci/dev-tools/pyproject.toml\`: pulls \`soldr>=0.7.0\` as a Python dep so the \`soldr\` binary is available in the venv that the uv-run trampolines execute under. - \`ci/hooks/tool_guard.py\`: accepts \`soldr ...\` as a valid prefix alongside \`uv run\` and the \`_cargo\` trampolines. New test case covers \`soldr cargo\`, \`soldr --no-cache cargo\`, \`soldr rustc\`, \`soldr rustfmt\`. - Docs: \`CLAUDE.md\`, \`CODEX.md\`, \`ci/dev-tools/README.md\`, \`ci/hooks/README.md\` list \`soldr ...\` as an approved form and explain that the cargo trampoline uses \`--no-cache\` to preserve prior semantics. Cargo.lock picks up the existing 2.1.14 → 2.1.15 version alignment (\`cargo check\` regenerated it during local verification). uv.lock updates with the new soldr dep. Closes #53 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
📝 WalkthroughWalkthroughThis PR replaces fbuild's hand-rolled Rust toolchain trampolines ( Changes
Sequence Diagram(s)sequenceDiagram
participant User as Build Command
participant UV as uv run
participant Soldr as soldr
participant Rustup as rustup which
participant Tool as Rust Tool<br/>(cargo/rustc)
User->>UV: uv run cargo check
UV->>Soldr: soldr --no-cache cargo check
Soldr->>Rustup: rustup which cargo
Rustup-->>Soldr: path to toolchain cargo
Soldr->>Tool: Execute cargo check
Tool-->>User: Build result
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
CLAUDE.md (1)
69-69:⚠️ Potential issue | 🟡 MinorHook description is out of sync with the updated allow-list.
Line 7 (and
ci/hooks/README.md, and thetool_guard.pydenial message) now listsoldralongsideuv runand the_cargo/_rustc/_rustfmttrampolines, but this line still mentions onlyuv runand the trampolines. Worth syncing to avoid confusing users who read the hooks section.📝 Proposed doc fix
-- **PreToolUse**: `ci/hooks/tool_guard.py` blocks bare Rust commands (must use `uv run` or `_cargo`/`_rustc`/`_rustfmt` trampolines) and bare `python`/`pip` (must use `uv`) across supported shell tools, not just Bash +- **PreToolUse**: `ci/hooks/tool_guard.py` blocks bare Rust commands (must use `uv run`, `soldr`, or `_cargo`/`_rustc`/`_rustfmt` trampolines) and bare `python`/`pip` (must use `uv`) across supported shell tools, not just Bash🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@CLAUDE.md` at line 69, Update the PreToolUse bullet so it matches the allow-list by adding "soldr" alongside "uv run" and the `_cargo`/`_rustc`/`_rustfmt` trampolines (i.e., change the text in the PreToolUse line to list `soldr`, `uv run`, and the trampolines as allowed patterns), and ensure the same wording is reflected in the tool_guard.py messages and ci/hooks/README.md denial/help text to keep all descriptions consistent (search for the PreToolUse string, the denial message in tool_guard.py, and the corresponding README entry to update).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Outside diff comments:
In `@CLAUDE.md`:
- Line 69: Update the PreToolUse bullet so it matches the allow-list by adding
"soldr" alongside "uv run" and the `_cargo`/`_rustc`/`_rustfmt` trampolines
(i.e., change the text in the PreToolUse line to list `soldr`, `uv run`, and the
trampolines as allowed patterns), and ensure the same wording is reflected in
the tool_guard.py messages and ci/hooks/README.md denial/help text to keep all
descriptions consistent (search for the PreToolUse string, the denial message in
tool_guard.py, and the corresponding README entry to update).
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 9a0a3386-c33b-4e77-bfa1-4a74948b732b
⛔ Files ignored due to path filters (2)
Cargo.lockis excluded by!**/*.lockuv.lockis excluded by!**/*.lock
📒 Files selected for processing (11)
CLAUDE.mdCODEX.md_cargo_rustc_rustfmtci/dev-tools/README.mdci/dev-tools/pyproject.tomlci/hooks/README.mdci/hooks/test_tool_guard.pyci/hooks/tool_guard.pyci/trampoline.py
Replaces zccache's hand-rolled PATH-munging trampolines with calls to soldr, which resolves each tool via \`rustup which\` so the rustup-managed toolchain is always used without per-call environment shaping. Parallel to FastLED/fbuild#54. Nice closing of the loop: soldr already fetches and invokes zccache as its managed RUSTC_WRAPPER. Having zccache itself build through soldr closes the circle. - \`ci/trampoline.py\`: cargo/rustc/rustfmt/clippy_driver exec \`soldr [--no-cache] <subcommand>\` instead of discovering cargo_bin and calling \`ensure_windows_msvc\`. soldr already enforces MSVC on Windows. \`cargo\` passes \`--no-cache\` so soldr's own RUSTC_WRAPPER / managed-zccache path is not inserted — prior bare-cargo semantics preserved. \`_run_cargo_bin\` (run_zccache, run_zccache_daemon, run_zccache_fingerprint, check_on_stop) also routes through soldr. \`ci.env.activate()\` is still called first so repo-local \`.rustup\` / \`.cargo\` layouts still win — soldr's \`rustup which\` honors those env vars. - \`_cargo\` / \`_rustc\` / \`_rustfmt\`: bash trampolines preserve the repo-local RUSTUP_HOME / CARGO_HOME detection (so vendored toolchain layouts still override the user-global location) and then \`exec uv run soldr [--no-cache] <subcommand>\`. The hand-rolled cargo_bin probe is removed. - \`ci/hooks/tool_guard.py\`: accepts \`soldr ...\` as a valid top-level invocation alongside the \`./_cargo\` / \`./_rustc\` / \`./_rustfmt\` trampolines. \`uv run cargo\` remains blocked, but the message now points at either \`./_cargo\` or \`soldr cargo\`. - \`pyproject.toml\`: pulls \`soldr>=0.7.0\` as a dev dependency and bumps \`requires-python\` from 3.9 to 3.10 (soldr wheels require 3.10+). - Docs: \`CLAUDE.md\` and \`CODEX.md\` list \`soldr <tool>\` as an approved form and explain the \`--no-cache\` preservation of previous semantics. Closes #30 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replaces zccache's hand-rolled PATH-munging trampolines with calls to soldr, which resolves each tool via \`rustup which\` so the rustup-managed toolchain is always used without per-call environment shaping. Parallel to FastLED/fbuild#54. Nice closing of the loop: soldr already fetches and invokes zccache as its managed RUSTC_WRAPPER. Having zccache itself build through soldr closes the circle. - \`ci/trampoline.py\`: cargo/rustc/rustfmt/clippy_driver exec \`soldr [--no-cache] <subcommand>\` instead of discovering cargo_bin and calling \`ensure_windows_msvc\`. soldr already enforces MSVC on Windows. \`cargo\` passes \`--no-cache\` so soldr's own RUSTC_WRAPPER / managed-zccache path is not inserted — prior bare-cargo semantics preserved. \`_run_cargo_bin\` (run_zccache, run_zccache_daemon, run_zccache_fingerprint, check_on_stop) also routes through soldr. \`ci.env.activate()\` is still called first so repo-local \`.rustup\` / \`.cargo\` layouts still win — soldr's \`rustup which\` honors those env vars. - \`_cargo\` / \`_rustc\` / \`_rustfmt\`: bash trampolines preserve the repo-local RUSTUP_HOME / CARGO_HOME detection (so vendored toolchain layouts still override the user-global location) and then \`exec uv run soldr [--no-cache] <subcommand>\`. The hand-rolled cargo_bin probe is removed. - \`ci/hooks/tool_guard.py\`: accepts \`soldr ...\` as a valid top-level invocation alongside the \`./_cargo\` / \`./_rustc\` / \`./_rustfmt\` trampolines. \`uv run cargo\` remains blocked, but the message now points at either \`./_cargo\` or \`soldr cargo\`. - \`pyproject.toml\`: pulls \`soldr>=0.7.0\` as a dev dependency and bumps \`requires-python\` from 3.9 to 3.10 (soldr wheels require 3.10+). - Docs: \`CLAUDE.md\` and \`CODEX.md\` list \`soldr <tool>\` as an approved form and explain the \`--no-cache\` preservation of previous semantics. Closes #30 Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Summary
Replaces fbuild's hand-rolled PATH-munging trampolines with calls to soldr v0.7.0. soldr resolves each toolchain binary via `rustup which`, so the rustup-managed toolchain is always used without any per-call environment shaping. Closes #53.
Behavior-preserving — all the same commands work the same way. The implementation is just thinner underneath.
Changes
Why soldr
soldr solves the exact problem this repo's trampolines were handling: finding the right rustup-managed toolchain binary on systems with polluted PATH (chocolatey cargo on Windows, stale system rust on Linux, etc.). Using soldr means:
Verification
Risk / rollback
Minimal. soldr's rustup resolver mirrors what fbuild's trampolines already do. If CI flags anything, revert is a single-commit rollback.
Closes #53
Summary by CodeRabbit
soldr>=0.7.0as a project dependency for improved Rust toolchain management.soldrfor consistent toolchain selection.