aboutsummaryrefslogtreecommitdiff
path: root/.run/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to '.run/src/lib.rs')
-rw-r--r--.run/src/lib.rs35
1 files changed, 30 insertions, 5 deletions
diff --git a/.run/src/lib.rs b/.run/src/lib.rs
index cff606a..b17a61f 100644
--- a/.run/src/lib.rs
+++ b/.run/src/lib.rs
@@ -3,6 +3,8 @@ pub mod verify;
use colored::Colorize;
+use std::io::IsTerminal as _;
+
#[macro_export]
macro_rules! run_cmd {
($fmt:literal, $($arg:tt)*) => {
@@ -201,7 +203,15 @@ pub fn run_cmd_capture_with_dir(
let exit_code = output.status.code().unwrap_or(1);
let stderr = String::from_utf8_lossy(&output.stderr).to_string();
let stdout = String::from_utf8_lossy(&output.stdout).to_string();
- let combined = if stderr.is_empty() { stdout } else { stderr };
+ // Keep both streams so a failure is never hidden: when stderr carries
+ // warnings, the real failure details (e.g. the failing test name and
+ // assertion diff) usually live on stdout and must not be dropped.
+ let combined = match (stdout.trim().is_empty(), stderr.trim().is_empty()) {
+ (false, false) => format!("{stdout}\n{stderr}"),
+ (false, true) => stdout,
+ (true, false) => stderr,
+ (true, true) => stdout,
+ };
if exit_code == 0 {
Ok(combined)
@@ -275,15 +285,30 @@ pub fn run_parallel(phase: &str, tasks: Vec<(String, String, String)>) -> Result
if first_exit_code == 0 {
first_exit_code = code;
}
- pb.println(format!(
+ let msg = format!(
"{}: {} failed (exit code {})",
"error".bright_red().bold(),
labels[i],
code,
- ));
+ );
+ let mut lines = Vec::new();
if !output.is_empty() {
- for line in output.lines() {
- pb.println(format!(" {line}"));
+ lines.extend(output.lines().map(|l| format!(" {l}")));
+ }
+ if std::io::stdout().is_terminal() {
+ // On a TTY, render errors through the progress bar so they
+ // appear above it.
+ pb.println(&msg);
+ for line in &lines {
+ pb.println(line);
+ }
+ } else {
+ // On a non-TTY (CI, piped output), `ProgressBar::println` can
+ // be swallowed, hiding the failure. Emit to plain stdout so the
+ // failure is always visible.
+ println!("{msg}");
+ for line in &lines {
+ println!("{line}");
}
}
}