Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .anvil.lock
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
version = 1
tool = "anvil"
tool_version = "0.8.0"
catalog_checksum = "sha256:25beddc77b7a0f7c6d7569bd7d252f63770603600e5f3a2701eb0c5adf8ca44f"
catalog_checksum = "sha256:b878cd5259480f652389bae4c82c73bf8a776386113600d8c76e6f2b8353fd47"

[[file]]
path = ".anvil/container/Dockerfile.dockerignore"
Expand Down Expand Up @@ -125,7 +125,7 @@ checksum = "sha256:7aa0560dc9088b33e80cd55aee0a25090cbd3d3610652afd3734d0ca52ee7

[[file]]
path = "justfiles/anvil/checks/llvm-cov.just"
checksum = "sha256:a6c45a290030fc56ab39ce92d7f89b7169485edc58d931381bf7957eec1622bd"
checksum = "sha256:36986c41d7eb1a1d3c9da2243b5e3b176b4d353be0a3d2c6fe296f7c2fa67a6c"

[[file]]
path = "justfiles/anvil/checks/loom.just"
Expand Down
2 changes: 1 addition & 1 deletion crates/cargo-anvil/docs/design/checks.md
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ matrix overhead.

| Check | Invocation | Source |
|--------------|-----------------------------------------------------------------------------|--------|
| `llvm-cov` | Runs tests for every affected package under both feature configurations. Packages with a positive coverage threshold run through self-contained `cargo +<catalog-nightly> llvm-cov nextest --no-report` invocations and produce per-config lcov/cobertura reports. Packages declaring `min-lines-percent = 0` still run through plain `cargo nextest`; the opt-out disables measurement and gating, never tests. Per-config reports avoid Windows command-line overflow and are reconciled downstream by cargo-coverage-gate, Codecov, and ADO. Codecov is display-only; the local coverage gate is authoritative. | oxidizer, oxidizer-github; gate via [`cargo-coverage-gate`](../../../cargo-coverage-gate) |
| `llvm-cov` | Runs tests for every affected package under both feature configurations. Packages with a positive coverage threshold run through self-contained `cargo +<catalog-nightly> llvm-cov nextest --no-report` invocations and produce per-config lcov/cobertura reports. Packages declaring `min-lines-percent = 0` still run through plain `cargo nextest`; the opt-out disables measurement and gating, never tests. Per-config reports reduce each `llvm-cov` object list, and Windows uses the compact private build directory `target/c` to shorten every object path under the CreateProcess command-line limit. Reports are reconciled downstream by cargo-coverage-gate, Codecov, and ADO. Codecov is display-only; the local coverage gate is authoritative. | oxidizer, oxidizer-github; gate via [`cargo-coverage-gate`](../../../cargo-coverage-gate) |
| `doc-test` | Two cargo-test runs over the same affected set: `cargo test --doc --workspace --all-features --locked` and `cargo test --doc --workspace --locked` (default features). Running both catches doctests that only compile under one feature configuration (oxidizer-github runs both). nextest does not run doctests, so this stays a separate cargo-test invocation. | oxidizer, oxidizer-github |
| `examples` | `cargo build --workspace --examples --all-features --locked` -- verifies that example targets compile. Local `--run` executes selected examples after compilation with a bounded timeout; cloud workflows never pass it. Packages exclude interactive, credentialed, or otherwise unsuitable examples from an unfiltered run with `[package.metadata.anvil.examples] no-run = ["name"]`. An explicit `--example <name>` overrides the default exclusion. | oxidizer, oxidizer-github |

Expand Down
16 changes: 12 additions & 4 deletions crates/cargo-anvil/templates/justfiles/anvil/checks/llvm-cov.just
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,13 @@ anvil-llvm-cov: anvil-llvm-cov-validate-prereqs anvil-impact
Write-Host 'anvil-llvm-cov: all affected packages opted out of coverage; tests completed'
exit 0
}
# cargo-llvm-cov passes every instrumented object to llvm-cov on one
# command line. Keep its private Windows build directory compact so the
# repeated object paths leave enough room under CreateProcess's 32,767
# character limit. Preserve an explicit caller override.
if ($IsWindows -and -not $env:CARGO_LLVM_COV_TARGET_DIR) {
$env:CARGO_LLVM_COV_TARGET_DIR = 'target/c'
}
# The *report* output directory (target/coverage/) is something we
# choose and must exist before --output-path runs.
[System.IO.Directory]::CreateDirectory('target/coverage') | Out-Null
Expand All @@ -104,11 +111,12 @@ anvil-llvm-cov: anvil-llvm-cov-validate-prereqs anvil-impact
#
# Crucially this does NOT merge both configs' objects into one report.
# A single `llvm-cov report` over the union shells one `--object=` per
# test binary and, on a large workspace, overflows the Windows
# test binary and, on a large workspace, can overflow the Windows
# CreateProcess command-line limit (os error 206, "filename or extension
# is too long"). Each per-config report references only ~half the
# objects and stays under the limit. The two configs are reconciled
# *downstream* instead of via a merged report:
# is too long"). Per-config reports reduce the object count, while the
# compact Windows target directory above shortens every remaining object
# path. The two configs are reconciled *downstream* instead of via a
# merged report:
# * cargo-coverage-gate merges the two lcov files at the line level
# (per-line counts summed) -- this is the gate;
# * Codecov ingests both lcov files (it coalesces uploads);
Expand Down
57 changes: 57 additions & 0 deletions crates/cargo-anvil/tests/recipe_contracts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,12 @@ fn bolero_uses_its_supported_release_profile_option() {
);
}

