Command

Struct Command 

Source
pub struct Command { /* private fields */ }
Expand description

A process builder for cargo commands, providing a similar API to std::process::Command.

Command is a wrapper around std::process::Command specifically designed for executing cargo commands targeting hyperlight guest code. Before executing the desired command, Command takes care of setting up the appropriate environment. It:

  • creates a custom rust target for hyperlight guest code
  • creates a sysroot with Rust’s libs core and alloc
  • finds the appropriate compiler and archiver for any C dependencies
  • sets up necessary environment variables for cc-rs and bindgen to work correctly.

§Examples

Basic usage:

use cargo_hyperlight::cargo;

let mut command = cargo().unwrap();
command.arg("build").arg("--release");
command.exec(); // This will replace the current process

Setting environment variables and working directory:

use cargo_hyperlight::cargo;

let mut command = cargo().unwrap();
command
    .current_dir("/path/to/project")
    .env("CARGO_TARGET_DIR", "/custom/target")
    .args(["build", "--release"]);

Implementations§

Source§

impl Command

Source

pub fn arg(&mut self, arg: impl AsRef<OsStr>) -> &mut Self

Adds an argument to pass to the cargo program.

Only one argument can be passed per use. So instead of:

command.arg("--features some_feature");

usage would be:

command.arg("--features").arg("some_feature");

To pass multiple arguments see args.

Note that the argument is not shell-escaped, so if you pass an argument like "hello world", it will be passed as a single argument with the literal hello world, not as two arguments hello and world.

§Examples

Basic usage:

use cargo_hyperlight::cargo;

cargo()
    .unwrap()
    .arg("build")
    .arg("--release")
    .exec();
Source

pub fn args( &mut self, args: impl IntoIterator<Item = impl AsRef<OsStr>>, ) -> &mut Self

Adds multiple arguments to pass to the cargo program.

To pass a single argument see arg.

Note that the arguments are not shell-escaped, so if you pass an argument like "hello world", it will be passed as a single argument with the literal hello world, not as two arguments hello and world.

§Examples

Basic usage:

use cargo_hyperlight::cargo;

cargo()
    .unwrap()
    .args(["build", "--release"])
    .exec();
Source

pub fn current_dir(&mut self, dir: impl AsRef<Path>) -> &mut Self

Sets the working directory for the child process.

§Examples

Basic usage:

use cargo_hyperlight::cargo;

cargo()
    .unwrap()
    .current_dir("path/to/project")
    .arg("build")
    .exec();
Source

pub fn env( &mut self, key: impl AsRef<OsStr>, value: impl AsRef<OsStr>, ) -> &mut Self

Inserts or updates an explicit environment variable mapping.

This method allows you to add an environment variable mapping to the spawned process or overwrite a variable if it already exists.

Child processes will inherit environment variables from their parent process by default. Environment variables explicitly set using env take precedence over inherited variables. You can disable environment variable inheritance entirely using env_clear or for a single key using env_remove.

Note that environment variable names are case-insensitive (but case-preserving) on Windows and case-sensitive on all other platforms.

§Examples

Basic usage:

use cargo_hyperlight::cargo;

cargo()
    .unwrap()
    .env("CARGO_TARGET_DIR", "/path/to/target")
    .arg("build")
    .exec();
Source

pub fn env_clear(&mut self) -> &mut Self

Clears all environment variables that will be set for the child process.

This method will remove all environment variables from the child process, including those that would normally be inherited from the parent process. Environment variables can be added back individually using env.

If RUSTUP_TOOLCHAIN was set in the parent process, it will be preserved.

§Examples

Basic usage:

use cargo_hyperlight::cargo;

cargo()
    .unwrap()
    .env_clear()
    .env("CARGO_TARGET_DIR", "/path/to/target")
    .arg("build")
    .exec();
Source

pub fn env_remove(&mut self, key: impl AsRef<OsStr>) -> &mut Self

Removes an explicitly set environment variable and prevents inheriting it from a parent process.

This method will ensure that the specified environment variable is not present in the spawned process’s environment, even if it was present in the parent process. This serves to “unset” environment variables.

Note that environment variable names are case-insensitive (but case-preserving) on Windows and case-sensitive on all other platforms.

§Examples

Basic usage:

use cargo_hyperlight::cargo;

cargo()
    .unwrap()
    .env_remove("CARGO_TARGET_DIR")
    .arg("build")
    .exec();
Source

