Skip to content

Commit 19e32bf

Browse files
authored
Rollup merge of #129096 - Kobzol:bootstrap-cmd-verbosity, r=onur-ozkan
Print more verbose error for commands that capture output #128874 made bootstrap command errors less verbose without `-v`. However, in some cases it's too extreme. If a command fails, it now outputs just `Command has failed. Rerun with -v to see more details.`, without providing any context. I think that I found a reasonable heuristic to figure out when we should print a more verbose error. When the command doesn't capture output, its stdout/stderr is printed, therefore the user sees context about the error. However, when the command captures its output, the user won't see any error message in the output, which is not great. So only in that case, bootstrap now prints a slightly more verbose output (and also prints the captured output). r? `@onur-ozkan`
2 parents 53bf554 + 478d42b commit 19e32bf

File tree

2 files changed

+32
-4
lines changed

2 files changed

+32
-4
lines changed

Diff for: src/bootstrap/src/lib.rs

+22-4
Original file line numberDiff line numberDiff line change
@@ -1056,11 +1056,29 @@ Executed at: {executed_at}"#,
10561056
}
10571057
};
10581058

1059-
let fail = |message: &str| {
1059+
let fail = |message: &str, output: CommandOutput| -> ! {
10601060
if self.is_verbose() {
10611061
println!("{message}");
10621062
} else {
1063-
println!("Command has failed. Rerun with -v to see more details.");
1063+
let (stdout, stderr) = (output.stdout_if_present(), output.stderr_if_present());
1064+
// If the command captures output, the user would not see any indication that
1065+
// it has failed. In this case, print a more verbose error, since to provide more
1066+
// context.
1067+
if stdout.is_some() || stderr.is_some() {
1068+
if let Some(stdout) =
1069+
output.stdout_if_present().take_if(|s| !s.trim().is_empty())
1070+
{
1071+
println!("STDOUT:\n{stdout}\n");
1072+
}
1073+
if let Some(stderr) =
1074+
output.stderr_if_present().take_if(|s| !s.trim().is_empty())
1075+
{
1076+
println!("STDERR:\n{stderr}\n");
1077+
}
1078+
println!("Command {command:?} has failed. Rerun with -v to see more details.");
1079+
} else {
1080+
println!("Command has failed. Rerun with -v to see more details.");
1081+
}
10641082
}
10651083
exit!(1);
10661084
};
@@ -1069,14 +1087,14 @@ Executed at: {executed_at}"#,
10691087
match command.failure_behavior {
10701088
BehaviorOnFailure::DelayFail => {
10711089
if self.fail_fast {
1072-
fail(&message);
1090+
fail(&message, output);
10731091
}
10741092

10751093
let mut failures = self.delayed_failures.borrow_mut();
10761094
failures.push(message);
10771095
}
10781096
BehaviorOnFailure::Exit => {
1079-
fail(&message);
1097+
fail(&message, output);
10801098
}
10811099
BehaviorOnFailure::Ignore => {
10821100
// If failures are allowed, either the error has been printed already

Diff for: src/bootstrap/src/utils/exec.rs

+10
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,11 @@ impl CommandOutput {
291291
.expect("Cannot parse process stdout as UTF-8")
292292
}
293293

294+
#[must_use]
295+
pub fn stdout_if_present(&self) -> Option<String> {
296+
self.stdout.as_ref().and_then(|s| String::from_utf8(s.clone()).ok())
297+
}
298+
294299
#[must_use]
295300
pub fn stdout_if_ok(&self) -> Option<String> {
296301
if self.is_success() { Some(self.stdout()) } else { None }
@@ -303,6 +308,11 @@ impl CommandOutput {
303308
)
304309
.expect("Cannot parse process stderr as UTF-8")
305310
}
311+
312+
#[must_use]
313+
pub fn stderr_if_present(&self) -> Option<String> {
314+
self.stderr.as_ref().and_then(|s| String::from_utf8(s.clone()).ok())
315+
}
306316
}
307317

308318
impl Default for CommandOutput {

0 commit comments

Comments
 (0)