Skip to content

Commit 86f712f

Browse files
committed
Add behavior on failure to BootstrapCommand
1 parent b35c8f5 commit 86f712f

File tree

2 files changed

+36
-18
lines changed

2 files changed

+36
-18
lines changed

src/bootstrap/exec.rs

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,26 +9,34 @@ pub enum OutputOnFailure {
99
Verbose,
1010
}
1111

12+
/// What should be done when the command fails.
13+
#[derive(Debug, Copy, Clone)]
14+
pub enum BehaviorOnFailure {
15+
/// Immediately stop bootstrap
16+
Exit,
17+
/// Delay failure until the end of bootstrap invocation
18+
DelayFail,
19+
}
20+
1221
/// Wrapper around `std::process::Command`.
1322
#[derive(Debug)]
1423
pub struct BootstrapCommand<'a> {
1524
pub command: &'a mut Command,
16-
/// Report failure later instead of immediately.
17-
pub delay_failure: bool,
18-
pub output_on_failure: Option<OutputOnFailure>,
25+
pub failure_behavior: Option<BehaviorOnFailure>,
26+
pub failure_output: Option<OutputOnFailure>,
1927
}
2028

2129
impl<'a> BootstrapCommand<'a> {
22-
pub fn delay_failure(self) -> Self {
23-
Self { delay_failure: true, ..self }
30+
pub fn failure_behavior(self, failure_behavior: BehaviorOnFailure) -> Self {
31+
Self { failure_behavior: Some(failure_behavior), ..self }
2432
}
25-
pub fn output_on_failure(self, output_on_failure: OutputOnFailure) -> Self {
26-
Self { output_on_failure: Some(output_on_failure), ..self }
33+
pub fn failure_output(self, failure_output: OutputOnFailure) -> Self {
34+
Self { failure_output: Some(failure_output), ..self }
2735
}
2836
}
2937

3038
impl<'a> From<&'a mut Command> for BootstrapCommand<'a> {
3139
fn from(command: &'a mut Command) -> Self {
32-
Self { command, delay_failure: false, output_on_failure: None }
40+
Self { command, failure_behavior: None, failure_output: None }
3341
}
3442
}

src/bootstrap/lib.rs

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ mod job {
9090
pub use crate::builder::PathSet;
9191
use crate::cache::{Interned, INTERNER};
9292
pub use crate::config::Config;
93-
use crate::exec::{BootstrapCommand, OutputOnFailure};
93+
use crate::exec::{BehaviorOnFailure, BootstrapCommand, OutputOnFailure};
9494
pub use crate::flags::Subcommand;
9595
use termcolor::{ColorChoice, StandardStream, WriteColor};
9696

@@ -976,22 +976,26 @@ impl Build {
976976
/// Runs a command, printing out nice contextual information if it fails.
977977
fn run_quiet(&self, cmd: &mut Command) {
978978
let cmd: BootstrapCommand<'_> = cmd.into();
979-
// TODO: fail bootstrap immediately if this command fails
980-
self.run_cmd(cmd.output_on_failure(OutputOnFailure::Verbose));
979+
self.run_cmd(
980+
cmd.failure_output(OutputOnFailure::Verbose).failure_behavior(BehaviorOnFailure::Exit),
981+
);
981982
}
982983

983984
/// Runs a command, printing out nice contextual information if it fails.
984985
/// Exits if the command failed to execute at all, otherwise returns its
985986
/// `status.success()`.
986987
fn run_quiet_delaying_failure(&self, cmd: &mut Command) -> bool {
987988
let cmd: BootstrapCommand<'_> = cmd.into();
988-
self.run_cmd(cmd.output_on_failure(OutputOnFailure::Verbose).delay_failure())
989+
self.run_cmd(
990+
cmd.failure_output(OutputOnFailure::Verbose)
991+
.failure_behavior(BehaviorOnFailure::DelayFail),
992+
)
989993
}
990994

991995
/// Runs a command, printing out contextual info if it fails, and delaying errors until the build finishes.
992996
pub(crate) fn run_delaying_failure(&self, cmd: &mut Command) -> bool {
993997
let cmd: BootstrapCommand<'_> = cmd.into();
994-
self.run_cmd(cmd.delay_failure())
998+
self.run_cmd(cmd.failure_behavior(BehaviorOnFailure::DelayFail))
995999
}
9961000

9971001
/// A centralized function for running commands that do not return output.
@@ -1004,7 +1008,7 @@ impl Build {
10041008
Err(e) => fail(&format!("failed to execute command: {:?}\nerror: {}", command, e)),
10051009
};
10061010
let result = if !output.status.success() {
1007-
let output_on_failure = match command.output_on_failure {
1011+
let output_on_failure = match command.failure_output {
10081012
Some(output) => Some(output),
10091013
None if self.is_verbose() => Some(OutputOnFailure::Succint),
10101014
None => None,
@@ -1040,10 +1044,16 @@ impl Build {
10401044
match result {
10411045
Ok(_) => true,
10421046
Err(_) => {
1043-
if command.delay_failure {
1044-
let mut failures = self.delayed_failures.borrow_mut();
1045-
failures.push(format!("{command:?}"));
1046-
return false;
1047+
if let Some(failure_behavior) = command.failure_behavior {
1048+
match failure_behavior {
1049+
BehaviorOnFailure::DelayFail => {
1050+
let mut failures = self.delayed_failures.borrow_mut();
1051+
failures.push(format!("{command:?}"));
1052+
}
1053+
BehaviorOnFailure::Exit => {
1054+
exit!(1);
1055+
}
1056+
}
10471057
}
10481058
if self.fail_fast {
10491059
exit!(1);

0 commit comments

Comments
 (0)