rustdoc: add --test-builder-wrapper argument

Instead of executing the test builder directly, the test builder wrapper
will be called with test builder as the first argument and subsequent
arguments. This is similar to cargo's RUSTC_WRAPPER argument.

The `--test-builder-wrapper` argument can be passed multiple times to
allow "nesting" of wrappers.
This commit is contained in:
Travis Finkenauer 2023-08-19 15:40:24 -07:00
parent ee03c286cf
commit 58dee7d781
3 changed files with 27 additions and 2 deletions

View File

@ -130,6 +130,9 @@ pub(crate) struct Options {
/// default to loading from `$sysroot/bin/rustc`.
pub(crate) test_builder: Option<PathBuf>,
/// Run these wrapper instead of rustc directly
pub(crate) test_builder_wrappers: Vec<PathBuf>,
// Options that affect the documentation process
/// Whether to run the `calculate-doc-coverage` pass, which counts the number of public items
/// with and without documentation.
@ -204,6 +207,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
.field("enable-per-target-ignores", &self.enable_per_target_ignores)
.field("run_check", &self.run_check)
.field("no_run", &self.no_run)
.field("test_builder_wrappers", &self.test_builder_wrappers)
.field("nocapture", &self.nocapture)
.field("scrape_examples_options", &self.scrape_examples_options)
.field("unstable_features", &self.unstable_features)
@ -521,6 +525,8 @@ fn println_condition(condition: Condition) {
dcx.fatal("the `--test` flag must be passed to enable `--no-run`");
}
let test_builder_wrappers =
matches.opt_strs("test-builder-wrapper").iter().map(PathBuf::from).collect();
let out_dir = matches.opt_str("out-dir").map(|s| PathBuf::from(&s));
let output = matches.opt_str("output").map(|s| PathBuf::from(&s));
let output = match (out_dir, output) {
@ -727,6 +733,7 @@ fn println_condition(condition: Condition) {
test_builder,
run_check,
no_run,
test_builder_wrappers,
nocapture,
crate_name,
output_format,

View File

@ -25,7 +25,7 @@
use std::env;
use std::io::{self, Write};
use std::panic;
use std::path::PathBuf;
use std::path::{Path, PathBuf};
use std::process::{self, Command, Stdio};
use std::str;
use std::sync::atomic::{AtomicUsize, Ordering};
@ -306,6 +306,16 @@ fn add_exe_suffix(input: String, target: &TargetTriple) -> String {
input + &exe_suffix
}
fn wrapped_rustc_command(rustc_wrappers: &[PathBuf], rustc_binary: &Path) -> Command {
let args: Vec<&Path> =
rustc_wrappers.iter().map(PathBuf::as_path).chain([rustc_binary].into_iter()).collect();
let (exe, args) = args.split_first().expect("unable to create rustc command");
let mut command = Command::new(exe);
command.args(args);
command
}
fn run_test(
test: &str,
crate_name: &str,
@ -334,7 +344,7 @@ fn run_test(
.test_builder
.as_deref()
.unwrap_or_else(|| rustc_interface::util::rustc_path().expect("found rustc"));
let mut compiler = Command::new(&rustc_binary);
let mut compiler = wrapped_rustc_command(&rustdoc_options.test_builder_wrappers, rustc_binary);
compiler.arg("--crate-type").arg("bin");
for cfg in &rustdoc_options.cfgs {
compiler.arg("--cfg").arg(&cfg);

View File

@ -530,6 +530,14 @@ fn opts() -> Vec<RustcOptGroup> {
unstable("test-builder", |o| {
o.optopt("", "test-builder", "The rustc-like binary to use as the test builder", "PATH")
}),
unstable("test-builder-wrapper", |o| {
o.optmulti(
"",
"test-builder-wrapper",
"The wrapper program for running rustc",
"WRAPPER",
)
}),
unstable("check", |o| o.optflagmulti("", "check", "Run rustdoc checks")),
unstable("generate-redirect-map", |o| {
o.optflagmulti(