pub struct Command<Output, Error>{ /* private fields */ }
Expand description
A alternative to std::process::Command
see module level documentation.
Implementations§
Source§impl<Output, Error> Command<Output, Error>
impl<Output, Error> Command<Output, Error>
Sourcepub fn new(
program: impl Into<OsString>,
return_settings: impl OutputMapping<Output = Output, Error = Error>,
) -> Self
pub fn new( program: impl Into<OsString>, return_settings: impl OutputMapping<Output = Output, Error = Error>, ) -> Self
Create a new command for given program and output mapping.
The output mapping will imply if stdout/stderr is captured and how the
captured output is mapped to a Result<Self::Output, Self::Error>
.
Sourcepub fn with_arguments<T>(self, args: impl IntoIterator<Item = T>) -> Self
pub fn with_arguments<T>(self, args: impl IntoIterator<Item = T>) -> Self
Returns this command with new arguments added to the end of the argument list
Sourcepub fn with_argument(self, arg: impl Into<OsString>) -> Self
pub fn with_argument(self, arg: impl Into<OsString>) -> Self
Returns this command with a new argument added to the end of the argument list
Sourcepub fn env_updates(&self) -> &HashMap<OsString, EnvChange>
pub fn env_updates(&self) -> &HashMap<OsString, EnvChange>
Return a map of all env variables which will be set/overwritten in the subprocess.
§Warning
The keys of env variables have not not been evaluated for syntactic validity.
So the given keys can cause process spawning or calls to std::env::set_var
to
fail.
Sourcepub fn with_env_updates<K, V>(
self,
map: impl IntoIterator<Item = (K, V)>,
) -> Self
pub fn with_env_updates<K, V>( self, map: impl IntoIterator<Item = (K, V)>, ) -> Self
Returns this command with the map of env updates updated by given iterator of key value pairs.
If any key from the new map already did exist in the current updates it will replace the old key & value.
- Common supported values for keys include
OsString
,&OsStr
,String
,&str
. - Common supported values for values include
EnvChange
,OsString
,&OsStr
,String
,&str
So you can pass in containers like Vec<(&str, &str)>
, HashMap<&str, &str>
or
HashMap<OsString, EnvChange>
, etc.
§Warning
The keys of env variables will not be evaluated for syntactic validity.
Setting a key invalid on given platform might cause the process spawning to
fail (e.g. using a key lik "="
or ""
). It also might also do other thinks
like the env variable being passed in but being unaccessible or similar. It’s completely
dependent on the OS and the impl. of std::process::Command
or whatever is used to
execute the command.
Sourcepub fn with_env_update(
self,
key: impl Into<OsString>,
value: impl Into<EnvChange>,
) -> Self
pub fn with_env_update( self, key: impl Into<OsString>, value: impl Into<EnvChange>, ) -> Self
Returns this command with the map of env updates updated by one key value pair.
If the new key already did exist in the current updates it will replace that old key & value.
Sourcepub fn inherit_env(&self) -> bool
pub fn inherit_env(&self) -> bool
Returns true if the env of the current process is inherited.
Updates to then environment are applied after the inheritance:
EnvChange::Set
can be use to override inherited env vars, or add new ones if no variable with given key was inheritedEnvChange::Remove
can be used to remove an inherited (or previously added) env variableEnvChange::Inherit
can be used to state a env variable should be inherited even ifinherit_env
isfalse
. Ifinherit_env
is true this will have no effect.
Sourcepub fn with_inherit_env(self, do_inherit: bool) -> Self
pub fn with_inherit_env(self, do_inherit: bool) -> Self
Returns this command with a change to weather or the sub-process will inherit env variables.
See Command::inherit_env()
for how this affects the sub-process env.
Sourcepub fn create_expected_env_iter(
&self,
) -> impl Iterator<Item = (Cow<'_, OsStr>, Cow<'_, OsStr>)>
pub fn create_expected_env_iter( &self, ) -> impl Iterator<Item = (Cow<'_, OsStr>, Cow<'_, OsStr>)>
Returns a map with all env variables the sub-process spawned by this command would have if the current processes env is not changed.
§Site note about env::set_var()
problems
Note that if you use std::env::set_var()
in a multi-threaded setup depending on
the operating system you run this on this can lead to all kind of problem, including
unexpected race conditions in some situations (especially if inherit_env(true)
is
combined with EnvChange::Inherit
and multiple variables are changed in another thread
racing with this function and some but not all are covered by EnvChange::Inherit
).
Given that std::env::set_var()
should strictly be avoided in a multi-threaded context
this is seen as an acceptable drawback.
Note that this function + std::env::set_var()
is not unsafe it might just have a
very unexpected result. Except if env::set_var()
+ reading env races are inherently
unsafe on your system, in which case this has nothing to do with this function.
Sourcepub fn working_directory_override(&self) -> Option<&Path>
pub fn working_directory_override(&self) -> Option<&Path>
Return the working directory which will be used instead of the current working directory.
If None
is returned it means no override is set and the working directory will be inherited
from the spawning process.
Sourcepub fn with_working_directory_override(
self,
wd_override: Option<impl Into<PathBuf>>,
) -> Self
pub fn with_working_directory_override( self, wd_override: Option<impl Into<PathBuf>>, ) -> Self
Replaces the working directory override.
Setting it to None
will unset the override making the spawned
process inherit the working directory from the spawning process.
Sourcepub fn expected_exit_status(&self) -> ExitStatus
pub fn expected_exit_status(&self) -> ExitStatus
Return which exit status is treated as success.
Sourcepub fn with_expected_exit_status(
self,
exit_status: impl Into<ExitStatus>,
) -> Self
pub fn with_expected_exit_status( self, exit_status: impl Into<ExitStatus>, ) -> Self
Set which exit status is treated as successful.
This enables exit status checking even if it was turned of before.
Sourcepub fn check_exit_status(&self) -> bool
pub fn check_exit_status(&self) -> bool
Returns true if the exit status is checked before mapping the output(s).
Sourcepub fn with_check_exit_status(self, val: bool) -> Self
pub fn with_check_exit_status(self, val: bool) -> Self
Sets if the exit status is checked before mapping the output(s).
Sourcepub fn will_capture_stdout(&self) -> bool
pub fn will_capture_stdout(&self) -> bool
Returns true if stdout will be captured.
§Panics
If called in a exec_replacement_callback
this will panic.
Sourcepub fn will_capture_stderr(&self) -> bool
pub fn will_capture_stderr(&self) -> bool
Returns true if stderr will be captured.
§Panics
If called in a exec_replacement_callback
this will panic.
Sourcepub fn run(self) -> Result<Output, Error>
pub fn run(self) -> Result<Output, Error>
Run the command, blocking until completion and then mapping the output.
This will:
- run the program with the specified arguments and env variables
- capture the necessary outputs as specified by the output mapping
- if exit status checking was not disabled check the exit status and potentially fail.
- if 3 doesn’t fail now map captured outputs to a
Result<Output, Error>
If Command::with_exec_replacement_callback()
is used instead of running the
program and capturing the output the given callback is called. The callback
could mock the program execution. The exit status checking and output mapping
are still done as normal.
§Panics
This will panic if called in a exec_replacement_callback
.
Sourcepub fn with_exec_replacement_callback(
self,
callback: impl FnOnce(Self, &dyn OutputMapping<Output = Output, Error = Error>) -> Result<ExecResult, Error> + 'static,
) -> Self
pub fn with_exec_replacement_callback( self, callback: impl FnOnce(Self, &dyn OutputMapping<Output = Output, Error = Error>) -> Result<ExecResult, Error> + 'static, ) -> Self
Sets a callback which is called instead of executing the command when running the command.
This is mainly meant to be used for mocking command execution during testing, but can be used for other thinks, too. E.g. the current implementation does have a default callback for normally executing the command this method was not called.
§Implementing Mocks with an exec_replacement_callback
You must not call following methods in the callback:
Command::run()
, recursively calling run will not work.Command::will_capture_stdout()
, use the passed in output mappingOutputMapping::capture_stdout()
method instead.Command::will_capture_stderr()
, use the passed in output mappingOutputMapping::capture_stderr()
method instead.
An emulation of captured output and exit status is returned as ExecResult
instance:
- Any exit code can be returned including a target specific one,
the
From<num> for ExitStatus
implementations are useful here. - If
OutputMapping::capture_stdout()
istrue
thenExecResult::stdout
must beSome
else it must beNone
. Failing to do so will panic on unwrap of debug assertions. - If
OutputMapping::capture_stdout()
istrue
thenExecResult::stdout
must beSome
else it must beNone
. Failing to do so will panic on unwrap of debug assertions.
If used for mocking in tests you already know if stdout/stderr is assumed to (not) be
captured so you do not need to access OutputMapping::capture_stdout()
/OutputMapping::capture_stdout()
.
Settings like env updates and inheritance can be retrieved from the passed in Command
instance.
§Implement custom subprocess spawning
Be aware that if you execute the program in the callback you need to make sure the right program, arguments
stdout/stderr capture setting and env variables are used. Especially note should be taken to how EnvChange::Inherit
is handled.
The Command::create_expected_env_iter()
method can be used to find what exact env variables
are expected to be in the sub-process. Clearing the sub-process env and then setting all env vars
using Command::create_expected_env_iter()
is not the most efficient but most simple and robust
to changes way to set the env. It’s recommended to be used.