-
Notifications
You must be signed in to change notification settings - Fork 12.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Auto merge of #125752 - jieyouxu:kaboom, r=Kobzol
run-make: arm command wrappers with drop bombs This PR is one in a series of cleanups to run-make tests and the run-make-support library. ### Summary It's easy to forget to actually executed constructed command wrappers, e.g. `rustc().input("foo.rs")` but forget the `run()`, so to help catch these mistakes, we arm command wrappers with drop bombs on construction to force them to be executed by test code. This PR also removes the `Deref`/`DerefMut` impl for our custom `Command` which derefs to `std::process::Command` because it can cause issues when trying to use a custom command: ```rs htmldocck().arg().run() ``` fails to compile because the `arg()` is resolved to `std::process::Command::arg`, which returns `&mut std::process::Command` that doesn't have a `run()` command. This PR also: - Removes `env_var` on the `impl_common_helper` macro that was wrongly named and is a footgun (no users). - Bumps the run-make-support library to version `0.1.0`. - Adds a changelog to the support library. ### Details Especially for command wrappers like `Rustc`, it's very easy to build up a command invocation but forget to actually execute it, e.g. by using `run()`. This commit adds "drop bombs" to command wrappers, which are armed on command wrapper construction, and only defused if the command is executed (through `run`, `run_fail`). If the test writer forgets to execute the command, the drop bomb will "explode" and panic with an error message. This is so that tests don't silently pass with constructed-but-not-executed command wrappers. This PR is best reviewed commit-by-commit. try-job: x86_64-msvc
- Loading branch information
Showing
22 changed files
with
280 additions
and
80 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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`. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
[package] | ||
name = "run_make_support" | ||
version = "0.0.0" | ||
version = "0.1.0" | ||
edition = "2021" | ||
|
||
[dependencies] | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 <https://docs.rs/drop_bomb/latest/drop_bomb/> 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<S: AsRef<OsStr>>(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() | ||
) | ||
} | ||
} | ||
} |
Oops, something went wrong.