#[test]
fn llvm_cov_shortens_its_private_windows_target_directory() {
assert!(LLVM_COV.contains("if ($IsWindows -and -not $env:CARGO_LLVM_COV_TARGET_DIR)"));
assert!(LLVM_COV.contains("$env:CARGO_LLVM_COV_TARGET_DIR = 'target/c'"));
}

#[test]
fn developer_options_are_explicit_and_cloud_defaults_stay_non_interactive() {
assert!(BUILD.contains("[arg(\"package\", long"));
Expand Down Expand Up @@ -109,6 +115,9 @@ if ($env:FAKE_CARGO_TOOLCHAIN_LOG) {
if ($env:FAKE_CARGO_AUTO_INSTALL_LOG) {
Add-Content -LiteralPath $env:FAKE_CARGO_AUTO_INSTALL_LOG -Value $env:RUSTUP_AUTO_INSTALL
}
if ($env:FAKE_CARGO_LLVM_COV_TARGET_DIR_LOG) {
Add-Content -LiteralPath $env:FAKE_CARGO_LLVM_COV_TARGET_DIR_LOG -Value $env:CARGO_LLVM_COV_TARGET_DIR
}
if ($args -contains 'each') {
exit [int]$env:FAKE_EACH_EXIT
}
Expand Down Expand Up @@ -1562,6 +1571,54 @@ fn all_coverage_opted_out_packages_run_both_test_configurations() {
assert_failed(&failed, "plain nextest failure for an opted-out package");
}

#[cfg(windows)]
#[test]
fn windows_coverage_uses_the_compact_target_directory() {
if !tools_available() {
return;
}
let tmp = fixture(
&[("llvm-cov.just", LLVM_COV), ("impact.just", IMPACT)],
&[
"anvil-component-nightly-llvm-tools-validate-prereqs",
"anvil-tool-cargo-llvm-cov-validate-prereqs",
"anvil-tool-cargo-nextest-validate-prereqs",
"anvil-tool-cargo-coverage-gate-validate-prereqs",
"anvil-component-nightly-llvm-tools-install",
"anvil-tool-cargo-llvm-cov-install installer",
"anvil-tool-cargo-nextest-install installer",
"anvil-tool-cargo-coverage-gate-install installer",
"anvil-impact",
],
);
let target_dir_log = tmp.path().join("target-dir.log");
seed_include(tmp.path(), "affected", "--package fixture@0.1.0 --package measured@0.1.0");
let output = run_just(
tmp.path(),
&["anvil-llvm-cov"],
&[
("FAKE_SECOND_PACKAGE_NAME", OsStr::new("measured")),
("FAKE_CARGO_LLVM_COV_TARGET_DIR_LOG", target_dir_log.as_os_str()),
],
);
assert!(
output.status.success(),
"Windows coverage path should succeed:\n{}",
String::from_utf8_lossy(&output.stderr)
);
let configured_dirs: Vec<_> = fs::read_to_string(target_dir_log)
.unwrap()
.lines()
.filter(|line| !line.is_empty())
.map(str::to_owned)
.collect();
assert!(!configured_dirs.is_empty());
assert!(
configured_dirs.iter().all(|dir| dir == "target/c"),
"unexpected coverage target directories: {configured_dirs:?}"
);
}

#[cfg(windows)]
#[test]
fn windows_arm64_fallback_accepts_empty_nextest_sets_in_both_configurations() {
Expand Down
16 changes: 12 additions & 4 deletions justfiles/anvil/checks/llvm-cov.just
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,13 @@ anvil-llvm-cov: anvil-llvm-cov-validate-prereqs anvil-impact
Write-Host 'anvil-llvm-cov: all affected packages opted out of coverage; tests completed'
exit 0
}
# cargo-llvm-cov passes every instrumented object to llvm-cov on one
# command line. Keep its private Windows build directory compact so the
# repeated object paths leave enough room under CreateProcess's 32,767
# character limit. Preserve an explicit caller override.
if ($IsWindows -and -not $env:CARGO_LLVM_COV_TARGET_DIR) {
$env:CARGO_LLVM_COV_TARGET_DIR = 'target/c'
}
# The *report* output directory (target/coverage/) is something we
# choose and must exist before --output-path runs.
[System.IO.Directory]::CreateDirectory('target/coverage') | Out-Null
Expand All @@ -104,11 +111,12 @@ anvil-llvm-cov: anvil-llvm-cov-validate-prereqs anvil-impact
#
# Crucially this does NOT merge both configs' objects into one report.
# A single `llvm-cov report` over the union shells one `--object=` per
# test binary and, on a large workspace, overflows the Windows
# test binary and, on a large workspace, can overflow the Windows
# CreateProcess command-line limit (os error 206, "filename or extension
# is too long"). Each per-config report references only ~half the
# objects and stays under the limit. The two configs are reconciled
# *downstream* instead of via a merged report:
# is too long"). Per-config reports reduce the object count, while the
# compact Windows target directory above shortens every remaining object
# path. The two configs are reconciled *downstream* instead of via a
# merged report:
# * cargo-coverage-gate merges the two lcov files at the line level
# (per-line counts summed) -- this is the gate;
# * Codecov ingests both lcov files (it coalesces uploads);
Expand Down
Loading