Skip to content

Commit 509a232

Browse files
Implement missing methods on Command and on CompletedProcess
1 parent 8217b41 commit 509a232

File tree

2 files changed

+60
-96
lines changed

2 files changed

+60
-96
lines changed

src/tools/run-make-support/src/command.rs

+18-61
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
1-
use std::ffi;
21
use std::ffi::OsStr;
32
use std::io::Write;
43
use std::panic;
5-
use std::path::Path;
64
use std::process::{Command as StdCommand, ExitStatus, Output, Stdio};
75

86
use crate::drop_bomb::DropBomb;
@@ -39,63 +37,6 @@ impl Command {
3937
self.stdin = Some(stdin);
4038
}
4139

42-
/// Specify an environment variable.
43-
pub fn env<K, V>(&mut self, key: K, value: V) -> &mut Self
44-
where
45-
K: AsRef<ffi::OsStr>,
46-
V: AsRef<ffi::OsStr>,
47-
{
48-
self.cmd.env(key, value);
49-
self
50-
}
51-
52-
/// Remove an environmental variable.
53-
pub fn env_remove<K>(&mut self, key: K) -> &mut Self
54-
where
55-
K: AsRef<ffi::OsStr>,
56-
{
57-
self.cmd.env_remove(key);
58-
self
59-
}
60-
61-
/// Generic command argument provider. Prefer specific helper methods if possible.
62-
/// Note that for some executables, arguments might be platform specific. For C/C++
63-
/// compilers, arguments might be platform *and* compiler specific.
64-
pub fn arg<S>(&mut self, arg: S) -> &mut Self
65-
where
66-
S: AsRef<ffi::OsStr>,
67-
{
68-
self.cmd.arg(arg);
69-
self
70-
}
71-
72-
/// Generic command arguments provider. Prefer specific helper methods if possible.
73-
/// Note that for some executables, arguments might be platform specific. For C/C++
74-
/// compilers, arguments might be platform *and* compiler specific.
75-
pub fn args<S>(&mut self, args: &[S]) -> &mut Self
76-
where
77-
S: AsRef<ffi::OsStr>,
78-
{
79-
self.cmd.args(args);
80-
self
81-
}
82-
83-
/// Inspect what the underlying [`std::process::Command`] is up to the
84-
/// current construction.
85-
pub fn inspect<I>(&mut self, inspector: I) -> &mut Self
86-
where
87-
I: FnOnce(&StdCommand),
88-
{
89-
inspector(&self.cmd);
90-
self
91-
}
92-
93-
/// Set the path where the command will be run.
94-
pub fn current_dir<P: AsRef<Path>>(&mut self, path: P) -> &mut Self {
95-
self.cmd.current_dir(path);
96-
self
97-
}
98-
9940
/// Run the constructed command and assert that it is successfully run.
10041
#[track_caller]
10142
pub fn run(&mut self) -> CompletedProcess {
@@ -140,6 +81,22 @@ impl Command {
14081
}
14182
}
14283

84+
crate::impl_common_helpers_without_run!(Command);
85+
86+
impl std::ops::Deref for Command {
87+
type Target = StdCommand;
88+
89+
fn deref(&self) -> &Self::Target {
90+
&self.cmd
91+
}
92+
}
93+
94+
impl std::ops::DerefMut for Command {
95+
fn deref_mut(&mut self) -> &mut Self::Target {
96+
&mut self.cmd
97+
}
98+
}
99+
143100
/// Represents the result of an executed process.
144101
/// The various `assert_` helper methods should preferably be used for
145102
/// checking the contents of stdout/stderr.
@@ -171,8 +128,8 @@ impl CompletedProcess {
171128
}
172129

