pub struct Invocation { /* private fields */ }Expand description
The description of one external command
An invocation holds the program that the command starts, the arguments of the program, and the directory in which the command runs. The arguments keep the order in which the caller named them, and the working directory is optional.
An invocation also holds the variables that the caller sets for the command. The command inherits the environment of the process that runs it, and a variable of the invocation replaces a variable of the process with the same name.
No shell reads the command. Nothing splits an argument at a space, removes
a quotation mark, or expands a character such as *, so the program
receives every argument as the caller wrote it. An application that wants
a shell names the shell as the program, and gives the command line to it
as one argument.
The type renders as a command line through Display, which gives a log
line or an error message the name of the command.
§Examples
A command with two arguments:
use kawauso_process::Invocation;
let invocation = Invocation::new("git").arg("status").arg("--short");
assert_eq!(invocation.to_string(), "git status --short");A command that runs in a directory of its own:
use std::path::Path;
use kawauso_process::Invocation;
use kawauso_process::invocation::WorkingDirectory;
let invocation = Invocation::new("cargo")
.arg("build")
.in_directory("crates/example");
assert_eq!(
invocation.working_directory().map(WorkingDirectory::get),
Some(Path::new("crates/example"))
);A command that reads a variable of its environment:
use kawauso_process::Invocation;
let invocation = Invocation::new("cargo")
.arg("nextest")
.arg("run")
.env("NEXTEST_EXPERIMENTAL_LIBTEST_JSON", "1");
assert_eq!(
invocation.to_string(),
"NEXTEST_EXPERIMENTAL_LIBTEST_JSON=1 cargo nextest run"
);Implementations§
Source§impl Invocation
impl Invocation
Sourcepub fn new(program: impl Into<Program>) -> Self
pub fn new(program: impl Into<Program>) -> Self
Describes a command that starts the program that the caller names
The program is the path of an executable file, or the bare name of
one. The command has no argument yet, and it runs where the process
runs. arg adds an argument, and
in_directory names a working directory.
§Examples
use kawauso_process::Invocation;
let invocation = Invocation::new("git");
assert_eq!(invocation.program().get(), std::path::Path::new("git"));Sourcepub fn arg(self, argument: impl Into<Argument>) -> Self
pub fn arg(self, argument: impl Into<Argument>) -> Self
Adds one argument to the command
Every call adds one argument, and the program receives the arguments in the order of the calls. The value reaches the program as the caller wrote it, so an argument that holds a space stays one argument.
§Examples
use kawauso_process::Invocation;
let invocation = Invocation::new("git")
.arg("commit")
.arg("--message=two words");
assert_eq!(invocation.arguments().len(), 2);Sourcepub fn args(
self,
arguments: impl IntoIterator<Item = impl Into<Argument>>,
) -> Self
pub fn args( self, arguments: impl IntoIterator<Item = impl Into<Argument>>, ) -> Self
Adds every argument of an iterator to the command
The command keeps the order of the iterator, and a later call appends
to the arguments that the command holds. Use this method for a caller
that holds its arguments in a collection, and arg for one
that names them.
§Examples
use kawauso_process::Invocation;
let invocation = Invocation::new("cargo").args(["build", "--release"]);
assert_eq!(invocation.to_string(), "cargo build --release");Sourcepub fn arguments(&self) -> &[Argument]
pub fn arguments(&self) -> &[Argument]
Returns the arguments of the command, in the order of the calls
Sourcepub fn env(
self,
name: impl Into<VariableName>,
value: impl Into<VariableValue>,
) -> Self
pub fn env( self, name: impl Into<VariableName>, value: impl Into<VariableValue>, ) -> Self
Sets one variable in the environment of the command
The command inherits the environment of the process that runs it, and the variable comes on top of that environment. A variable with the name of one that the process holds replaces the value for the command alone, and the process keeps its own.
A later call with the same name replaces the value of the earlier call, because a variable holds one value. The variable keeps the place of the earlier call.
§Examples
use kawauso_process::Invocation;
let invocation = Invocation::new("cargo")
.arg("build")
.env("RUSTUP_TOOLCHAIN", "nightly");
assert_eq!(invocation.environment().len(), 1);Sourcepub fn environment(&self) -> &[Variable]
pub fn environment(&self) -> &[Variable]
Returns the variables that the caller set, in the order of the calls
Sourcepub fn env_remove(self, name: impl Into<VariableName>) -> Self
pub fn env_remove(self, name: impl Into<VariableName>) -> Self
Takes one name out of the environment of the command
The command inherits the environment of the process that runs it, and this name is the exception: the command runs as if the process never held it. Use this method for a program that reads a variable which the caller cannot set to a value that would be right, such as one that names the repository of a version control system to a child of a hook.
The process keeps its own environment. Nothing here changes the variables that this process holds, which is what makes the method safe in a program that runs several commands at once.
A name is either set or taken out, so this call undoes an earlier
env with the same name, and a later env with the name
undoes this call. A repeated call keeps the place of the earlier one.
§Examples
use kawauso_process::Invocation;
let invocation = Invocation::new("git")
.arg("status")
.env_remove("GIT_DIR");
assert_eq!(invocation.to_string(), "-GIT_DIR git status");Sourcepub fn removals(&self) -> &[VariableName]
pub fn removals(&self) -> &[VariableName]
Returns the names that the caller took out, in the order of the calls
Sourcepub fn envs(
self,
variables: impl IntoIterator<Item = impl Into<Variable>>,
) -> Self
pub fn envs( self, variables: impl IntoIterator<Item = impl Into<Variable>>, ) -> Self
Sets every variable of an iterator in the environment of the command
Each variable goes through the same steps as one that env
sets, so a later variable with the name of an earlier one replaces its
value. A pair of a name and a value is a variable, so a caller that
holds its variables as pairs gives them as they are. Use this method
for a caller that holds its variables in a collection, and
env for one that names them.
§Examples
use kawauso_process::Invocation;
let invocation = Invocation::new("cargo")
.arg("build")
.envs([("RUSTUP_TOOLCHAIN", "nightly"), ("CARGO_TERM_COLOR", "always")]);
assert_eq!(invocation.environment().len(), 2);Sourcepub fn in_directory(self, directory: impl Into<WorkingDirectory>) -> Self
pub fn in_directory(self, directory: impl Into<WorkingDirectory>) -> Self
Runs the command in the directory that the caller names
Use this method for a command that works on the directory that it runs in, such as a build tool that reads the manifest of a project. A command without a working directory runs where the process runs.
A later call replaces the directory of an earlier one, because a command runs in one directory.
§Examples
use kawauso_process::Invocation;
let invocation = Invocation::new("cargo")
.arg("test")
.in_directory("crates/example");
assert!(invocation.working_directory().is_some());Sourcepub async fn run(&self) -> Result<Execution, RunCommandError>
pub async fn run(&self) -> Result<Execution, RunCommandError>
Runs the command and reports what it produced
The method starts the program, reads what the command writes to its standard output and to its standard error, and waits for the command to end. A command that fills a pipe stops until a reader empties it, so the run reads both streams while it waits. A command that writes more than a pipe holds therefore never stops the run.
The command starts with a standard input that is null, so a command that reads its input sees the end of the input at once. A program that asks for a password ends instead of waiting for an answer. The command inherits the environment of the process that runs it, and it reads the variables of the invocation on top of that environment. The operating system resolves the program with the rules of the platform, and the crate searches no path of its own.
A command that ends without success is no failure of this method. The
status travels in the result, and require_success
turns a status that is not a success into an error.
The future of this method owns the command. A caller that drops the future, after a timeout for example, ends the command with it.
On Windows, a program whose name ends in .cmd or .bat starts
through cmd.exe. Rust escapes the arguments for that interpreter and
refuses an argument that it cannot pass safely, so an argument reaches
the program as the caller wrote it or the run fails.
§Errors
Returns UnstartableCommand when the program does not
start, and IncompleteRun when the command started and
the crate could not collect its result.
§Panics
Panics when no Tokio runtime drives the future. The runtime watches the streams and the end of the command, and the crate has no way to run the command without one.
§Examples
use kawauso_process::Invocation;
let execution = Invocation::new("git").arg("status").run().await?;
println!("{}", execution.stdout());Sourcepub fn start(&self) -> Result<Run, RunCommandError>
pub fn start(&self) -> Result<Run, RunCommandError>
Starts the command and reports its output while the command runs
The method starts the program and returns a handle. The handle gives
the output of the command to the caller as lines, in the order in
which the lines arrive, and it collects the same capture that
run collects. Use this method for an application that shows
the progress of a command, or that turns the output of a command into
events of its own, and run for one that needs the result
alone.
The command starts with the same decisions that run makes.
The standard input is null, the command inherits the environment of
the process that runs it, and the operating system resolves the
program. The variables of the invocation reach the command as well.
The handle owns the command. A caller that drops the handle kills the
command with it, and a caller that asks the command to end first calls
stop on the handle.
§Errors
Returns UnstartableCommand when the program does not
start.
§Panics
Panics when no Tokio runtime runs. The runtime watches the streams and the end of the command, and the crate has no way to run the command without one.
§Examples
use kawauso_process::Invocation;
let mut run = Invocation::new("cargo").arg("build").start()?;
while let Some(line) = run.next_line().await? {
println!("[{}] {line}", line.stream());
}
println!("{}", run.wait().await?.status());Sourcepub fn working_directory(&self) -> Option<&WorkingDirectory>
pub fn working_directory(&self) -> Option<&WorkingDirectory>
Returns the directory in which the command runs
None when the caller named no directory. The command then runs where
the process runs.
Trait Implementations§
Source§impl Clone for Invocation
impl Clone for Invocation
Source§fn clone(&self) -> Invocation
fn clone(&self) -> Invocation
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for Invocation
impl Debug for Invocation
Source§impl Display for Invocation
Renders the command as a command line for a reader
impl Display for Invocation
Renders the command as a command line for a reader
The line names every name that the caller took out, then every variable
that the caller set, then the program, and then every argument, each in the
order in which the caller named them. A variable shows as its name, an
equals sign, and its value, which is the form in which a shell sets a
variable for one command. A name that the caller took out shows behind a
minus sign, which is the form of the env program, because no shell takes
a name out of the environment of one command. The line does not name the
working directory, because a command line holds the command and not the
place that it runs in.
The line is for a person. No caller reads it back, and no shell runs it, so it is not a command line that a shell has to accept.