Skip to content

Commit 3c01747

Browse files
committed
Add output mode to BootstrapCommand
1 parent cfcb860 commit 3c01747

File tree

3 files changed

+77
-55
lines changed

3 files changed

+77
-55
lines changed

src/bootstrap/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/lib.rs

+59-21
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};
@@ -40,9 +41,9 @@ pub use crate::builder::PathSet;
4041
use crate::cache::{Interned, INTERNER};
4142
pub use crate::config::Config;
4243
use crate::config::{LlvmLibunwind, TargetSelection};
43-
use crate::exec::{BehaviorOnFailure, BootstrapCommand};
44+
use crate::exec::{BehaviorOnFailure, BootstrapCommand, OutputMode};
4445
pub use crate::flags::Subcommand;
45-
use crate::util::{dir_is_empty, exe, libdir, mtime, output, run, symlink_dir};
46+
use crate::util::{dir_is_empty, exe, libdir, mtime, output, symlink_dir};
4647

4748
mod builder;
4849
mod cache;
@@ -965,41 +966,78 @@ impl Build {
965966

966967
/// Runs a command, printing out nice contextual information if it fails.
967968
fn run(&self, cmd: &mut Command) {
968-
// FIXME: output mode -> status + err if self.is_verbose()
969-
let cmd: BootstrapCommand<'_> = cmd.into();
970-
self.run_cmd(cmd.fail_fast());
969+
self.run_cmd(BootstrapCommand::from(cmd).fail_fast().output_mode(
970+
match self.is_verbose() {
971+
true => OutputMode::PrintAll,
972+
false => OutputMode::PrintOutput,
973+
},
974+
));
975+
}
976+
977+
/// Runs a command, printing out contextual info if it fails, and delaying errors until the build finishes.
978+
pub(crate) fn run_delaying_failure(&self, cmd: &mut Command) -> bool {
979+
self.run_cmd(BootstrapCommand::from(cmd).delay_failure().output_mode(
980+
match self.is_verbose() {
981+
true => OutputMode::PrintAll,
982+
false => OutputMode::PrintOutput,
983+
},
984+
))
971985
}
972986

973987
/// Runs a command, printing out nice contextual information if it fails.
974988
fn run_quiet(&self, cmd: &mut Command) {
975-
// FIXME: output mode -> output + err
976-
let cmd: BootstrapCommand<'_> = cmd.into();
977-
self.run_cmd(cmd.fail_fast());
989+
self.run_cmd(BootstrapCommand::from(cmd).fail_fast().output_mode(OutputMode::Suppress));
978990
}
979991

980992
/// Runs a command, printing out nice contextual information if it fails.
981993
/// Exits if the command failed to execute at all, otherwise returns its
982994
/// `status.success()`.
983995
fn run_quiet_delaying_failure(&self, cmd: &mut Command) -> bool {
984-
// FIXME: output mode -> output + err
985-
let cmd: BootstrapCommand<'_> = cmd.into();
986-
self.run_cmd(cmd.delay_failure())
987-
}
988-
989-
/// Runs a command, printing out contextual info if it fails, and delaying errors until the build finishes.
990-
pub(crate) fn run_delaying_failure(&self, cmd: &mut Command) -> bool {
991-
// FIXME: output mode -> status + err if self.is_verbose()
992-
let cmd: BootstrapCommand<'_> = cmd.into();
993-
self.run_cmd(cmd.delay_failure())
996+
self.run_cmd(BootstrapCommand::from(cmd).delay_failure().output_mode(OutputMode::Suppress))
994997
}
995998

996999
/// A centralized function for running commands that do not return output.
9971000
pub(crate) fn run_cmd<'a, C: Into<BootstrapCommand<'a>>>(&self, cmd: C) -> bool {
1001+
if self.config.dry_run() {
1002+
return true;
1003+
}
1004+
9981005
let command = cmd.into();
9991006
self.verbose(&format!("running: {command:?}"));
10001007

1001-
#[allow(deprecated)] // can't use Build::try_run, that's us
1002-
let result = self.config.try_run(command.command);
1008+
let (output, print_error) = match command.output_mode {
1009+
mode @ (OutputMode::PrintAll | OutputMode::PrintOutput) => (
1010+
command.command.status().map(|status| Output {
1011+
status,
1012+
stdout: Vec::new(),
1013+
stderr: Vec::new(),
1014+
}),
1015+
matches!(mode, OutputMode::PrintAll),
1016+
),
1017+
OutputMode::Suppress => (command.command.output(), true),
1018+
};
1019+
1020+
let output = match output {
1021+
Ok(output) => output,
1022+
Err(e) => fail(&format!("failed to execute command: {:?}\nerror: {}", command, e)),
1023+
};
1024+
let result = if !output.status.success() {
1025+
if print_error {
1026+
println!(
1027+
"\n\ncommand did not execute successfully: {:?}\n\
1028+
expected success, got: {}\n\n\
1029+
stdout ----\n{}\n\
1030+
stderr ----\n{}\n\n",
1031+
command.command,
1032+
output.status,
1033+
String::from_utf8_lossy(&output.stdout),
1034+
String::from_utf8_lossy(&output.stderr)
1035+
);
1036+
}
1037+
Err(())
1038+
} else {
1039+
Ok(())
1040+
};
10031041

10041042
match result {
10051043
Ok(_) => true,

src/bootstrap/util.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)