Skip to main content

Invocation

Struct Invocation 

Source
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

Source

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"));
Source

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);
Source

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");
Source

pub fn arguments(&self) -> &[Argument]

Returns the arguments of the command, in the order of the calls

Source

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);
Source

pub fn environment(&self) -> &[Variable]

Returns the variables that the caller set, in the order of the calls

Source

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");
Source

pub fn removals(&self) -> &[VariableName]

Returns the names that the caller took out, in the order of the calls

Source

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);
Source

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());
Source

pub fn program(&self) -> &Program

Returns the program that the command starts

Source

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());
Source

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());
Source

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

Source§

fn clone(&self) -> Invocation

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Invocation

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

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.

Source§

fn fmt(&self, formatter: &mut Formatter<'_>) -> FmtResult

Formats the value using the given formatter. Read more
Source§

impl Eq for Invocation

Source§

impl Hash for Invocation

Source§

fn hash<__H: Hasher>(&self, state: &mut __H)

Feeds this value into the given Hasher. Read more
1.3.0 · Source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where H: Hasher, Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
Source§

impl Ord for Invocation

Source§

fn cmp(&self, other: &Invocation) -> Ordering

This method returns an Ordering between self and other. Read more
1.21.0 (const: unstable) · Source§

fn max(self, other: Self) -> Self
where Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 (const: unstable) · Source§

fn min(self, other: Self) -> Self
where Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 (const: unstable) · Source§

fn clamp(self, min: Self, max: Self) -> Self
where Self: Sized,

Restrict a value to a certain interval. Read more
Source§

fn clamp_to<R>(self, range: R) -> Self
where Self: Sized, R: ClampBounds<Self>,

🔬This is a nightly-only experimental API. (clamp_to)
Restrict a value to a certain range. Read more
Source§

impl PartialEq for Invocation

Source§

fn eq(&self, other: &Invocation) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl PartialOrd for Invocation

Source§

fn partial_cmp(&self, other: &Invocation) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 (const: unstable) · Source§

fn lt(&self, other: &Rhs) -> bool

Tests less than (for self and other) and is used by the < operator. Read more
1.0.0 (const: unstable) · Source§

fn le(&self, other: &Rhs) -> bool

Tests less than or equal to (for self and other) and is used by the <= operator. Read more
1.0.0 (const: unstable) · Source§

fn gt(&self, other: &Rhs) -> bool

Tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 (const: unstable) · Source§

fn ge(&self, other: &Rhs) -> bool

Tests greater than or equal to (for self and other) and is used by the >= operator. Read more
Source§

impl StructuralPartialEq for Invocation

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.