Skip to content

Commit

Permalink
run-make-support: add support for stdin input with rustc/rustdoc
Browse files Browse the repository at this point in the history
  • Loading branch information
Urgau committed May 2, 2024
1 parent a8773d5 commit 0a03b09
Show file tree
Hide file tree
Showing 6 changed files with 94 additions and 17 deletions.
5 changes: 5 additions & 0 deletions src/tools/run-make-support/src/cc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,11 @@ impl Cc {

self
}

/// Get the [`Output`][::std::process::Output] of the finished process.
pub fn output(&mut self) -> ::std::process::Output {
self.cmd.output().expect("failed to get output of finished process")
}
}

/// `EXTRACFLAGS`
Expand Down
5 changes: 5 additions & 0 deletions src/tools/run-make-support/src/clang.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,4 +70,9 @@ impl Clang {
self.cmd.arg(format!("-fuse-ld={ld}"));
self
}

/// Get the [`Output`][::std::process::Output] of the finished process.
pub fn output(&mut self) -> ::std::process::Output {
self.cmd.output().expect("failed to get output of finished process")
}
}
18 changes: 9 additions & 9 deletions src/tools/run-make-support/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ pub fn set_host_rpath(cmd: &mut Command) {
}

/// Implement common helpers for command wrappers. This assumes that the command wrapper is a struct
/// containing a `cmd: Command` field. The provided helpers are:
/// containing a `cmd: Command` field and a `output` function. The provided helpers are:
///
/// 1. Generic argument acceptors: `arg` and `args` (delegated to [`Command`]). These are intended
/// to be *fallback* argument acceptors, when specific helpers don't make sense. Prefer to add
Expand All @@ -160,7 +160,12 @@ pub fn set_host_rpath(cmd: &mut Command) {
/// Example usage:
///
/// ```ignore (illustrative)
/// struct CommandWrapper { cmd: Command }
/// struct CommandWrapper { cmd: Command } // <- required `cmd` field
///
/// impl CommandWrapper {
/// /// Get the [`Output`][::std::process::Output] of the finished process.
/// pub fn output(&mut self) -> Output { /* ... */ } // <- required `output()` method
/// }
///
/// crate::impl_common_helpers!(CommandWrapper);
///
Expand Down Expand Up @@ -231,18 +236,13 @@ macro_rules! impl_common_helpers {
self
}

/// Get the [`Output`][::std::process::Output] of the finished process.
pub fn output(&mut self) -> ::std::process::Output {
self.cmd.output().expect("failed to get output of finished process")
}

/// Run the constructed command and assert that it is successfully run.
#[track_caller]
pub fn run(&mut self) -> ::std::process::Output {
let caller_location = ::std::panic::Location::caller();
let caller_line_number = caller_location.line();

let output = self.cmd.output().unwrap();
let output = self.output();
if !output.status.success() {
handle_failed_output(&self.cmd, output, caller_line_number);
}
Expand All @@ -255,7 +255,7 @@ macro_rules! impl_common_helpers {
let caller_location = ::std::panic::Location::caller();
let caller_line_number = caller_location.line();

let output = self.cmd.output().unwrap();
let output = self.output();
if output.status.success() {
handle_failed_output(&self.cmd, output, caller_line_number);
}
Expand Down
6 changes: 6 additions & 0 deletions src/tools/run-make-support/src/llvm_readobj.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,10 @@ impl LlvmReadobj {
self.cmd.arg("--file-header");
self
}

/// Get the [`Output`][::std::process::Output] of the finished process.
#[track_caller]
pub fn output(&mut self) -> ::std::process::Output {
self.cmd.output().expect("failed to get output of finished process")
}
}
38 changes: 34 additions & 4 deletions src/tools/run-make-support/src/rustc.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use std::env;
use std::ffi::OsString;
use std::io::Write;
use std::path::Path;
use std::process::{Command, Output};
use std::process::{Command, Output, Stdio};

use crate::{handle_failed_output, set_host_rpath, tmp_dir};

Expand All @@ -19,6 +20,7 @@ pub fn aux_build() -> Rustc {
#[derive(Debug)]
pub struct Rustc {
cmd: Command,
stdin: Option<Box<[u8]>>,
}

crate::impl_common_helpers!(Rustc);
Expand All @@ -37,14 +39,14 @@ impl Rustc {
/// Construct a new `rustc` invocation.
pub fn new() -> Self {
let cmd = setup_common();
Self { cmd }
Self { cmd, stdin: None }
}

/// Construct a new `rustc` invocation with `aux_build` preset (setting `--crate-type=lib`).
pub fn new_aux_build() -> Self {
let mut cmd = setup_common();
cmd.arg("--crate-type=lib");
Self { cmd }
Self { cmd, stdin: None }
}

// Argument provider methods
Expand Down Expand Up @@ -161,12 +163,40 @@ impl Rustc {
self
}

/// Specify a stdin input
pub fn stdin<I: AsRef<[u8]>>(&mut self, input: I) -> &mut Self {
self.stdin = Some(input.as_ref().to_vec().into_boxed_slice());
self
}

/// Get the [`Output`][::std::process::Output] of the finished process.
#[track_caller]
pub fn output(&mut self) -> ::std::process::Output {
// let's make sure we piped all the input and outputs
self.cmd.stdin(Stdio::piped());
self.cmd.stdout(Stdio::piped());
self.cmd.stderr(Stdio::piped());

if let Some(input) = &self.stdin {
let mut child = self.cmd.spawn().unwrap();

{
let mut stdin = child.stdin.take().unwrap();
stdin.write_all(input.as_ref()).unwrap();
}

child.wait_with_output().expect("failed to get output of finished process")
} else {
self.cmd.output().expect("failed to get output of finished process")
}
}

#[track_caller]
pub fn run_fail_assert_exit_code(&mut self, code: i32) -> Output {
let caller_location = std::panic::Location::caller();
let caller_line_number = caller_location.line();

let output = self.cmd.output().unwrap();
let output = self.output();
if output.status.code().unwrap() != code {
handle_failed_output(&self.cmd, output, caller_line_number);
}
Expand Down
39 changes: 35 additions & 4 deletions src/tools/run-make-support/src/rustdoc.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::env;
use std::io::Write;
use std::path::Path;
use std::process::{Command, Output};
use std::process::{Command, Output, Stdio};

use crate::{handle_failed_output, set_host_rpath};

Expand All @@ -17,6 +18,7 @@ pub fn rustdoc() -> Rustdoc {
#[derive(Debug)]
pub struct Rustdoc {
cmd: Command,
stdin: Option<Box<[u8]>>,
}

crate::impl_common_helpers!(Rustdoc);
Expand All @@ -32,15 +34,15 @@ impl Rustdoc {
/// Construct a bare `rustdoc` invocation.
pub fn bare() -> Self {
let cmd = setup_common();
Self { cmd }
Self { cmd, stdin: None }
}

/// Construct a `rustdoc` invocation with `-L $(TARGET_RPATH_DIR)` set.
pub fn new() -> Self {
let mut cmd = setup_common();
let target_rpath_dir = env::var_os("TARGET_RPATH_DIR").unwrap();
cmd.arg(format!("-L{}", target_rpath_dir.to_string_lossy()));
Self { cmd }
Self { cmd, stdin: None }
}

/// Specify path to the input file.
Expand All @@ -62,12 +64,41 @@ impl Rustdoc {
self
}

/// Specify a stdin input
pub fn stdin<I: AsRef<[u8]>>(&mut self, input: I) -> &mut Self {
self.cmd.stdin(Stdio::piped());
self.stdin = Some(input.as_ref().to_vec().into_boxed_slice());
self
}

/// Get the [`Output`][::std::process::Output] of the finished process.
#[track_caller]
pub fn output(&mut self) -> ::std::process::Output {
// let's make sure we piped all the input and outputs
self.cmd.stdin(Stdio::piped());
self.cmd.stdout(Stdio::piped());
self.cmd.stderr(Stdio::piped());

if let Some(input) = &self.stdin {
let mut child = self.cmd.spawn().unwrap();

{
let mut stdin = child.stdin.take().unwrap();
stdin.write_all(input.as_ref()).unwrap();
}

child.wait_with_output().expect("failed to get output of finished process")
} else {
self.cmd.output().expect("failed to get output of finished process")
}
}

#[track_caller]
pub fn run_fail_assert_exit_code(&mut self, code: i32) -> Output {
let caller_location = std::panic::Location::caller();
let caller_line_number = caller_location.line();

let output = self.cmd.output().unwrap();
let output = self.output();
if output.status.code().unwrap() != code {
handle_failed_output(&self.cmd, output, caller_line_number);
}
Expand Down

0 comments on commit 0a03b09

Please sign in to comment.