Skip to content

Commit a7ca8ee

Browse files
Implement missing methods on Command and on CompletedProcess
1 parent 921645c commit a7ca8ee

File tree

2 files changed

+65
-95
lines changed

2 files changed

+65
-95
lines changed

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

Lines changed: 23 additions & 60 deletions
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,7 +128,13 @@ impl CompletedProcess {
171128
}
172129

173130
#[track_caller]
174-
pub fn assert_stdout_not_contains<S: AsRef<str>>(&self, needle: S) -> &Self {
131+
pub fn assert_stdout_contains<S: AsRef<str>>(self, content: S) -> Self {
132+
assert!(self.stdout_utf8().contains(content.as_ref()));
133+
self
134+
}
135+
136+
#[track_caller]
137+
pub fn assert_stdout_not_contains<S: AsRef<str>>(self, needle: S) -> Self {
175138
assert_not_contains(&self.stdout_utf8(), needle.as_ref());
176139
self
177140
}

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

Lines changed: 42 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -365,32 +365,7 @@ pub fn run_in_tmpdir<F: FnOnce()>(callback: F) {
365365
fs::remove_dir_all(tmpdir).unwrap();
366366
}
367367

368-
/// Implement common helpers for command wrappers. This assumes that the command wrapper is a struct
369-
/// containing a `cmd: Command` field. The provided helpers are:
370-
///
371-
/// 1. Generic argument acceptors: `arg` and `args` (delegated to [`Command`]). These are intended
372-
/// to be *fallback* argument acceptors, when specific helpers don't make sense. Prefer to add
373-
/// new specific helper methods over relying on these generic argument providers.
374-
/// 2. Environment manipulation methods: `env`, `env_remove` and `env_clear`: these delegate to
375-
/// methods of the same name on [`Command`].
376-
/// 3. Output and execution: `run` and `run_fail` are provided. These are
377-
/// higher-level convenience methods which wait for the command to finish running and assert
378-
/// that the command successfully ran or failed as expected. They return
379-
/// [`CompletedProcess`], which can be used to assert the stdout/stderr/exit code of the executed
380-
/// process.
381-
///
382-
/// Example usage:
383-
///
384-
/// ```ignore (illustrative)
385-
/// struct CommandWrapper { cmd: Command } // <- required `cmd` field
386-
///
387-
/// crate::impl_common_helpers!(CommandWrapper);
388-
///
389-
/// impl CommandWrapper {
390-
/// // ... additional specific helper methods
391-
/// }
392-
/// ```
393-
macro_rules! impl_common_helpers {
368+
macro_rules! impl_common_helpers_without_run {
394369
($wrapper: ident) => {
395370
impl $wrapper {
396371
/// Specify an environment variable.
@@ -434,13 +409,50 @@ macro_rules! impl_common_helpers {
434409
self
435410
}
436411

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

@@ -455,15 +467,10 @@ macro_rules! impl_common_helpers {
455467
pub fn run_fail(&mut self) -> crate::command::CompletedProcess {
456468
self.cmd.run_fail()
457469
}
458-
459-
/// Set the path where the command will be run.
460-
pub fn current_dir<P: AsRef<::std::path::Path>>(&mut self, path: P) -> &mut Self {
461-
self.cmd.current_dir(path);
462-
self
463-
}
464470
}
465471
};
466472
}
467473

468474
use crate::command::{Command, CompletedProcess};
469475
pub(crate) use impl_common_helpers;
476+
pub(crate) use impl_common_helpers_without_run;

0 commit comments

Comments
 (0)