mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-07 04:23:30 +00:00
run_make_support: make each command invocation only-run-once
This commit is contained in:
parent
afed862b26
commit
8871ce0e1f
@ -15,7 +15,7 @@ use crate::{
|
||||
/// 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`] must be executed exactly once
|
||||
///
|
||||
/// 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
|
||||
@ -23,6 +23,12 @@ use crate::{
|
||||
/// containing constructed but never executed commands is dangerous because it can give a false
|
||||
/// sense of confidence.
|
||||
///
|
||||
/// Each [`Command`] invocation can also only be executed once, because we want to enforce
|
||||
/// `std{in,out,err}` config via [`std::process::Stdio`] but [`std::process::Stdio`] is not
|
||||
/// cloneable.
|
||||
///
|
||||
/// In this sense, [`Command`] exhibits linear type semantics but enforced at run-time.
|
||||
///
|
||||
/// [`run`]: Self::run
|
||||
/// [`run_fail`]: Self::run_fail
|
||||
/// [`run_unchecked`]: Self::run_unchecked
|
||||
@ -37,7 +43,9 @@ pub struct Command {
|
||||
stdout: Option<Stdio>,
|
||||
stderr: Option<Stdio>,
|
||||
|
||||
// Emulate linear type semantics.
|
||||
drop_bomb: DropBomb,
|
||||
already_executed: bool,
|
||||
}
|
||||
|
||||
impl Command {
|
||||
@ -51,6 +59,7 @@ impl Command {
|
||||
stdin: None,
|
||||
stdout: None,
|
||||
stderr: None,
|
||||
already_executed: false,
|
||||
}
|
||||
}
|
||||
|
||||
@ -177,6 +186,12 @@ impl Command {
|
||||
|
||||
#[track_caller]
|
||||
fn command_output(&mut self) -> CompletedProcess {
|
||||
if self.already_executed {
|
||||
panic!("command was already executed");
|
||||
} else {
|
||||
self.already_executed = true;
|
||||
}
|
||||
|
||||
self.drop_bomb.defuse();
|
||||
// let's make sure we piped all the input and outputs
|
||||
self.cmd.stdin(self.stdin.take().unwrap_or(Stdio::piped()));
|
||||
|
Loading…
Reference in New Issue
Block a user