diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index bfd0e42acfd32..1e2e90105a9a9 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -1056,11 +1056,29 @@ Executed at: {executed_at}"#, } }; - let fail = |message: &str| { + let fail = |message: &str, output: CommandOutput| -> ! { if self.is_verbose() { println!("{message}"); } else { - println!("Command has failed. Rerun with -v to see more details."); + let (stdout, stderr) = (output.stdout_if_present(), output.stderr_if_present()); + // If the command captures output, the user would not see any indication that + // it has failed. In this case, print a more verbose error, since to provide more + // context. + if stdout.is_some() || stderr.is_some() { + if let Some(stdout) = + output.stdout_if_present().take_if(|s| !s.trim().is_empty()) + { + println!("STDOUT:\n{stdout}\n"); + } + if let Some(stderr) = + output.stderr_if_present().take_if(|s| !s.trim().is_empty()) + { + println!("STDERR:\n{stderr}\n"); + } + println!("Command {command:?} has failed. Rerun with -v to see more details."); + } else { + println!("Command has failed. Rerun with -v to see more details."); + } } exit!(1); }; @@ -1069,14 +1087,14 @@ Executed at: {executed_at}"#, match command.failure_behavior { BehaviorOnFailure::DelayFail => { if self.fail_fast { - fail(&message); + fail(&message, output); } let mut failures = self.delayed_failures.borrow_mut(); failures.push(message); } BehaviorOnFailure::Exit => { - fail(&message); + fail(&message, output); } BehaviorOnFailure::Ignore => { // If failures are allowed, either the error has been printed already diff --git a/src/bootstrap/src/utils/exec.rs b/src/bootstrap/src/utils/exec.rs index 9f0d0b7e9691f..530d760a584c8 100644 --- a/src/bootstrap/src/utils/exec.rs +++ b/src/bootstrap/src/utils/exec.rs @@ -291,6 +291,11 @@ impl CommandOutput { .expect("Cannot parse process stdout as UTF-8") } + #[must_use] + pub fn stdout_if_present(&self) -> Option { + self.stdout.as_ref().and_then(|s| String::from_utf8(s.clone()).ok()) + } + #[must_use] pub fn stdout_if_ok(&self) -> Option { if self.is_success() { Some(self.stdout()) } else { None } @@ -303,6 +308,11 @@ impl CommandOutput { ) .expect("Cannot parse process stderr as UTF-8") } + + #[must_use] + pub fn stderr_if_present(&self) -> Option { + self.stderr.as_ref().and_then(|s| String::from_utf8(s.clone()).ok()) + } } impl Default for CommandOutput {