Only instrument workspace members

Signed-off-by: William Woodruff <william@yossarian.net>
This commit is contained in:
William Woodruff
2026-06-12 13:45:15 -04:00
parent de6b7193cc
commit 9aa7a4010a
4 changed files with 54 additions and 10 deletions
-6
View File
@@ -1,8 +1,2 @@
[build]
rustflags = ["-C", "instrument-coverage"]
target-dir = "target/coverage"
# Target-specific rustflags take precedence over build.rustflags. Repeat the
# instrumentation flag so it is combined with Windows' static CRT flag.
[target.'cfg(all(target_env = "msvc", target_os = "windows"))']
rustflags = ["-C", "instrument-coverage"]
+27 -2
View File
@@ -2,7 +2,7 @@ use std::env;
use std::ffi::OsString;
use std::io::{BufRead, BufReader, Write};
use std::path::{Path, PathBuf};
use std::process::{Command, Stdio};
use std::process::{Command, ExitStatus, Stdio};
use anstream::println;
use anyhow::{Context, Result, bail};
@@ -11,7 +11,7 @@ use serde_json::Value;
use uv_configuration::Concurrency;
use uv_fastid::Id;
use crate::ROOT_DIR;
use crate::{COVERAGE_RUSTC_WRAPPER_ENV, ROOT_DIR};
const CARGO_MESSAGE_REASONS: [&str; 4] = [
"compiler-artifact",
@@ -71,6 +71,10 @@ pub(crate) fn coverage(args: CoverageArgs) -> Result<()> {
println!("Using a pool of {profile_pool_size} profile files");
let profile_pattern = raw_profiles.join(format!("%{profile_pool_size}m.profraw"));
let current_executable =
env::current_exe().context("failed to locate the current executable")?;
// Cargo applies `RUSTC_WORKSPACE_WRAPPER` only to workspace members, so dependency coverage
// is omitted without changing how third-party crates are compiled.
let mut child = Command::new("cargo")
.args([
"nextest",
@@ -82,6 +86,8 @@ pub(crate) fn coverage(args: CoverageArgs) -> Result<()> {
])
.args(args.nextest_args)
.current_dir(&root)
.env("RUSTC_WORKSPACE_WRAPPER", current_executable)
.env(COVERAGE_RUSTC_WRAPPER_ENV, "1")
.env("LLVM_PROFILE_FILE", profile_pattern)
.stdout(Stdio::piped())
.spawn()
@@ -158,6 +164,25 @@ pub(crate) fn coverage(args: CoverageArgs) -> Result<()> {
Ok(())
}
pub(crate) fn rustc_wrapper() -> Option<Result<ExitStatus>> {
env::var_os(COVERAGE_RUSTC_WRAPPER_ENV)?;
// Cargo passes the real `rustc` path first, followed by the original compiler arguments.
let mut arguments = env::args_os().skip(1);
let rustc = arguments.next()?;
if Path::new(&rustc).file_stem()? != "rustc" {
return None;
}
Some(
Command::new(&rustc)
.args(["-C", "instrument-coverage"])
.args(arguments)
.status()
.with_context(|| format!("failed to run `{}`", Path::new(&rustc).display())),
)
}
fn collect_coverage_binaries(reader: impl BufRead) -> Result<Vec<PathBuf>> {
let mut binaries = Vec::new();
let mut stdout = std::io::stdout().lock();
+6
View File
@@ -1,4 +1,5 @@
use std::env;
use std::process::ExitStatus;
use anyhow::Result;
use clap::Parser;
@@ -38,6 +39,11 @@ mod validate_zip;
mod wheel_metadata;
const ROOT_DIR: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/../../");
pub const COVERAGE_RUSTC_WRAPPER_ENV: &str = "UV_INTERNAL__COVERAGE_RUSTC_WRAPPER";
pub fn coverage_rustc_wrapper() -> Option<Result<ExitStatus>> {
coverage::rustc_wrapper()
}
#[derive(Parser)]
enum Cli {
+21 -2
View File
@@ -4,6 +4,7 @@ use std::process::ExitCode;
use std::str::FromStr;
use std::time::Instant;
use anstream::eprintln;
use tracing::{debug, trace};
use tracing_durations_export::DurationsLayerBuilder;
use tracing_durations_export::plot::PlotConfig;
@@ -12,11 +13,29 @@ use tracing_subscriber::layer::SubscriberExt;
use tracing_subscriber::util::SubscriberInitExt;
use tracing_subscriber::{EnvFilter, Layer};
use uv_dev::run;
use uv_dev::{COVERAGE_RUSTC_WRAPPER_ENV, coverage_rustc_wrapper, run};
use uv_static::EnvVars;
fn main() -> ExitCode {
// Handle Cargo's compiler-wrapper invocation before initializing the normal CLI runtime.
if env::var_os(COVERAGE_RUSTC_WRAPPER_ENV).is_some()
&& let Some(result) = coverage_rustc_wrapper()
{
return match result {
Ok(status) if status.success() => ExitCode::SUCCESS,
Ok(_) => ExitCode::FAILURE,
Err(error) => {
eprintln!("uv-dev coverage rustc wrapper failed: {error:#}");
ExitCode::FAILURE
}
};
}
run_main()
}
#[tokio::main(flavor = "current_thread")]
async fn main() -> ExitCode {
async fn run_main() -> ExitCode {
let (duration_layer, _guard) = if let Ok(location) = env::var(EnvVars::TRACING_DURATIONS_FILE) {
let location = PathBuf::from(location);
if let Some(parent) = location.parent() {