173130
#[track_caller]
174-
pub fn assert_stdout_contains<S: AsRef<str>>(self, needle: S) -> Self {
175-
assert_contains(&self.stdout_utf8(), needle.as_ref());
131+
pub fn assert_stdout_contains<S: AsRef<str>>(&self, content: S) -> &Self {
132+
assert!(self.stdout_utf8().contains(content.as_ref()));
176133
self
177134
}
178135

src/tools/run-make-support/src/lib.rs

+42-35
Original file line numberDiff line numberDiff line change
@@ -377,32 +377,7 @@ pub fn run_in_tmpdir<F: FnOnce()>(callback: F) {
377377
fs::remove_dir_all(tmpdir).unwrap();
378378
}
379379

380-
/// Implement common helpers for command wrappers. This assumes that the command wrapper is a struct
381-
/// containing a `cmd: Command` field. The provided helpers are:
382-
///
383-
/// 1. Generic argument acceptors: `arg` and `args` (delegated to [`Command`]). These are intended
384-
/// to be *fallback* argument acceptors, when specific helpers don't make sense. Prefer to add
385-
/// new specific helper methods over relying on these generic argument providers.
386-
/// 2. Environment manipulation methods: `env`, `env_remove` and `env_clear`: these delegate to
387-
/// methods of the same name on [`Command`].
388-
/// 3. Output and execution: `run` and `run_fail` are provided. These are
389-
/// higher-level convenience methods which wait for the command to finish running and assert
390-
/// that the command successfully ran or failed as expected. They return
391-
/// [`CompletedProcess`], which can be used to assert the stdout/stderr/exit code of the executed
392-
/// process.
393-
///
394-
/// Example usage:
395-
///
396-
/// ```ignore (illustrative)
397-
/// struct CommandWrapper { cmd: Command } // <- required `cmd` field
398-
///
399-
/// crate::impl_common_helpers!(CommandWrapper);
400-
///
401-
/// impl CommandWrapper {
402-
/// // ... additional specific helper methods
403-
/// }
404-
/// ```
405-
macro_rules! impl_common_helpers {
380+
macro_rules! impl_common_helpers_without_run {
406381
($wrapper: ident) => {
407382
impl $wrapper {
408383
/// Specify an environment variable.
@@ -446,13 +421,50 @@ macro_rules! impl_common_helpers {
446421
self
447422
}
448423

449-
/// Inspect what the underlying [`Command`] is up to the
450-
/// current construction.
451424
pub fn inspect<I>(&mut self, inspector: I) -> &mut Self
452425
where
453426
I: FnOnce(&::std::process::Command),
454427
{
455-
self.cmd.inspect(inspector);
428+
inspector(&self.cmd);
429+
self
430+
}
431+
}
432+
};
433+
}
434+
435+
/// Implement common helpers for command wrappers. This assumes that the command wrapper is a struct
436+
/// containing a `cmd: Command` field. The provided helpers are:
437+
///
438+
/// 1. Generic argument acceptors: `arg` and `args` (delegated to [`Command`]). These are intended
439+
/// to be *fallback* argument acceptors, when specific helpers don't make sense. Prefer to add
440+
/// new specific helper methods over relying on these generic argument providers.
441+
/// 2. Environment manipulation methods: `env`, `env_remove` and `env_clear`: these delegate to
442+
/// methods of the same name on [`Command`].
443+
/// 3. Output and execution: `run` and `run_fail` are provided. These are
444+
/// higher-level convenience methods which wait for the command to finish running and assert
445+
/// that the command successfully ran or failed as expected. They return
446+
/// [`CompletedProcess`], which can be used to assert the stdout/stderr/exit code of the executed
447+
/// process.
448+
///
449+
/// Example usage:
450+
///
451+
/// ```ignore (illustrative)
452+
/// struct CommandWrapper { cmd: Command } // <- required `cmd` field
453+
///
454+
/// crate::impl_common_helpers!(CommandWrapper);
455+
///
456+
/// impl CommandWrapper {
457+
/// // ... additional specific helper methods
458+
/// }
459+
/// ```
460+
macro_rules! impl_common_helpers {
461+
($wrapper: ident) => {
462+
crate::impl_common_helpers_without_run!($wrapper);
463+
464+
impl $wrapper {
465+
/// Set the path where the command will be run.
466+
pub fn current_dir<P: AsRef<Path>>(&mut self, path: P) -> &mut Self {
467+
self.cmd.current_dir(path);
456468
self
457469
}
458470

@@ -467,15 +479,10 @@ macro_rules! impl_common_helpers {
467479
pub fn run_fail(&mut self) -> crate::command::CompletedProcess {
468480
self.cmd.run_fail()
469481
}
470-
471-
/// Set the path where the command will be run.
472-
pub fn current_dir<P: AsRef<::std::path::Path>>(&mut self, path: P) -> &mut Self {
473-
self.cmd.current_dir(path);
474-
self
475-
}
476482
}
477483
};
478484
}
479485

480486
use crate::command::{Command, CompletedProcess};
481487
pub(crate) use impl_common_helpers;
488+
pub(crate) use impl_common_helpers_without_run;

0 commit comments

Comments
 (0)