Skip to content

Commit 7efe8fa

Browse files
committed
Add output mode to BootstrapCommand
1 parent 0e090e7 commit 7efe8fa

File tree

3 files changed

+76
-54
lines changed

3 files changed

+76
-54
lines changed

src/bootstrap/src/lib.rs

+58-20
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,12 @@ use std::fmt::Display;
2323
use std::fs::{self, File};
2424
use std::io;
2525
use std::path::{Path, PathBuf};
26-
use std::process::{Command, Stdio};
26+
use std::process::{Command, Output, Stdio};
2727
use std::str;
2828

2929
use build_helper::ci::{gha, CiEnv};
3030
use build_helper::exit;
31+
use build_helper::util::fail;
3132
use filetime::FileTime;
3233
use once_cell::sync::OnceCell;
3334
use termcolor::{ColorChoice, StandardStream, WriteColor};
@@ -39,7 +40,7 @@ use crate::core::config::flags;
3940
use crate::core::config::{DryRun, Target};
4041
use crate::core::config::{LlvmLibunwind, TargetSelection};
4142
use crate::utils::cache::{Interned, INTERNER};
42-
use crate::utils::exec::{BehaviorOnFailure, BootstrapCommand};
43+
use crate::utils::exec::{BehaviorOnFailure, BootstrapCommand, OutputMode};
4344
use crate::utils::helpers::{self, dir_is_empty, exe, libdir, mtime, output, symlink_dir};
4445

4546
mod core;
@@ -919,41 +920,78 @@ impl Build {
919920

920921
/// Runs a command, printing out nice contextual information if it fails.
921922
fn run(&self, cmd: &mut Command) {
922-
// FIXME: output mode -> status + err if self.is_verbose()
923-
let cmd: BootstrapCommand<'_> = cmd.into();
924-
self.run_cmd(cmd.fail_fast());
923+
self.run_cmd(BootstrapCommand::from(cmd).fail_fast().output_mode(
924+
match self.is_verbose() {
925+
true => OutputMode::PrintAll,
926+
false => OutputMode::PrintOutput,
927+
},
928+
));
929+
}
930+
931+
/// Runs a command, printing out contextual info if it fails, and delaying errors until the build finishes.
932+
pub(crate) fn run_delaying_failure(&self, cmd: &mut Command) -> bool {
933+
self.run_cmd(BootstrapCommand::from(cmd).delay_failure().output_mode(
934+
match self.is_verbose() {
935+
true => OutputMode::PrintAll,
936+
false => OutputMode::PrintOutput,
937+
},
938+
))
925939
}
926940

927941
/// Runs a command, printing out nice contextual information if it fails.
928942
fn run_quiet(&self, cmd: &mut Command) {
929-
// FIXME: output mode -> output + err
930-
let cmd: BootstrapCommand<'_> = cmd.into();
931-
self.run_cmd(cmd.fail_fast());
943+
self.run_cmd(BootstrapCommand::from(cmd).fail_fast().output_mode(OutputMode::Suppress));
932944
}
933945

934946
/// Runs a command, printing out nice contextual information if it fails.
935947
/// Exits if the command failed to execute at all, otherwise returns its
936948
/// `status.success()`.
937949
fn run_quiet_delaying_failure(&self, cmd: &mut Command) -> bool {
938-
// FIXME: output mode -> output + err
939-
let cmd: BootstrapCommand<'_> = cmd.into();
940-
self.run_cmd(cmd.delay_failure())
941-
}
942-
943-
/// Runs a command, printing out contextual info if it fails, and delaying errors until the build finishes.
944-
pub(crate) fn run_delaying_failure(&self, cmd: &mut Command) -> bool {
945-
// FIXME: output mode -> status + err if self.is_verbose()
946-
let cmd: BootstrapCommand<'_> = cmd.into();
947-
self.run_cmd(cmd.delay_failure())
950+
self.run_cmd(BootstrapCommand::from(cmd).delay_failure().output_mode(OutputMode::Suppress))
948951
}
949952

950953
/// A centralized function for running commands that do not return output.
951954
pub(crate) fn run_cmd<'a, C: Into<BootstrapCommand<'a>>>(&self, cmd: C) -> bool {
955+
if self.config.dry_run() {
956+
return true;
957+
}
958+
952959
let command = cmd.into();
953960
self.verbose(&format!("running: {command:?}"));
954961

955-
#[allow(deprecated)] // can't use Build::try_run, that's us
956-
let result = self.config.try_run(command.command);
962+
let (output, print_error) = match command.output_mode {
963+
mode @ (OutputMode::PrintAll | OutputMode::PrintOutput) => (
964+
command.command.status().map(|status| Output {
965+
status,
966+
stdout: Vec::new(),
967+
stderr: Vec::new(),
968+
}),
969+
matches!(mode, OutputMode::PrintAll),
970+
),
971+
OutputMode::Suppress => (command.command.output(), true),
972+
};
973+
974+
let output = match output {
975+
Ok(output) => output,
976+
Err(e) => fail(&format!("failed to execute command: {:?}\nerror: {}", command, e)),
977+
};
978+
let result = if !output.status.success() {
979+
if print_error {
980+
println!(
981+
"\n\ncommand did not execute successfully: {:?}\n\
982+
expected success, got: {}\n\n\
983+
stdout ----\n{}\n\
984+
stderr ----\n{}\n\n",
985+
command.command,
986+
output.status,
987+
String::from_utf8_lossy(&output.stdout),
988+
String::from_utf8_lossy(&output.stderr)
989+
);
990+
}
991+
Err(())
992+
} else {
993+
Ok(())
994+
};
957995

958996
match result {
959997
Ok(_) => true,

src/bootstrap/src/utils/exec.rs

+17-1
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,24 @@ pub enum BehaviorOnFailure {
99
DelayFail,
1010
}
1111

12+
/// How should the output of the command be handled.
13+
#[derive(Debug, Copy, Clone)]
14+
pub enum OutputMode {
15+
/// Print both the output (by inheriting stdout/stderr) and also the command itself, if it
16+
/// fails.
17+
PrintAll,
18+
/// Print the output (by inheriting stdout/stderr).
19+
PrintOutput,
20+
/// Suppress the output if the command succeeds, otherwise print the output.
21+
Suppress,
22+
}
23+
1224
/// Wrapper around `std::process::Command`.
1325
#[derive(Debug)]
1426
pub struct BootstrapCommand<'a> {
1527
pub command: &'a mut Command,
1628
pub failure_behavior: Option<BehaviorOnFailure>,
29+
pub output_mode: OutputMode,
1730
}
1831

1932
impl<'a> BootstrapCommand<'a> {
@@ -23,10 +36,13 @@ impl<'a> BootstrapCommand<'a> {
2336
pub fn fail_fast(self) -> Self {
2437
Self { failure_behavior: Some(BehaviorOnFailure::Exit), ..self }
2538
}
39+
pub fn output_mode(self, output_mode: OutputMode) -> Self {
40+
Self { output_mode, ..self }
41+
}
2642
}
2743

2844
impl<'a> From<&'a mut Command> for BootstrapCommand<'a> {
2945
fn from(command: &'a mut Command) -> Self {
30-
Self { command, failure_behavior: None }
46+
Self { command, failure_behavior: None, output_mode: OutputMode::Suppress }
3147
}
3248
}

src/bootstrap/src/utils/helpers.rs

+1-33
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
//! Simple things like testing the various filesystem operations here and there,
44
//! not a lot of interesting happenings here unfortunately.
55
6-
use build_helper::util::{fail, try_run};
6+
use build_helper::util::fail;
77
use std::env;
88
use std::fs;
99
use std::io;
@@ -216,12 +216,6 @@ pub fn is_valid_test_suite_arg<'a, P: AsRef<Path>>(
216216
}
217217
}
218218

