From 7255c2825df1b6497dea1d689173a62ea872244f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= Date: Sun, 9 Jun 2024 14:13:38 +0000 Subject: [PATCH 1/6] run-make-support: remove `env_var` This is incorrectly named (it's actually `env_clear`), and is itself a gigantic footgun: removing `TMPDIR` on Unix and `TMP`/`TEMP` on Windows basically wrecks anything that relies on `std::env::temp_dir` from functioning correctly. For example, this includes rustc's codegen. --- src/tools/run-make-support/src/lib.rs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/tools/run-make-support/src/lib.rs b/src/tools/run-make-support/src/lib.rs index cea1313e29d..93e41b593d1 100644 --- a/src/tools/run-make-support/src/lib.rs +++ b/src/tools/run-make-support/src/lib.rs @@ -364,12 +364,6 @@ macro_rules! impl_common_helpers { self } - /// Clear all environmental variables. - pub fn env_var(&mut self) -> &mut Self { - self.cmd.env_clear(); - self - } - /// Generic command argument provider. Prefer specific helper methods if possible. /// Note that for some executables, arguments might be platform specific. For C/C++ /// compilers, arguments might be platform *and* compiler specific. From a3feeb3afe075898e4112baa90d948ef57ce4401 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= Date: Sun, 9 Jun 2024 14:13:01 +0000 Subject: [PATCH 2/6] run-make-support: add drop bomb module --- .../run-make-support/src/drop_bomb/mod.rs | 50 +++++++++++++++++++ .../run-make-support/src/drop_bomb/tests.rs | 15 ++++++ src/tools/run-make-support/src/lib.rs | 1 + 3 files changed, 66 insertions(+) create mode 100644 src/tools/run-make-support/src/drop_bomb/mod.rs create mode 100644 src/tools/run-make-support/src/drop_bomb/tests.rs diff --git a/src/tools/run-make-support/src/drop_bomb/mod.rs b/src/tools/run-make-support/src/drop_bomb/mod.rs new file mode 100644 index 00000000000..2fc84892c1b --- /dev/null +++ b/src/tools/run-make-support/src/drop_bomb/mod.rs @@ -0,0 +1,50 @@ +//! This module implements "drop bombs" intended for use by command wrappers to ensure that the +//! constructed commands are *eventually* executed. This is exactly like `rustc_errors::Diag` where +//! we force every `Diag` to be consumed or we emit a bug, but we panic instead. +//! +//! This is adapted from and simplified for our +//! purposes. + +use std::ffi::{OsStr, OsString}; +use std::panic; + +#[cfg(test)] +mod tests; + +#[derive(Debug)] +pub(crate) struct DropBomb { + command: OsString, + defused: bool, + armed_line: u32, +} + +impl DropBomb { + /// Arm a [`DropBomb`]. If the value is dropped without being [`defused`][Self::defused], then + /// it will panic. It is expected that the command wrapper uses `#[track_caller]` to help + /// propagate the caller info from rmake.rs. + #[track_caller] + pub(crate) fn arm>(command: S) -> DropBomb { + DropBomb { + command: command.as_ref().into(), + defused: false, + armed_line: panic::Location::caller().line(), + } + } + + /// Defuse the [`DropBomb`]. This will prevent the drop bomb from panicking when dropped. + pub(crate) fn defuse(&mut self) { + self.defused = true; + } +} + +impl Drop for DropBomb { + fn drop(&mut self) { + if !self.defused && !std::thread::panicking() { + panic!( + "command constructed but not executed at line {}: `{}`", + self.armed_line, + self.command.to_string_lossy() + ) + } + } +} diff --git a/src/tools/run-make-support/src/drop_bomb/tests.rs b/src/tools/run-make-support/src/drop_bomb/tests.rs new file mode 100644 index 00000000000..4a488c0f670 --- /dev/null +++ b/src/tools/run-make-support/src/drop_bomb/tests.rs @@ -0,0 +1,15 @@ +use super::DropBomb; + +#[test] +#[should_panic] +fn test_arm() { + let bomb = DropBomb::arm("hi :3"); + drop(bomb); // <- armed bomb should explode when not defused +} + +#[test] +fn test_defuse() { + let mut bomb = DropBomb::arm("hi :3"); + bomb.defuse(); + drop(bomb); // <- defused bomb should not explode +} diff --git a/src/tools/run-make-support/src/lib.rs b/src/tools/run-make-support/src/lib.rs index 93e41b593d1..20ad25efaf0 100644 --- a/src/tools/run-make-support/src/lib.rs +++ b/src/tools/run-make-support/src/lib.rs @@ -7,6 +7,7 @@ pub mod cc; pub mod clang; mod command; pub mod diff; +mod drop_bomb; pub mod llvm_readobj; pub mod run; pub mod rustc; From 54e704437b3968c3cb14bf8ceb08ca34610425ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= Date: Sun, 9 Jun 2024 14:21:04 +0000 Subject: [PATCH 3/6] run-make-support: arm command with drop bombs - Update all command wrappers and command construction helpers with `#[track_caller]` where suitable to help the drop bomb panic message. - Remove `Deref`/`DerefMut` for `Command` because it was causing issues with resolving to `std::process::Command` in a method call chain. --- src/tools/run-make-support/src/cc.rs | 7 +- src/tools/run-make-support/src/clang.rs | 2 + src/tools/run-make-support/src/command.rs | 115 +++++++++++++----- src/tools/run-make-support/src/diff/mod.rs | 10 +- src/tools/run-make-support/src/lib.rs | 25 ++-- .../run-make-support/src/llvm_readobj.rs | 2 + src/tools/run-make-support/src/run.rs | 30 ++--- src/tools/run-make-support/src/rustc.rs | 5 + src/tools/run-make-support/src/rustdoc.rs | 5 + 9 files changed, 137 insertions(+), 64 deletions(-) diff --git a/src/tools/run-make-support/src/cc.rs b/src/tools/run-make-support/src/cc.rs index 5c0158d7547..8694740cfc3 100644 --- a/src/tools/run-make-support/src/cc.rs +++ b/src/tools/run-make-support/src/cc.rs @@ -7,6 +7,7 @@ use crate::{bin_name, cygpath_windows, env_var, is_msvc, is_windows, uname}; /// /// WARNING: This means that what flags are accepted by the underlying C compiler is /// platform- AND compiler-specific. Consult the relevant docs for `gcc`, `clang` and `mvsc`. +#[track_caller] pub fn cc() -> Cc { Cc::new() } @@ -25,6 +26,7 @@ impl Cc { /// /// WARNING: This means that what flags are accepted by the underlying C compile is /// platform- AND compiler-specific. Consult the relevant docs for `gcc`, `clang` and `mvsc`. + #[track_caller] pub fn new() -> Self { let compiler = env_var("CC"); @@ -84,11 +86,6 @@ impl Cc { self.cmd.arg(path.as_ref()); self } - - /// Get the [`Output`][::std::process::Output] of the finished process. - pub fn command_output(&mut self) -> ::std::process::Output { - self.cmd.output().expect("failed to get output of finished process") - } } /// `EXTRACFLAGS` diff --git a/src/tools/run-make-support/src/clang.rs b/src/tools/run-make-support/src/clang.rs index d2ebed7ab06..a31004659c1 100644 --- a/src/tools/run-make-support/src/clang.rs +++ b/src/tools/run-make-support/src/clang.rs @@ -4,6 +4,7 @@ use crate::command::Command; use crate::{bin_name, env_var}; /// Construct a new `clang` invocation. `clang` is not always available for all targets. +#[track_caller] pub fn clang() -> Clang { Clang::new() } @@ -18,6 +19,7 @@ crate::impl_common_helpers!(Clang); impl Clang { /// Construct a new `clang` invocation. `clang` is not always available for all targets. + #[track_caller] pub fn new() -> Self { let clang = env_var("CLANG"); let cmd = Command::new(clang); diff --git a/src/tools/run-make-support/src/command.rs b/src/tools/run-make-support/src/command.rs index b9e56ab632a..f427e50906f 100644 --- a/src/tools/run-make-support/src/command.rs +++ b/src/tools/run-make-support/src/command.rs @@ -1,36 +1,107 @@ -use crate::{assert_not_contains, handle_failed_output}; +use std::ffi; use std::ffi::OsStr; use std::io::Write; -use std::ops::{Deref, DerefMut}; +use std::panic; +use std::path::Path; use std::process::{Command as StdCommand, ExitStatus, Output, Stdio}; -/// This is a custom command wrapper that simplifies working with commands -/// and makes it easier to ensure that we check the exit status of executed -/// processes. +use crate::drop_bomb::DropBomb; +use crate::{assert_not_contains, handle_failed_output}; + +/// This is a custom command wrapper that simplifies working with commands and makes it easier to +/// ensure that we check the exit status of executed processes. +/// +/// # A [`Command`] must be executed +/// +/// A [`Command`] is armed by a [`DropBomb`] on construction to enforce that it will be executed. If +/// a [`Command`] is constructed but never executed, the drop bomb will explode and cause the test +/// to panic. Execution methods [`run`] and [`run_fail`] will defuse the drop bomb. A test +/// containing constructed but never executed commands is dangerous because it can give a false +/// sense of confidence. +/// +/// [`run`]: Self::run +/// [`run_fail`]: Self::run_fail #[derive(Debug)] pub struct Command { cmd: StdCommand, stdin: Option>, + drop_bomb: DropBomb, } impl Command { - pub fn new>(program: S) -> Self { - Self { cmd: StdCommand::new(program), stdin: None } + #[track_caller] + pub fn new>(program: P) -> Self { + let program = program.as_ref(); + Self { cmd: StdCommand::new(program), stdin: None, drop_bomb: DropBomb::arm(program) } } pub fn set_stdin(&mut self, stdin: Box<[u8]>) { self.stdin = Some(stdin); } + /// Specify an environment variable. + pub fn env(&mut self, key: K, value: V) -> &mut Self + where + K: AsRef, + V: AsRef, + { + self.cmd.env(key, value); + self + } + + /// Remove an environmental variable. + pub fn env_remove(&mut self, key: K) -> &mut Self + where + K: AsRef, + { + self.cmd.env_remove(key); + self + } + + /// Generic command argument provider. Prefer specific helper methods if possible. + /// Note that for some executables, arguments might be platform specific. For C/C++ + /// compilers, arguments might be platform *and* compiler specific. + pub fn arg(&mut self, arg: S) -> &mut Self + where + S: AsRef, + { + self.cmd.arg(arg); + self + } + + /// Generic command arguments provider. Prefer specific helper methods if possible. + /// Note that for some executables, arguments might be platform specific. For C/C++ + /// compilers, arguments might be platform *and* compiler specific. + pub fn args(&mut self, args: &[S]) -> &mut Self + where + S: AsRef, + { + self.cmd.args(args); + self + } + + /// Inspect what the underlying [`std::process::Command`] is up to the + /// current construction. + pub fn inspect(&mut self, inspector: I) -> &mut Self + where + I: FnOnce(&StdCommand), + { + inspector(&self.cmd); + self + } + + /// Set the path where the command will be run. + pub fn current_dir>(&mut self, path: P) -> &mut Self { + self.cmd.current_dir(path); + self + } + /// Run the constructed command and assert that it is successfully run. #[track_caller] pub fn run(&mut self) -> CompletedProcess { - let caller_location = std::panic::Location::caller(); - let caller_line_number = caller_location.line(); - let output = self.command_output(); if !output.status().success() { - handle_failed_output(&self, output, caller_line_number); + handle_failed_output(&self, output, panic::Location::caller().line()); } output } @@ -38,18 +109,16 @@ impl Command { /// Run the constructed command and assert that it does not successfully run. #[track_caller] pub fn run_fail(&mut self) -> CompletedProcess { - let caller_location = std::panic::Location::caller(); - let caller_line_number = caller_location.line(); - let output = self.command_output(); if output.status().success() { - handle_failed_output(&self, output, caller_line_number); + handle_failed_output(&self, output, panic::Location::caller().line()); } output } #[track_caller] - pub(crate) fn command_output(&mut self) -> CompletedProcess { + fn command_output(&mut self) -> CompletedProcess { + self.drop_bomb.defuse(); // let's make sure we piped all the input and outputs self.cmd.stdin(Stdio::piped()); self.cmd.stdout(Stdio::piped()); @@ -71,20 +140,6 @@ impl Command { } } -impl Deref for Command { - type Target = StdCommand; - - fn deref(&self) -> &Self::Target { - &self.cmd - } -} - -impl DerefMut for Command { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.cmd - } -} - /// Represents the result of an executed process. /// The various `assert_` helper methods should preferably be used for /// checking the contents of stdout/stderr. diff --git a/src/tools/run-make-support/src/diff/mod.rs b/src/tools/run-make-support/src/diff/mod.rs index d864ddf4eb1..0fb6fec9d58 100644 --- a/src/tools/run-make-support/src/diff/mod.rs +++ b/src/tools/run-make-support/src/diff/mod.rs @@ -2,9 +2,12 @@ use regex::Regex; use similar::TextDiff; use std::path::Path; +use crate::drop_bomb::DropBomb; + #[cfg(test)] mod tests; +#[track_caller] pub fn diff() -> Diff { Diff::new() } @@ -16,10 +19,12 @@ pub struct Diff { actual: Option, actual_name: Option, normalizers: Vec<(String, String)>, + drop_bomb: DropBomb, } impl Diff { /// Construct a bare `diff` invocation. + #[track_caller] pub fn new() -> Self { Self { expected: None, @@ -27,6 +32,7 @@ impl Diff { actual: None, actual_name: None, normalizers: Vec::new(), + drop_bomb: DropBomb::arm("diff"), } } @@ -79,9 +85,9 @@ impl Diff { self } - /// Executes the diff process, prints any differences to the standard error. #[track_caller] - pub fn run(&self) { + pub fn run(&mut self) { + self.drop_bomb.defuse(); let expected = self.expected.as_ref().expect("expected text not set"); let mut actual = self.actual.as_ref().expect("actual text not set").to_string(); let expected_name = self.expected_name.as_ref().unwrap(); diff --git a/src/tools/run-make-support/src/lib.rs b/src/tools/run-make-support/src/lib.rs index 20ad25efaf0..bf74d94f911 100644 --- a/src/tools/run-make-support/src/lib.rs +++ b/src/tools/run-make-support/src/lib.rs @@ -17,6 +17,7 @@ use std::env; use std::ffi::OsString; use std::fs; use std::io; +use std::panic; use std::path::{Path, PathBuf}; pub use gimli; @@ -32,6 +33,7 @@ pub use run::{cmd, run, run_fail}; pub use rustc::{aux_build, rustc, Rustc}; pub use rustdoc::{bare_rustdoc, rustdoc, Rustdoc}; +#[track_caller] pub fn env_var(name: &str) -> String { match env::var(name) { Ok(v) => v, @@ -39,6 +41,7 @@ pub fn env_var(name: &str) -> String { } } +#[track_caller] pub fn env_var_os(name: &str) -> OsString { match env::var_os(name) { Some(v) => v, @@ -66,11 +69,13 @@ pub fn is_darwin() -> bool { target().contains("darwin") } +#[track_caller] pub fn python_command() -> Command { let python_path = env_var("PYTHON"); Command::new(python_path) } +#[track_caller] pub fn htmldocck() -> Command { let mut python = python_command(); python.arg(source_root().join("src/etc/htmldocck.py")); @@ -162,15 +167,13 @@ pub fn cwd() -> PathBuf { /// available on the platform! #[track_caller] pub fn cygpath_windows>(path: P) -> String { - let caller_location = std::panic::Location::caller(); - let caller_line_number = caller_location.line(); - + let caller = panic::Location::caller(); let mut cygpath = Command::new("cygpath"); cygpath.arg("-w"); cygpath.arg(path.as_ref()); - let output = cygpath.command_output(); + let output = cygpath.run(); if !output.status().success() { - handle_failed_output(&cygpath, output, caller_line_number); + handle_failed_output(&cygpath, output, caller.line()); } // cygpath -w can attach a newline output.stdout_utf8().trim().to_string() @@ -179,13 +182,11 @@ pub fn cygpath_windows>(path: P) -> String { /// Run `uname`. This assumes that `uname` is available on the platform! #[track_caller] pub fn uname() -> String { - let caller_location = std::panic::Location::caller(); - let caller_line_number = caller_location.line(); - + let caller = panic::Location::caller(); let mut uname = Command::new("uname"); - let output = uname.command_output(); + let output = uname.run(); if !output.status().success() { - handle_failed_output(&uname, output, caller_line_number); + handle_failed_output(&uname, output, caller.line()); } output.stdout_utf8() } @@ -393,7 +394,7 @@ macro_rules! impl_common_helpers { where I: FnOnce(&::std::process::Command), { - inspector(&self.cmd); + self.cmd.inspect(inspector); self } @@ -410,7 +411,7 @@ macro_rules! impl_common_helpers { } /// Set the path where the command will be run. - pub fn current_dir>(&mut self, path: P) -> &mut Self { + pub fn current_dir>(&mut self, path: P) -> &mut Self { self.cmd.current_dir(path); self } diff --git a/src/tools/run-make-support/src/llvm_readobj.rs b/src/tools/run-make-support/src/llvm_readobj.rs index db2f9db6e41..57ddfc205e6 100644 --- a/src/tools/run-make-support/src/llvm_readobj.rs +++ b/src/tools/run-make-support/src/llvm_readobj.rs @@ -5,6 +5,7 @@ use crate::env_var; /// Construct a new `llvm-readobj` invocation. This assumes that `llvm-readobj` is available /// at `$LLVM_BIN_DIR/llvm-readobj`. +#[track_caller] pub fn llvm_readobj() -> LlvmReadobj { LlvmReadobj::new() } @@ -20,6 +21,7 @@ crate::impl_common_helpers!(LlvmReadobj); impl LlvmReadobj { /// Construct a new `llvm-readobj` invocation. This assumes that `llvm-readobj` is available /// at `$LLVM_BIN_DIR/llvm-readobj`. + #[track_caller] pub fn new() -> Self { let llvm_bin_dir = env_var("LLVM_BIN_DIR"); let llvm_bin_dir = PathBuf::from(llvm_bin_dir); diff --git a/src/tools/run-make-support/src/run.rs b/src/tools/run-make-support/src/run.rs index 4a6fd7c432e..6fa1a75363c 100644 --- a/src/tools/run-make-support/src/run.rs +++ b/src/tools/run-make-support/src/run.rs @@ -1,5 +1,6 @@ use std::env; use std::ffi::OsStr; +use std::panic; use std::path::{Path, PathBuf}; use crate::command::{Command, CompletedProcess}; @@ -7,7 +8,8 @@ use crate::{cwd, env_var, is_windows, set_host_rpath}; use super::handle_failed_output; -fn run_common(name: &str) -> (Command, CompletedProcess) { +#[track_caller] +fn run_common(name: &str) -> Command { let mut bin_path = PathBuf::new(); bin_path.push(cwd()); bin_path.push(name); @@ -34,19 +36,17 @@ fn run_common(name: &str) -> (Command, CompletedProcess) { cmd.env("PATH", env::join_paths(paths.iter()).unwrap()); } - let output = cmd.command_output(); - (cmd, output) + cmd } /// Run a built binary and make sure it succeeds. #[track_caller] pub fn run(name: &str) -> CompletedProcess { - let caller_location = std::panic::Location::caller(); - let caller_line_number = caller_location.line(); - - let (cmd, output) = run_common(name); + let caller = panic::Location::caller(); + let mut cmd = run_common(name); + let output = cmd.run(); if !output.status().success() { - handle_failed_output(&cmd, output, caller_line_number); + handle_failed_output(&cmd, output, caller.line()); } output } @@ -54,18 +54,18 @@ pub fn run(name: &str) -> CompletedProcess { /// Run a built binary and make sure it fails. #[track_caller] pub fn run_fail(name: &str) -> CompletedProcess { - let caller_location = std::panic::Location::caller(); - let caller_line_number = caller_location.line(); - - let (cmd, output) = run_common(name); + let caller = panic::Location::caller(); + let mut cmd = run_common(name); + let output = cmd.run_fail(); if output.status().success() { - handle_failed_output(&cmd, output, caller_line_number); + handle_failed_output(&cmd, output, caller.line()); } output } -/// Create a new custom Command. -/// This should be preferred to creating `std::process::Command` directly. +/// Create a new custom [`Command`]. This should be preferred to creating [`std::process::Command`] +/// directly. +#[track_caller] pub fn cmd>(program: S) -> Command { let mut command = Command::new(program); set_host_rpath(&mut command); diff --git a/src/tools/run-make-support/src/rustc.rs b/src/tools/run-make-support/src/rustc.rs index 5ea231442bc..32fa5018d80 100644 --- a/src/tools/run-make-support/src/rustc.rs +++ b/src/tools/run-make-support/src/rustc.rs @@ -5,11 +5,13 @@ use std::path::Path; use crate::{command, cwd, env_var, set_host_rpath}; /// Construct a new `rustc` invocation. +#[track_caller] pub fn rustc() -> Rustc { Rustc::new() } /// Construct a new `rustc` aux-build invocation. +#[track_caller] pub fn aux_build() -> Rustc { Rustc::new_aux_build() } @@ -22,6 +24,7 @@ pub struct Rustc { crate::impl_common_helpers!(Rustc); +#[track_caller] fn setup_common() -> Command { let rustc = env_var("RUSTC"); let mut cmd = Command::new(rustc); @@ -34,12 +37,14 @@ impl Rustc { // `rustc` invocation constructor methods /// Construct a new `rustc` invocation. + #[track_caller] pub fn new() -> Self { let cmd = setup_common(); Self { cmd } } /// Construct a new `rustc` invocation with `aux_build` preset (setting `--crate-type=lib`). + #[track_caller] pub fn new_aux_build() -> Self { let mut cmd = setup_common(); cmd.arg("--crate-type=lib"); diff --git a/src/tools/run-make-support/src/rustdoc.rs b/src/tools/run-make-support/src/rustdoc.rs index 39a698a47b4..332906f739a 100644 --- a/src/tools/run-make-support/src/rustdoc.rs +++ b/src/tools/run-make-support/src/rustdoc.rs @@ -5,11 +5,13 @@ use crate::command::Command; use crate::{env_var, env_var_os, set_host_rpath}; /// Construct a plain `rustdoc` invocation with no flags set. +#[track_caller] pub fn bare_rustdoc() -> Rustdoc { Rustdoc::bare() } /// Construct a new `rustdoc` invocation with `-L $(TARGET_RPATH_DIR)` set. +#[track_caller] pub fn rustdoc() -> Rustdoc { Rustdoc::new() } @@ -21,6 +23,7 @@ pub struct Rustdoc { crate::impl_common_helpers!(Rustdoc); +#[track_caller] fn setup_common() -> Command { let rustdoc = env_var("RUSTDOC"); let mut cmd = Command::new(rustdoc); @@ -30,12 +33,14 @@ fn setup_common() -> Command { impl Rustdoc { /// Construct a bare `rustdoc` invocation. + #[track_caller] pub fn bare() -> Self { let cmd = setup_common(); Self { cmd } } /// Construct a `rustdoc` invocation with `-L $(TARGET_RPATH_DIR)` set. + #[track_caller] pub fn new() -> Self { let mut cmd = setup_common(); let target_rpath_dir = env_var_os("TARGET_RPATH_DIR"); From ca95f783c1cb84ea5739681ba284eccbb41ebf6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= Date: Sun, 9 Jun 2024 15:45:57 +0000 Subject: [PATCH 4/6] tests/run-make: update tests to use new API --- tests/run-make/compiler-builtins/rmake.rs | 2 +- tests/run-make/rustdoc-map-file/rmake.rs | 2 +- tests/run-make/rustdoc-scrape-examples-macros/rmake.rs | 2 +- tests/run-make/rustdoc-scrape-examples-remap/scrape.rs | 2 +- tests/run-make/rustdoc-themes/rmake.rs | 2 +- tests/run-make/rustdoc-with-out-dir-option/rmake.rs | 2 +- tests/run-make/rustdoc-with-output-option/rmake.rs | 2 +- tests/run-make/rustdoc-with-short-out-dir-option/rmake.rs | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/run-make/compiler-builtins/rmake.rs b/tests/run-make/compiler-builtins/rmake.rs index a2c0ad5f6de..a102e5b3390 100644 --- a/tests/run-make/compiler-builtins/rmake.rs +++ b/tests/run-make/compiler-builtins/rmake.rs @@ -35,7 +35,7 @@ fn main() { let rustc = env_var("RUSTC"); let bootstrap_cargo = env_var("BOOTSTRAP_CARGO"); let mut cmd = cmd(bootstrap_cargo); - cmd.args([ + cmd.args(&[ "build", "--manifest-path", manifest_path.to_str().unwrap(), diff --git a/tests/run-make/rustdoc-map-file/rmake.rs b/tests/run-make/rustdoc-map-file/rmake.rs index de75561c9fb..08f9595ef9f 100644 --- a/tests/run-make/rustdoc-map-file/rmake.rs +++ b/tests/run-make/rustdoc-map-file/rmake.rs @@ -9,5 +9,5 @@ fn main() { .output(&out_dir) .run(); // FIXME (GuillaumeGomez): Port the python script to Rust as well. - assert!(python_command().arg("validate_json.py").arg(&out_dir).status().unwrap().success()); + python_command().arg("validate_json.py").arg(&out_dir).run(); } diff --git a/tests/run-make/rustdoc-scrape-examples-macros/rmake.rs b/tests/run-make/rustdoc-scrape-examples-macros/rmake.rs index c9650def347..bfe4a1df456 100644 --- a/tests/run-make/rustdoc-scrape-examples-macros/rmake.rs +++ b/tests/run-make/rustdoc-scrape-examples-macros/rmake.rs @@ -56,5 +56,5 @@ fn main() { .arg(&ex_dir) .run(); - assert!(htmldocck().arg(out_dir).arg("src/lib.rs").status().unwrap().success()); + htmldocck().arg(out_dir).arg("src/lib.rs").run(); } diff --git a/tests/run-make/rustdoc-scrape-examples-remap/scrape.rs b/tests/run-make/rustdoc-scrape-examples-remap/scrape.rs index 41efb837458..6bf48a94a49 100644 --- a/tests/run-make/rustdoc-scrape-examples-remap/scrape.rs +++ b/tests/run-make/rustdoc-scrape-examples-remap/scrape.rs @@ -45,5 +45,5 @@ pub fn scrape(extra_args: &[&str]) { } rustdoc.run(); - assert!(htmldocck().arg(out_dir).arg("src/lib.rs").status().unwrap().success()); + htmldocck().arg(out_dir).arg("src/lib.rs").run(); } diff --git a/tests/run-make/rustdoc-themes/rmake.rs b/tests/run-make/rustdoc-themes/rmake.rs index c28821b7628..bfda2d97888 100644 --- a/tests/run-make/rustdoc-themes/rmake.rs +++ b/tests/run-make/rustdoc-themes/rmake.rs @@ -28,5 +28,5 @@ fn main() { std::fs::write(&test_css, test_content).unwrap(); rustdoc().output(&out_dir).input("foo.rs").arg("--theme").arg(&test_css).run(); - assert!(htmldocck().arg(out_dir).arg("foo.rs").status().unwrap().success()); + htmldocck().arg(out_dir).arg("foo.rs").run(); } diff --git a/tests/run-make/rustdoc-with-out-dir-option/rmake.rs b/tests/run-make/rustdoc-with-out-dir-option/rmake.rs index 405da8412ae..ded89c9ae79 100644 --- a/tests/run-make/rustdoc-with-out-dir-option/rmake.rs +++ b/tests/run-make/rustdoc-with-out-dir-option/rmake.rs @@ -3,5 +3,5 @@ use run_make_support::{htmldocck, rustdoc}; fn main() { let out_dir = "rustdoc"; rustdoc().input("src/lib.rs").crate_name("foobar").crate_type("lib").output(&out_dir).run(); - assert!(htmldocck().arg(out_dir).arg("src/lib.rs").status().unwrap().success()); + htmldocck().arg(out_dir).arg("src/lib.rs").run(); } diff --git a/tests/run-make/rustdoc-with-output-option/rmake.rs b/tests/run-make/rustdoc-with-output-option/rmake.rs index a3b1c8ca0dd..f7fbbec6986 100644 --- a/tests/run-make/rustdoc-with-output-option/rmake.rs +++ b/tests/run-make/rustdoc-with-output-option/rmake.rs @@ -12,5 +12,5 @@ fn main() { .arg(&out_dir) .run(); - assert!(htmldocck().arg(out_dir).arg("src/lib.rs").status().unwrap().success()); + htmldocck().arg(out_dir).arg("src/lib.rs").run(); } diff --git a/tests/run-make/rustdoc-with-short-out-dir-option/rmake.rs b/tests/run-make/rustdoc-with-short-out-dir-option/rmake.rs index b536fbe2303..4a8896cc975 100644 --- a/tests/run-make/rustdoc-with-short-out-dir-option/rmake.rs +++ b/tests/run-make/rustdoc-with-short-out-dir-option/rmake.rs @@ -12,5 +12,5 @@ fn main() { .arg(&out_dir) .run(); - assert!(htmldocck().arg(out_dir).arg("src/lib.rs").status().unwrap().success()); + htmldocck().arg(out_dir).arg("src/lib.rs").run(); } From d308a70890b66a6e81bfc46286caed915a34c8f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= Date: Sun, 9 Jun 2024 14:10:55 +0000 Subject: [PATCH 5/6] run-make-support: bump version --- Cargo.lock | 2 +- src/tools/run-make-support/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ba8b2c27005..e5ea9fee8a6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3452,7 +3452,7 @@ dependencies = [ [[package]] name = "run_make_support" -version = "0.0.0" +version = "0.1.0" dependencies = [ "gimli 0.28.1", "object 0.34.0", diff --git a/src/tools/run-make-support/Cargo.toml b/src/tools/run-make-support/Cargo.toml index cf4ae4b16cd..5450620e7f0 100644 --- a/src/tools/run-make-support/Cargo.toml +++ b/src/tools/run-make-support/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "run_make_support" -version = "0.0.0" +version = "0.1.0" edition = "2021" [dependencies] From 5ec3eef9e70551a7eef059cfc9d039f053805cab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= Date: Sun, 9 Jun 2024 14:11:12 +0000 Subject: [PATCH 6/6] run-make-support: add changelog --- src/tools/run-make-support/CHANGELOG.md | 67 +++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 src/tools/run-make-support/CHANGELOG.md diff --git a/src/tools/run-make-support/CHANGELOG.md b/src/tools/run-make-support/CHANGELOG.md new file mode 100644 index 00000000000..a37de9fda80 --- /dev/null +++ b/src/tools/run-make-support/CHANGELOG.md @@ -0,0 +1,67 @@ +# Changelog + +All notable changes to the `run_make_support` library should be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and the support +library should adhere to [Semantic Versioning](https://semver.org/spec/v2.0.0.html) even if it's +not intended for public consumption (it's moreso to help internally, to help test writers track +changes to the support library). + +This support library will probably never reach 1.0. Please bump the minor version in `Cargo.toml` if +you make any breaking changes or other significant changes, or bump the patch version for bug fixes. + +## [0.1.0] - 2024-06-09 + +### Changed + +- Use *drop bombs* to enforce that commands are executed; a command invocation will panic if it is + constructed but never executed. Execution methods `Command::{run, run_fail}` will defuse the drop + bomb. +- Added `Command` helpers that forward to `std::process::Command` counterparts. + +### Removed + +- The `env_var` method which was incorrectly named and is `env_clear` underneath and is a footgun + from `impl_common_helpers`. For example, removing `TMPDIR` on Unix and `TMP`/`TEMP` breaks + `std::env::temp_dir` and wrecks anything using that, such as rustc's codgen. +- Removed `Deref`/`DerefMut` for `run_make_support::Command` -> `std::process::Command` because it + causes a method chain like `htmldocck().arg().run()` to fail, because `arg()` resolves to + `std::process::Command` which also returns a `&mut std::process::Command`, causing the `run()` to + be not found. + +## [0.0.0] - 2024-06-09 + +Consider this version to contain all changes made to the support library before we started to track +changes in this changelog. + +### Added + +- Custom command wrappers around `std::process::Command` (`run_make_support::Command`) and custom + wrapper around `std::process::Output` (`CompletedProcess`) to make it more convenient to work with + commands and their output, and help avoid forgetting to check for exit status. + - `Command`: `set_stdin`, `run`, `run_fail`. + - `CompletedProcess`: `std{err,out}_utf8`, `status`, `assert_std{err,out}_{equals, contains, + not_contains}`, `assert_exit_code`. +- `impl_common_helpers` macro to avoid repeating adding common convenience methods, including: + - Environment manipulation methods: `env`, `env_remove` + - Command argument providers: `arg`, `args` + - Common invocation inspection (of the command invocation up until `inspect` is called): + `inspect` + - Execution methods: `run` (for commands expected to succeed execution, exit status `0`) and + `run_fail` (for commands expected to fail execution, exit status non-zero). +- Command wrappers around: `rustc`, `clang`, `cc`, `rustc`, `rustdoc`, `llvm-readobj`. +- Thin helpers to construct `python` and `htmldocck` commands. +- `run` and `run_fail` (like `Command::{run, run_fail}`) for running binaries, which sets suitable + env vars (like `LD_LIB_PATH` or equivalent, `TARGET_RPATH_ENV`, `PATH` on Windows). +- Pseudo command `diff` which has similar functionality as the cli util but not the same API. +- Convenience panic-on-fail helpers `env_var`, `env_var_os`, `cwd` for their `std::env` conterparts. +- Convenience panic-on-fail helpers for reading respective env vars: `target`, `source_root`. +- Platform check helpers: `is_windows`, `is_msvc`, `cygpath_windows`, `uname`. +- fs helpers: `copy_dir_all`. +- `recursive_diff` helper. +- Generic `assert_not_contains` helper. +- Scoped run-with-teardown helper `run_in_tmpdir` which is designed to run commands in a temporary + directory that is cleared when closure returns. +- Helpers for constructing the name of binaries and libraries: `rust_lib_name`, `static_lib_name`, + `bin_name`, `dynamic_lib_name`. +- Re-export libraries: `gimli`, `object`, `regex`, `wasmparsmer`.