fix(cargo-anvil): make anvil-fmt actually run the pinned nightly rustfmt - #159
fix(cargo-anvil): make anvil-fmt actually run the pinned nightly rustfmt#159Evgenii (Vaiz) wants to merge 1 commit into
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. ❌ Your project status has failed because the head coverage (97.5%) is below the target coverage (100.0%). You can increase the head coverage or adjust the target coverage. Additional details and impacted files@@ Coverage Diff @@
## main #159 +/- ##
=====================================
Coverage 97.5% 97.5%
=====================================
Files 299 299
Lines 67766 67766
=====================================
+ Hits 66127 66132 +5
+ Misses 1639 1634 -5
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
🟢 Approval recommended
The change corrects toolchain selection for cargo fmt with a targeted regression test and consistent regenerated artifacts, with no remaining issues found in the reviewed diffs.
Pull request overview
This PR fixes anvil-fmt so it consistently runs the pinned nightly rustfmt by selecting the nightly toolchain via RUSTUP_TOOLCHAIN, ensuring unstable rustfmt.toml options are actually enforced even when an ambient/stable toolchain selection would otherwise leak into cargo fmt.
Changes:
- Update the
anvil-fmtcheck to set$env:RUSTUP_TOOLCHAINto the pinned nightly and runcargo fmtwithout relying on nested+toolchain. - Add a regression test that simulates a hostile inherited
RUSTUP_TOOLCHAINand asserts the pinned nightly selection is still used for formatting-related cargo invocations. - Extend the “no implicit default cargo” invariant to treat a per-recipe
RUSTUP_TOOLCHAINpin as an explicit toolchain selection.
File summaries
| File | Description |
|---|---|
| justfiles/anvil/checks/fmt.just | Pins nightly via RUSTUP_TOOLCHAIN and runs cargo each … cargo fmt … so rustfmt resolves under the intended toolchain. |
| crates/cargo-anvil/templates/justfiles/anvil/checks/fmt.just | Template source updated to generate the fixed anvil-fmt recipe. |
| crates/cargo-anvil/tests/recipe_contracts.rs | Adds/updates tests asserting correct cargo fmt invocation and toolchain pinning behavior under inherited toolchain env. |
| crates/cargo-anvil/src/anvil/artifacts/justfile.rs | Updates invariant checking to allow explicit toolchain selection via per-recipe $env:RUSTUP_TOOLCHAIN pinning. |
| crates/cargo-anvil/tests/snapshots/snapshots__local_only.snap | Snapshot update reflecting the generated fmt.just changes. |
| crates/cargo-anvil/tests/snapshots/snapshots__github_backend.snap | Snapshot update reflecting the generated fmt.just changes. |
| crates/cargo-anvil/tests/snapshots/snapshots__ado_backend.snap | Snapshot update reflecting the generated fmt.just changes. |
| .anvil.lock | Updates checksums to match the regenerated artifacts/templates. |
Review details
- Files reviewed: 7/8 changed files
- Comments generated: 0
- Review effort level: Lite
💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
25ce18f to
966f52c
Compare
There was a problem hiding this comment.
🟢 Approval recommended
The change directly addresses the described toolchain-leak failure mode and adds targeted contract coverage to prevent regressions under hostile ambient RUSTUP_TOOLCHAIN.
Review details
- Files reviewed: 7/8 changed files
- Comments generated: 0 new
- Review effort level: Lite
`cargo fmt` only dispatches: cargo-fmt runs `rustfmt` as a child process
through the rustup shim, and that shim reads `RUSTUP_TOOLCHAIN`, which
rustup exports into every child of a `+`-selected cargo and does not
rewrite when a nested cargo carries its own `+`. So the inner
`+{{ rust_nightly }}` selected a nightly cargo, but the `rustfmt`
underneath it still resolved through the outer stable selection. Stable
rustfmt does not fail on unstable options -- it downgrades each to a
warning and exits 0, so every unstable `rustfmt.toml` rule silently
stopped being enforced while the check kept passing.
Set `RUSTUP_TOOLCHAIN` for the recipe instead, which covers every
descendant. The wrapper loses its stable pin deliberately: that pin is
the thing that leaks, and `cargo each` only enumerates members, it
compiles nothing.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
966f52c to
4ca357a
Compare
There was a problem hiding this comment.
🟢 Approval recommended
The change is narrowly scoped, matches the stated failure mode, and includes targeted tests to prevent regressions under hostile RUSTUP_TOOLCHAIN environments.
Review details
- Files reviewed: 7/8 changed files
- Comments generated: 0 new
- Review effort level: Lite
🤖 Clawpilot here! Posted automatically by Clawpilot (an AI agent), not by a human. Please verify before acting.
The bug
anvil-fmtwas a green check that enforced nothing.cargo fmtonly dispatches: cargo-fmt runsrustfmtas a child process through the rustup shim, and that shim readsRUSTUP_TOOLCHAIN— which rustup exports into every child of a+-selected cargo and does not rewrite when a nested cargo carries its own+. So inthe inner
+nightlyselected a nightly cargo, but therustfmtunderneath it still resolved through the outer stable selection. Stable rustfmt does not fail on unstable options — it downgrades each to a warning and exits 0, so every unstablerustfmt.tomlrule silently stopped being enforced while the check kept passing.An ambient
RUSTUP_TOOLCHAIN(which anvil's own cloud setup exports) breaks it the same way, so dropping the stable pin alone is not a fix.The fix
RUSTUP_TOOLCHAINcovers every descendant, which is what a dispatcher needs; the assignment is scoped to this recipe's process. The wrapper loses its stable pin deliberately — that pin is the thing that leaks, andcargo eachonly enumerates members, it compiles nothing.anvil-fmtwas the only recipe nesting cargos this way. udeps, miri, careful, external-types, bolero and llvm-cov are cargo subcommands dispatched by the already-selected nightly cargo, so they resolve correctly even under a hostile ambientRUSTUP_TOOLCHAIN;rustfmtis the outlier because it is a separate rustup component re-resolved fromPATH.Tests
fmt_runs_the_pinned_nightly_over_workspace_members(the existing delegation test, extended) hands the recipe a hostile ambientRUSTUP_TOOLCHAIN=test-stableand asserts every cargo it spawns still sees the pinned nightly. Verified load-bearing against both broken forms: the original recipe, and the partial fix that only removes the stable pin.checks_do_not_invoke_an_implicit_default_cargonow accepts an assignment-scoped$env:RUSTUP_TOOLCHAIN = '{{ … }}'as an explicit selection, tracked per recipe and only when it interpolates a catalog variable.Verification
cargo run -p cargo-anvil -- anvil, snapshots regenerated,cargo fmt --check/clippy -D warnings/cargo test -p cargo-anvilall green.microsoft/oxidizer:just anvil-fmtwent from 2306 unstable-feature warnings (exit 0) to zero.Downstream
microsoft/oxidizer#728 carries a repository-customized
fmt.justsolely because of this bug; once oxidizer picks up the new cargo-anvil, that customization can be dropped.