feat(coverage-gate): add target-specific policies - #101
Conversation
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Keep the target-aware coverage-gate implementation publishable on its own. Cargo Anvil can consume version 0.4.0 after the crate has been released to crates.io. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Codecov Report✅ All modified and coverable lines are covered by tests. ❌ Your project status has failed because the head coverage (97.7%) 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 #101 +/- ##
======================================
Coverage 97.7% 97.7%
======================================
Files 286 287 +1
Lines 62174 62363 +189
======================================
+ Hits 60751 60942 +191
+ Misses 1423 1421 -2
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:
|
Exercise rustc target discovery failures and every target policy shape so coverage and mutation gates validate the new behavior. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The rustc discovery tests require filesystem and process access, both forbidden by Miri isolation. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
| min-lines-percent = 100 | ||
|
|
||
| [package.metadata.coverage-gate.target.'cfg(not(windows))'] | ||
| enabled = false |
There was a problem hiding this comment.
Why introduce a new enabled flag when we already have min-lines-percent and expect-no-coverable-lines?
There was a problem hiding this comment.
🤖 Agreed — enabled was redundant with the existing policy keys. I removed it in 0070062.
Target opt-outs now use min-lines-percent = 0; a positive target-specific threshold restores gating for an exact-triple override, and expect-no-coverable-lines = true remains the self-validating assertion. I updated the design, generated README, parser, tests, and metadata-only package query accordingly.
Remove the redundant target enabled flag. Target policies now use the existing min-lines-percent and expect-no-coverable-lines keys exclusively. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
This PR extends cargo-coverage-gate with Cargo-style target selectors so packages can vary coverage policy by target triple / cfg(...), and adds CLI + library surfaces to evaluate policy for an explicit target and to query “test-only” (non-instrumented) packages.
Changes:
- Add target-policy parsing and application during workspace metadata load (exact triple precedence; ambiguous matching cfg policies fail closed).
- Add
--targetand a metadata-only--print-test-only-packagesmode (plus a newtest_only_packageslibrary API). - Introduce target discovery/matching via
cargo-platformand a newTargetContextmodule, and bumpcargo-coverage-gateto0.4.0.
Reviewed changes
Copilot reviewed 12 out of 13 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| crates/cargo-coverage-gate/tests/cli.rs | Adds CLI integration tests for --target and --print-test-only-packages, plus workspace test helpers. |
| crates/cargo-coverage-gate/src/workspace.rs | Implements parsing + resolution of target-specific policies during workspace load, including ambiguity rejection. |
| crates/cargo-coverage-gate/src/verdict.rs | Exposes resolve_gated internally so it can be reused by the new metadata-only query API. |
| crates/cargo-coverage-gate/src/target.rs | New module to resolve a target triple + rustc --print cfg and match against cargo-platform selectors. |
| crates/cargo-coverage-gate/src/lib.rs | Updates public API/docs: adds evaluate_many_for_target and test_only_packages, wires workspace loading with target. |
| crates/cargo-coverage-gate/src/error.rs | Adds error types for invalid/ambiguous target policies and target resolution failures. |
| crates/cargo-coverage-gate/src/bin/cargo-coverage-gate/run.rs | Adds early-exit --print-test-only-packages flow and passes target into evaluation. |
| crates/cargo-coverage-gate/src/bin/cargo-coverage-gate/cli.rs | Defines --target and --print-test-only-packages CLI flags and help text. |
| crates/cargo-coverage-gate/README.md | Regenerates user-facing docs to describe target policies and new CLI/API surfaces. |
| crates/cargo-coverage-gate/docs/design/README.md | Updates design doc to specify target policy schema, precedence rules, and new CLI behavior. |
| crates/cargo-coverage-gate/Cargo.toml | Bumps crate version to 0.4.0 and adds cargo-platform dependency. |
| Cargo.toml | Adds cargo-platform as a workspace dependency. |
| Cargo.lock | Updates lockfile for the new dependency and crate version bump. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Sander Saares (sandersaares)
left a comment
There was a problem hiding this comment.
[Copilot speaking]
Published 25 findings. No finding follows up on an existing discussion thread.
See diagnostics
| Diagnostic | Value |
|---|---|
| Cache | Miss |
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 12 out of 13 changed files in this pull request and generated 1 comment.
Suppressed comments (1)
crates/cargo-coverage-gate/src/workspace.rs:234
- The PR description and config example mention a target-specific
enabled = false, but target policy parsing here only acceptsmin-lines-percentorexpect-no-coverable-lines = true(and errors if neither is set). As-is, configs usingenabled = falsewill fail to load; either implementenabledin target policy tables (and define how it interacts with threshold/expect), or update the PR description/example to match the actual supported schema.
let policy = if expect_no_coverable_lines {
PolicyOverride::ExpectNoCoverableLines
} else if let Some(value) = min_lines_percent {
PolicyOverride::Threshold(value)
} else {
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 12 out of 13 changed files in this pull request and generated no new comments.
Suppressed comments (1)
Previously missed (1) — in code that hasn't changed since the last review.
crates/cargo-coverage-gate/src/verdict.rs:157
resolve_gatedis only used within this module, so widening it topub(crate)is unnecessary and increases the internal surface area for no clear benefit. Keeping it private makes refactors easier and prevents accidental cross-module coupling.
pub(crate) fn resolve_gated<'w>(workspace: &'w Workspace, packages: &[String]) -> Result<Vec<&'w Member>, CoverageGateError> {
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 12 out of 13 changed files in this pull request and generated no new comments.
Suppressed comments (1)
Previously missed (1) — in code that hasn't changed since the last review.
crates/cargo-coverage-gate/src/verdict.rs:157
resolve_gatedwas widened topub(crate)but appears to still be used only withinverdict.rs. Keeping it private reduces the API surface inside the crate and makes future refactors easier (callers can’t accidentally start depending on it).
pub(crate) fn resolve_gated<'w>(workspace: &'w Workspace, packages: &[String]) -> Result<Vec<&'w Member>, CoverageGateError> {
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 13 out of 14 changed files in this pull request and generated no new comments.
Suppressed comments (1)
Previously missed (1) — in code that hasn't changed since the last review.
crates/cargo-coverage-gate/src/verdict.rs:157
resolve_gatedis only used withinverdict.rs(the only call site isevaluate(...)above), so making itpub(crate)unnecessarily expands the crate-internal surface area and makes refactors harder. Keeping it private avoids accidental cross-module coupling.
pub(crate) fn resolve_gated<'w>(workspace: &'w Workspace, packages: &[String]) -> Result<Vec<&'w Member>, CoverageGateError> {
🤖
Summary
cargo-coverage-gatecargo-coverage-gateto 0.4.0Motivation
Addresses the coverage policy gaps reported in:
expect-no-coverable-linesremains appropriate for facades and re-export crates: those packages stay instrumented, their tests can cover dependencies, and the gate asserts that the package itself owns no coverable lines. Platform-gated packages can apply that assertion only on unsupported targets while retaining a positive threshold on supported targets.Thresholds control verdicts, not instrumentation. A target-specific zero threshold disables gating without removing the package's tests from the instrumented run. If cargo-llvm-cov reports that an instrumented run produced no coverage data, an orchestrator can pass an empty lcov tracefile and let the effective policies determine whether the result is valid.
Cargo Anvil adoption is intentionally deferred until 0.4.0 has been published to crates.io; otherwise its generated setup would pin an unavailable version.
Configuration
Exact target triples take precedence over matching
cfg(...)selectors; ambiguous matching cfg policies fail closed.