pub fn envs( &mut self, envs: impl IntoIterator<Item = (impl AsRef<OsStr>, impl AsRef<OsStr>)>, ) -> &mut Self

Inserts or updates multiple explicit environment variable mappings.

This method allows you to add multiple environment variable mappings to the spawned process or overwrite variables if they already exist. Environment variables can be passed as a HashMap or any other type implementing IntoIterator with the appropriate item type.

Child processes will inherit environment variables from their parent process by default. Environment variables explicitly set using env take precedence over inherited variables. You can disable environment variable inheritance entirely using env_clear or for a single key using env_remove.

Note that environment variable names are case-insensitive (but case-preserving) on Windows and case-sensitive on all other platforms.

§Examples

Basic usage:

use std::collections::HashMap;
use cargo_hyperlight::cargo;

let mut envs = HashMap::new();
envs.insert("CARGO_TARGET_DIR", "/path/to/target");
envs.insert("CARGO_HOME", "/path/to/.cargo");

cargo()
    .unwrap()
    .envs(&envs)
    .arg("build")
    .exec();
use cargo_hyperlight::cargo;

cargo()
    .unwrap()
    .envs([
        ("CARGO_TARGET_DIR", "/path/to/target"),
        ("CARGO_HOME", "/path/to/.cargo"),
    ])
    .arg("build")
    .exec();
Source

pub fn get_args(&self) -> impl Iterator<Item = &OsStr>

Returns an iterator over the arguments that will be passed to the cargo program.

This does not include the program name itself (which can be retrieved with get_program).

§Examples
use cargo_hyperlight::cargo;

let mut command = cargo().unwrap();
command.arg("build").arg("--release");

let args: Vec<&std::ffi::OsStr> = command.get_args().collect();
assert_eq!(args, &["build", "--release"]);
Source

pub fn get_current_dir(&self) -> Option<&Path>

Returns the working directory for the child process.

This returns None if the working directory will not be changed from the current directory of the parent process.

§Examples
use std::path::Path;
use cargo_hyperlight::cargo;

let mut command = cargo().unwrap();
assert_eq!(command.get_current_dir(), None);

command.current_dir("/tmp");
assert_eq!(command.get_current_dir(), Some(Path::new("/tmp")));
Source

pub fn get_envs(&self) -> impl Iterator<Item = (&OsStr, Option<&OsStr>)>

Returns an iterator over the environment mappings that will be set for the child process.

Environment variables explicitly set or unset via env, envs, and env_remove can be retrieved with this method.

Note that this output does not include environment variables inherited from the parent process.

Each element is a tuple key/value where None means the variable is explicitly unset in the child process environment.

§Examples
use std::ffi::OsStr;
use cargo_hyperlight::cargo;

let mut command = cargo().unwrap();
command.env("CARGO_HOME", "/path/to/.cargo");
command.env_remove("CARGO_TARGET_DIR");

for (key, value) in command.get_envs() {
    println!("{key:?} => {value:?}");
}
Source

pub fn get_program(&self) -> &OsStr

Returns the path to the cargo program that will be executed.

§Examples
use cargo_hyperlight::cargo;

let command = cargo().unwrap();
println!("Program: {:?}", command.get_program());
Source

pub fn status(&self) -> Result<()>

Executes a cargo command as a child process, waiting for it to finish and collecting its exit status.

The process stdin, stdout and stderr are inherited from the parent.

§Examples

Basic usage:

use cargo_hyperlight::cargo;

let result = cargo()
    .unwrap()
    .arg("build")
    .status();

match result {
    Ok(()) => println!("Cargo command succeeded"),
    Err(e) => println!("Cargo command failed: {}", e),
}
§Errors

This method will return an error if:

  • The sysroot preparation fails
  • The cargo process could not be spawned
  • The cargo process returned a non-zero exit status
Source

pub fn exec(&self) -> !

Executes the cargo command, replacing the current process.

This function will never return on success, as it replaces the current process with the cargo process. On error, it will print the error and exit with code 101.

§Examples

Basic usage:

use cargo_hyperlight::cargo;

cargo()
    .unwrap()
    .arg("build")
    .exec(); // This will never return
§Errors

This function will exit the process with code 101 if:

  • The sysroot preparation fails
  • The process replacement fails

Trait Implementations§

Source§

impl Clone for Command

Source§

fn clone(&self) -> Command

Returns a duplicate of the value. Read more
1.0.0 · Source§

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

Performs copy-assignment from source. Read more
Source§

impl Debug for Command

Source§

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

Formats the value using the given formatter. Read more

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, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

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.