run_make_support: move impl_common_helpers into own macros module

This commit is contained in:
许杰友 Jieyou Xu (Joe) 2024-07-15 09:32:41 +00:00
parent cb12b52f16
commit 427cf94106
7 changed files with 125 additions and 122 deletions

View File

@ -20,7 +20,7 @@ pub struct Cc {
cmd: Command,
}
crate::impl_common_helpers!(Cc);
crate::macros::impl_common_helpers!(Cc);
impl Cc {
/// Construct a new platform-specific C compiler invocation.

View File

@ -16,7 +16,7 @@ pub struct Clang {
cmd: Command,
}
crate::impl_common_helpers!(Clang);
crate::macros::impl_common_helpers!(Clang);
impl Clang {
/// Construct a new `clang` invocation. `clang` is not always available for all targets.

View File

@ -9,6 +9,7 @@ mod command;
pub mod diff;
pub mod fs_wrapper;
pub mod llvm;
mod macros;
pub mod run;
pub mod rustc;
pub mod rustdoc;
@ -37,6 +38,8 @@ pub use run::{cmd, run, run_fail, run_with_args};
pub use rustc::{aux_build, bare_rustc, rustc, Rustc};
pub use rustdoc::{bare_rustdoc, rustdoc, Rustdoc};
use command::{Command, CompletedProcess};
#[track_caller]
#[must_use]
pub fn env_var(name: &str) -> String {
@ -538,116 +541,3 @@ pub fn run_in_tmpdir<F: FnOnce()>(callback: F) {
env::set_current_dir(original_dir).unwrap();
fs::remove_dir_all(tmpdir).unwrap();
}
/// Implement common helpers for command wrappers. This assumes that the command wrapper is a struct
/// containing a `cmd: Command` field. 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
/// new specific helper methods over relying on these generic argument providers.
/// 2. Environment manipulation methods: `env`, `env_remove` and `env_clear`: these delegate to
/// methods of the same name on [`Command`].
/// 3. Output and execution: `run` and `run_fail` are provided. These are
/// higher-level convenience methods which wait for the command to finish running and assert
/// that the command successfully ran or failed as expected. They return
/// [`CompletedProcess`], which can be used to assert the stdout/stderr/exit code of the executed
/// process.
///
/// Example usage:
///
/// ```ignore (illustrative)
/// struct CommandWrapper { cmd: Command } // <- required `cmd` field
///
/// crate::impl_common_helpers!(CommandWrapper);
///
/// impl CommandWrapper {
/// // ... additional specific helper methods
/// }
/// ```
macro_rules! impl_common_helpers {
($wrapper: ident) => {
impl $wrapper {
/// Specify an environment variable.
pub fn env<K, V>(&mut self, key: K, value: V) -> &mut Self
where
K: AsRef<::std::ffi::OsStr>,
V: AsRef<::std::ffi::OsStr>,
{
self.cmd.env(key, value);
self
}
/// Remove an environmental variable.
pub fn env_remove<K>(&mut self, key: K) -> &mut Self
where
K: AsRef<::std::ffi::OsStr>,
{
self.cmd.env_remove(key);
self
}
/// Generic command argument provider. Prefer specific helper methods if possible.
/// Note that for some executables, arguments might be platform specific. For C/C++
/// compilers, arguments might be platform *and* compiler specific.
pub fn arg<S>(&mut self, arg: S) -> &mut Self
where
S: AsRef<::std::ffi::OsStr>,
{
self.cmd.arg(arg);
self
}
/// Generic command arguments provider. Prefer specific helper methods if possible.
/// Note that for some executables, arguments might be platform specific. For C/C++
/// compilers, arguments might be platform *and* compiler specific.
pub fn args<V, S>(&mut self, args: V) -> &mut Self
where
V: AsRef<[S]>,
S: AsRef<::std::ffi::OsStr>,
{
self.cmd.args(args.as_ref());
self
}
/// Inspect what the underlying [`Command`] is up to the
/// current construction.
pub fn inspect<I>(&mut self, inspector: I) -> &mut Self
where
I: FnOnce(&::std::process::Command),
{
self.cmd.inspect(inspector);
self
}
/// Run the constructed command and assert that it is successfully run.
#[track_caller]
pub fn run(&mut self) -> crate::command::CompletedProcess {
self.cmd.run()
}
/// Run the constructed command and assert that it does not successfully run.
#[track_caller]
pub fn run_fail(&mut self) -> crate::command::CompletedProcess {
self.cmd.run_fail()
}
/// Run the command but do not check its exit status.
/// Only use if you explicitly don't care about the exit status.
/// Prefer to use [`Self::run`] and [`Self::run_fail`]
/// whenever possible.
#[track_caller]
pub fn run_unchecked(&mut self) -> crate::command::CompletedProcess {
self.cmd.run_unchecked()
}
/// Set the path where the command will be run.
pub fn current_dir<P: AsRef<::std::path::Path>>(&mut self, path: P) -> &mut Self {
self.cmd.current_dir(path);
self
}
}
};
}
use crate::command::{Command, CompletedProcess};
pub(crate) use impl_common_helpers;

View File

@ -70,11 +70,11 @@ pub struct LlvmAr {
cmd: Command,
}
crate::impl_common_helpers!(LlvmReadobj);
crate::impl_common_helpers!(LlvmProfdata);
crate::impl_common_helpers!(LlvmFilecheck);
crate::impl_common_helpers!(LlvmObjdump);
crate::impl_common_helpers!(LlvmAr);
crate::macros::impl_common_helpers!(LlvmReadobj);
crate::macros::impl_common_helpers!(LlvmProfdata);
crate::macros::impl_common_helpers!(LlvmFilecheck);
crate::macros::impl_common_helpers!(LlvmObjdump);
crate::macros::impl_common_helpers!(LlvmAr);
/// Generate the path to the bin directory of LLVM.
#[must_use]

View File

@ -0,0 +1,113 @@
/// Implement common helpers for command wrappers. This assumes that the command wrapper is a struct
/// containing a `cmd: Command` field. 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
/// new specific helper methods over relying on these generic argument providers.
/// 2. Environment manipulation methods: `env`, `env_remove` and `env_clear`: these delegate to
/// methods of the same name on [`Command`].
/// 3. Output and execution: `run` and `run_fail` are provided. These are higher-level convenience
/// methods which wait for the command to finish running and assert that the command successfully
/// ran or failed as expected. They return [`CompletedProcess`], which can be used to assert the
/// stdout/stderr/exit code of the executed process.
///
/// Example usage:
///
/// ```ignore (illustrative)
/// struct CommandWrapper { cmd: Command } // <- required `cmd` field
///
/// crate::macros::impl_common_helpers!(CommandWrapper);
///
/// impl CommandWrapper {
/// // ... additional specific helper methods
/// }
/// ```
///
/// [`Command`]: crate::command::Command
/// [`CompletedProcess`]: crate::command::CompletedProcess
macro_rules! impl_common_helpers {
($wrapper: ident) => {
impl $wrapper {
/// Specify an environment variable.
pub fn env<K, V>(&mut self, key: K, value: V) -> &mut Self
where
K: AsRef<::std::ffi::OsStr>,
V: AsRef<::std::ffi::OsStr>,
{
self.cmd.env(key, value);
self
}
/// Remove an environmental variable.
pub fn env_remove<K>(&mut self, key: K) -> &mut Self
where
K: AsRef<::std::ffi::OsStr>,
{
self.cmd.env_remove(key);
self
}
/// Generic command argument provider. Prefer specific helper methods if possible.
/// Note that for some executables, arguments might be platform specific. For C/C++
/// compilers, arguments might be platform *and* compiler specific.
pub fn arg<S>(&mut self, arg: S) -> &mut Self
where
S: AsRef<::std::ffi::OsStr>,
{
self.cmd.arg(arg);
self
}
/// Generic command arguments provider. Prefer specific helper methods if possible.
/// Note that for some executables, arguments might be platform specific. For C/C++
/// compilers, arguments might be platform *and* compiler specific.
pub fn args<V, S>(&mut self, args: V) -> &mut Self
where
V: AsRef<[S]>,
S: AsRef<::std::ffi::OsStr>,
{
self.cmd.args(args.as_ref());
self
}
/// Inspect what the underlying [`Command`] is up to the
/// current construction.
pub fn inspect<I>(&mut self, inspector: I) -> &mut Self
where
I: FnOnce(&::std::process::Command),
{
self.cmd.inspect(inspector);
self
}
/// Run the constructed command and assert that it is successfully run.
#[track_caller]
pub fn run(&mut self) -> crate::command::CompletedProcess {
self.cmd.run()
}
/// Run the constructed command and assert that it does not successfully run.
#[track_caller]
pub fn run_fail(&mut self) -> crate::command::CompletedProcess {
self.cmd.run_fail()
}
/// Run the command but do not check its exit status.
/// Only use if you explicitly don't care about the exit status.
/// Prefer to use [`Self::run`] and [`Self::run_fail`]
/// whenever possible.
#[track_caller]
pub fn run_unchecked(&mut self) -> crate::command::CompletedProcess {
self.cmd.run_unchecked()
}
/// Set the path where the command will be run.
pub fn current_dir<P: AsRef<::std::path::Path>>(&mut self, path: P) -> &mut Self {
self.cmd.current_dir(path);
self
}
}
};
}
pub(crate) use impl_common_helpers;

View File

@ -31,7 +31,7 @@ pub struct Rustc {
cmd: Command,
}
crate::impl_common_helpers!(Rustc);
crate::macros::impl_common_helpers!(Rustc);
#[track_caller]
fn setup_common() -> Command {

View File

@ -22,7 +22,7 @@ pub struct Rustdoc {
cmd: Command,
}
crate::impl_common_helpers!(Rustdoc);
crate::macros::impl_common_helpers!(Rustdoc);
#[track_caller]
fn setup_common() -> Command {