From e9047612313496f0cad1b0feb200072e0fd78027 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 1 Oct 2024 16:23:04 +0200 Subject: [PATCH] Use environment variables instead of command line arguments for merged doctests --- src/librustdoc/doctest.rs | 3 +-- src/librustdoc/doctest/runner.rs | 42 ++++++++++++-------------------- 2 files changed, 17 insertions(+), 28 deletions(-) diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index 3ee6b24ac92..e8bd36dffc7 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -644,8 +644,7 @@ fn run_test( } else { cmd = Command::new(&output_file); if doctest.is_multiple_tests { - cmd.arg("*doctest-bin-path"); - cmd.arg(&output_file); + cmd.env("RUSTDOC_DOCTEST_BIN_PATH", &output_file); } } if let Some(run_directory) = &rustdoc_options.test_run_directory { diff --git a/src/librustdoc/doctest/runner.rs b/src/librustdoc/doctest/runner.rs index 326ca4ee1e6..176008ae7a2 100644 --- a/src/librustdoc/doctest/runner.rs +++ b/src/librustdoc/doctest/runner.rs @@ -112,8 +112,7 @@ mod __doctest_mod {{ use std::path::PathBuf; pub static BINARY_PATH: OnceLock = OnceLock::new(); - pub const RUN_OPTION: &str = \"*doctest-inner-test\"; - pub const BIN_OPTION: &str = \"*doctest-bin-path\"; + pub const RUN_OPTION: &str = \"RUSTDOC_DOCTEST_RUN_NB_TEST\"; #[allow(unused)] pub fn doctest_path() -> Option<&'static PathBuf> {{ @@ -123,8 +122,8 @@ mod __doctest_mod {{ #[allow(unused)] pub fn doctest_runner(bin: &std::path::Path, test_nb: usize) -> Result<(), String> {{ let out = std::process::Command::new(bin) - .arg(self::RUN_OPTION) - .arg(test_nb.to_string()) + .env(self::RUN_OPTION, test_nb.to_string()) + .args(std::env::args().skip(1).collect::>()) .output() .expect(\"failed to run command\"); if !out.status.success() {{ @@ -138,36 +137,27 @@ mod __doctest_mod {{ #[rustc_main] fn main() -> std::process::ExitCode {{ const TESTS: [test::TestDescAndFn; {nb_tests}] = [{ids}]; -let bin_marker = std::ffi::OsStr::new(__doctest_mod::BIN_OPTION); let test_marker = std::ffi::OsStr::new(__doctest_mod::RUN_OPTION); let test_args = &[{test_args}]; +const ENV_BIN: &'static str = \"RUSTDOC_DOCTEST_BIN_PATH\"; -let mut args = std::env::args_os().skip(1); -while let Some(arg) = args.next() {{ - if arg == bin_marker {{ - let Some(binary) = args.next() else {{ - panic!(\"missing argument after `{{}}`\", __doctest_mod::BIN_OPTION); - }}; - if crate::__doctest_mod::BINARY_PATH.set(binary.into()).is_err() {{ - panic!(\"`{{}}` option was used more than once\", bin_marker.to_string_lossy()); - }} - return std::process::Termination::report(test::test_main(test_args, Vec::from(TESTS), None)); - }} else if arg == test_marker {{ - let Some(nb_test) = args.next() else {{ - panic!(\"missing argument after `{{}}`\", __doctest_mod::RUN_OPTION); - }}; - if let Some(nb_test) = nb_test.to_str().and_then(|nb| nb.parse::().ok()) {{ - if let Some(test) = TESTS.get(nb_test) {{ - if let test::StaticTestFn(f) = test.testfn {{ - return std::process::Termination::report(f()); - }} +if let Ok(binary) = std::env::var(ENV_BIN) {{ + let _ = crate::__doctest_mod::BINARY_PATH.set(binary.into()); + unsafe {{ std::env::remove_var(ENV_BIN); }} + return std::process::Termination::report(test::test_main(test_args, Vec::from(TESTS), None)); +}} else if let Ok(nb_test) = std::env::var(__doctest_mod::RUN_OPTION) {{ + if let Ok(nb_test) = nb_test.parse::() {{ + if let Some(test) = TESTS.get(nb_test) {{ + if let test::StaticTestFn(f) = test.testfn {{ + return std::process::Termination::report(f()); }} }} - panic!(\"Unexpected value after `{{}}`\", __doctest_mod::RUN_OPTION); }} + panic!(\"Unexpected value for `{{}}`\", __doctest_mod::RUN_OPTION); }} -eprintln!(\"WARNING: No argument provided so doctests will be run in the same process\"); +eprintln!(\"WARNING: No rustdoc doctest environment variable provided so doctests will be run in \ +the same process\"); std::process::Termination::report(test::test_main(test_args, Vec::from(TESTS), None)) }}", nb_tests = self.nb_tests,