From b618fea358147080a27f3984a3be078f8b49e519 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Wed, 3 Jul 2024 21:04:02 +0200 Subject: [PATCH] Simplify and generalize implementation of output mode --- src/bootstrap/src/lib.rs | 35 ++++++++++--------------- src/bootstrap/src/utils/exec.rs | 45 +++++++++++++++++++++------------ 2 files changed, 42 insertions(+), 38 deletions(-) diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index ce139a0bc59df..ffdd9bc885a62 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -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; use std::time::SystemTime; @@ -41,7 +41,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; @@ -943,18 +943,10 @@ impl Build { self.verbose(|| println!("running: {command:?}")); - let output: io::Result = 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; @@ -973,16 +965,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 } diff --git a/src/bootstrap/src/utils/exec.rs b/src/bootstrap/src/utils/exec.rs index 74fb483773e3a..086d10c63511a 100644 --- a/src/bootstrap/src/utils/exec.rs +++ b/src/bootstrap/src/utils/exec.rs @@ -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)] @@ -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`. @@ -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, } @@ -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 } } } @@ -137,7 +149,8 @@ impl From for BootstrapCommand { Self { command, failure_behavior: BehaviorOnFailure::Exit, - output_mode: OutputMode::Print, + stdout: OutputMode::Print, + stderr: OutputMode::Print, run_always: false, } }