219-
pub fn run(cmd: &mut Command, print_cmd_on_fail: bool) {
220-
if try_run(cmd, print_cmd_on_fail).is_err() {
221-
crate::exit!(1);
222-
}
223-
}
224-
225219
pub fn check_run(cmd: &mut Command, print_cmd_on_fail: bool) -> bool {
226220
let status = match cmd.status() {
227221
Ok(status) => status,
@@ -239,32 +233,6 @@ pub fn check_run(cmd: &mut Command, print_cmd_on_fail: bool) -> bool {
239233
status.success()
240234
}
241235

242-
pub fn run_suppressed(cmd: &mut Command) {
243-
if !try_run_suppressed(cmd) {
244-
crate::exit!(1);
245-
}
246-
}
247-
248-
pub fn try_run_suppressed(cmd: &mut Command) -> bool {
249-
let output = match cmd.output() {
250-
Ok(status) => status,
251-
Err(e) => fail(&format!("failed to execute command: {cmd:?}\nerror: {e}")),
252-
};
253-
if !output.status.success() {
254-
println!(
255-
"\n\ncommand did not execute successfully: {:?}\n\
256-
expected success, got: {}\n\n\
257-
stdout ----\n{}\n\
258-
stderr ----\n{}\n\n",
259-
cmd,
260-
output.status,
261-
String::from_utf8_lossy(&output.stdout),
262-
String::from_utf8_lossy(&output.stderr)
263-
);
264-
}
265-
output.status.success()
266-
}
267-
268236
pub fn make(host: &str) -> PathBuf {
269237
if host.contains("dragonfly")
270238
|| host.contains("freebsd")

0 commit comments

Comments
 (0)