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 8dc4485
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 38 deletions.
35 changes: 13 additions & 22 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 All @@ -40,7 +40,7 @@ use crate::core::builder::Kind;
use crate::core::config::{flags, LldMode};
use crate::core::config::{DryRun, Target};
use crate::core::config::{LlvmLibunwind, TargetSelection};
use crate::utils::exec::{BehaviorOnFailure, BootstrapCommand, CommandOutput, OutputMode};
use crate::utils::exec::{BehaviorOnFailure, BootstrapCommand, CommandOutput};
use crate::utils::helpers::{self, dir_is_empty, exe, libdir, mtime, output, symlink_dir};

mod core;
Expand Down Expand Up @@ -971,18 +971,10 @@ 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 => {
command.command.stderr(Stdio::inherit());
command.command.output()
}
};
command.command.stdout(command.stdout.stdio());
command.command.stderr(command.stderr.stdio());

let output = command.command.output();

use std::fmt::Write;

Expand All @@ -1001,16 +993,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
45 changes: 29 additions & 16 deletions src/bootstrap/src/utils/exec.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::ffi::OsStr;
use std::path::Path;
use std::process::{Command, CommandArgs, CommandEnvs, ExitStatus, Output};
use std::process::{Command, CommandArgs, CommandEnvs, ExitStatus, Output, Stdio};

/// What should be done when the command fails.
#[derive(Debug, Copy, Clone)]
Expand All @@ -13,19 +13,30 @@ 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,
}
}

pub fn stdio(&self) -> Stdio {
match self {
OutputMode::Print => Stdio::inherit(),
OutputMode::Capture => Stdio::piped(),
}
}
}

/// Wrapper around `std::process::Command`.
Expand All @@ -45,7 +56,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 +125,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 +149,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 8dc4485

Please sign in to comment.