diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index b20c20a360b9..7c052f262d86 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -39,11 +39,8 @@ use crate::core::config::flags; use crate::core::config::{DryRun, Target}; use crate::core::config::{LlvmLibunwind, TargetSelection}; use crate::utils::cache::{Interned, INTERNER}; -use crate::utils::exec::BootstrapCommand; -use crate::utils::helpers::{ - self, dir_is_empty, exe, libdir, mtime, output, run, run_suppressed, symlink_dir, - try_run_suppressed, -}; +use crate::utils::exec::{BehaviorOnFailure, BootstrapCommand}; +use crate::utils::helpers::{self, dir_is_empty, exe, libdir, mtime, output, symlink_dir}; mod core; mod utils; @@ -922,44 +919,30 @@ impl Build { /// Runs a command, printing out nice contextual information if it fails. fn run(&self, cmd: &mut Command) { - if self.config.dry_run() { - return; - } - self.verbose(&format!("running: {cmd:?}")); - run(cmd, self.is_verbose()) + // FIXME: output mode -> status + err if self.is_verbose() + let cmd: BootstrapCommand<'_> = cmd.into(); + self.run_cmd(cmd.fail_fast()); } /// Runs a command, printing out nice contextual information if it fails. fn run_quiet(&self, cmd: &mut Command) { - if self.config.dry_run() { - return; - } - self.verbose(&format!("running: {cmd:?}")); - run_suppressed(cmd) + // FIXME: output mode -> output + err + let cmd: BootstrapCommand<'_> = cmd.into(); + self.run_cmd(cmd.fail_fast()); } /// Runs a command, printing out nice contextual information if it fails. /// Exits if the command failed to execute at all, otherwise returns its /// `status.success()`. fn run_quiet_delaying_failure(&self, cmd: &mut Command) -> bool { - if self.config.dry_run() { - return true; - } - if !self.fail_fast { - self.verbose(&format!("running: {cmd:?}")); - if !try_run_suppressed(cmd) { - let mut failures = self.delayed_failures.borrow_mut(); - failures.push(format!("{cmd:?}")); - return false; - } - } else { - self.run_quiet(cmd); - } - true + // FIXME: output mode -> output + err + let cmd: BootstrapCommand<'_> = cmd.into(); + self.run_cmd(cmd.delay_failure()) } /// Runs a command, printing out contextual info if it fails, and delaying errors until the build finishes. pub(crate) fn run_delaying_failure(&self, cmd: &mut Command) -> bool { + // FIXME: output mode -> status + err if self.is_verbose() let cmd: BootstrapCommand<'_> = cmd.into(); self.run_cmd(cmd.delay_failure()) } @@ -975,10 +958,16 @@ impl Build { match result { Ok(_) => true, Err(_) => { - if command.delay_failure { - let mut failures = self.delayed_failures.borrow_mut(); - failures.push(format!("{command:?}")); - return false; + if let Some(failure_behavior) = command.failure_behavior { + match failure_behavior { + BehaviorOnFailure::DelayFail => { + let mut failures = self.delayed_failures.borrow_mut(); + failures.push(format!("{command:?}")); + } + BehaviorOnFailure::Exit => { + exit!(1); + } + } } if self.fail_fast { exit!(1); diff --git a/src/bootstrap/src/utils/exec.rs b/src/bootstrap/src/utils/exec.rs index a590171984e3..a2a0dbad240e 100644 --- a/src/bootstrap/src/utils/exec.rs +++ b/src/bootstrap/src/utils/exec.rs @@ -1,21 +1,32 @@ use std::process::Command; +/// What should be done when the command fails. +#[derive(Debug, Copy, Clone)] +pub enum BehaviorOnFailure { + /// Immediately stop bootstrap. + Exit, + /// Delay failure until the end of bootstrap invocation. + DelayFail, +} + /// Wrapper around `std::process::Command`. #[derive(Debug)] pub struct BootstrapCommand<'a> { pub command: &'a mut Command, - /// Report failure later instead of immediately. - pub delay_failure: bool, + pub failure_behavior: Option, } impl<'a> BootstrapCommand<'a> { pub fn delay_failure(self) -> Self { - Self { delay_failure: true, ..self } + Self { failure_behavior: Some(BehaviorOnFailure::DelayFail), ..self } + } + pub fn fail_fast(self) -> Self { + Self { failure_behavior: Some(BehaviorOnFailure::Exit), ..self } } } impl<'a> From<&'a mut Command> for BootstrapCommand<'a> { fn from(command: &'a mut Command) -> Self { - Self { command, delay_failure: false } + Self { command, failure_behavior: None } } }