Skip to content

Commit

Permalink
Simplify and generalize implementation of output mode
Browse files Browse the repository at this point in the history
  • Loading branch information
Kobzol committed Jul 3, 2024
1 parent 8e5cfc6 commit a47933f
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 34 deletions.
44 changes: 25 additions & 19 deletions src/bootstrap/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use std::fmt::Display;
use std::fs::{self, File};
use std::io;
use std::path::{Path, PathBuf};
use std::process::{Command, Output, Stdio};
use std::process::{Command, Stdio};
use std::str;
use std::sync::OnceLock;

Expand Down Expand Up @@ -971,18 +971,25 @@ impl Build {

self.verbose(|| println!("running: {command:?}"));

let output: io::Result<Output> = match command.output_mode {
OutputMode::Print => command.command.status().map(|status| Output {
status,
stdout: vec![],
stderr: vec![],
}),
OutputMode::CaptureAll => command.command.output(),
OutputMode::CaptureStdout => {
match command.stdout {
OutputMode::Print => {
command.command.stdout(Stdio::inherit());
}
OutputMode::Capture => {
command.command.stdout(Stdio::piped());
}
}

match command.stderr {
OutputMode::Print => {
command.command.stderr(Stdio::inherit());
command.command.output()
}
};
OutputMode::Capture => {
command.command.stderr(Stdio::piped());
}
}

let output = command.command.output();

use std::fmt::Write;

Expand All @@ -1001,16 +1008,15 @@ impl Build {
.unwrap();

let output: CommandOutput = output.into();
// If the output mode is OutputMode::Print, the output has already been printed to

// If the output mode is OutputMode::Capture, we can now print the output.
// If it is OutputMode::Print, then the output has already been printed to
// stdout/stderr, and we thus don't have anything captured to print anyway.
if matches!(command.output_mode, OutputMode::CaptureAll | OutputMode::CaptureStdout)
{
if command.stdout.captures() {
writeln!(message, "\nSTDOUT ----\n{}", output.stdout().trim()).unwrap();

// Stderr is added to the message only if it was captured
if matches!(command.output_mode, OutputMode::CaptureAll) {
writeln!(message, "\nSTDERR ----\n{}", output.stderr().trim()).unwrap();
}
}
if command.stderr.captures() {
writeln!(message, "\nSTDERR ----\n{}", output.stderr().trim()).unwrap();
}
output
}
Expand Down
36 changes: 21 additions & 15 deletions src/bootstrap/src/utils/exec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,23 @@ pub enum BehaviorOnFailure {
Ignore,
}

/// How should the output of the command be handled (whether it should be captured or printed).
/// How should the output of a specific stream of the command (stdout/stderr) be handled
/// (whether it should be captured or printed).
#[derive(Debug, Copy, Clone)]
pub enum OutputMode {
/// Prints the stdout/stderr of the command to stdout/stderr of bootstrap (by inheriting these
/// streams).
/// Corresponds to calling `cmd.status()`.
/// Prints the stream by inheriting it from the bootstrap process.
Print,
/// Captures the stdout and stderr of the command into memory.
/// Corresponds to calling `cmd.output()`.
CaptureAll,
/// Captures the stdout of the command into memory, inherits stderr.
/// Corresponds to calling `cmd.output()`.
CaptureStdout,
/// Captures the stream into memory.
Capture,
}

impl OutputMode {
pub fn captures(&self) -> bool {
match self {
OutputMode::Print => false,
OutputMode::Capture => true,
}
}
}

/// Wrapper around `std::process::Command`.
Expand All @@ -45,7 +49,8 @@ pub enum OutputMode {
pub struct BootstrapCommand {
pub command: Command,
pub failure_behavior: BehaviorOnFailure,
pub output_mode: OutputMode,
pub stdout: OutputMode,
pub stderr: OutputMode,
// Run the command even during dry run
pub run_always: bool,
}
Expand Down Expand Up @@ -113,14 +118,14 @@ impl BootstrapCommand {
self
}

/// Capture the output of the command, do not print it.
/// Capture all output of the command, do not print it.
pub fn capture(self) -> Self {
Self { output_mode: OutputMode::CaptureAll, ..self }
Self { stdout: OutputMode::Capture, stderr: OutputMode::Capture, ..self }
}

/// Capture stdout of the command, do not print it.
pub fn capture_stdout(self) -> Self {
Self { output_mode: OutputMode::CaptureStdout, ..self }
Self { stdout: OutputMode::Capture, ..self }
}
}

Expand All @@ -137,7 +142,8 @@ impl From<Command> for BootstrapCommand {
Self {
command,
failure_behavior: BehaviorOnFailure::Exit,
output_mode: OutputMode::Print,
stdout: OutputMode::Print,
stderr: OutputMode::Print,
run_always: false,
}
}
Expand Down

0 comments on commit a47933f

Please sign in to comment.