Struct bkt::CommandDesc

source ·
pub struct CommandDesc { /* private fields */ }
Expand description

A stateless description of a command to be executed and cached. It consists of a command line invocation and additional metadata about how the command should be cached which are configured via the with_* methods. Instances can be persisted and reused.

Calling any of these methods changes how the invocation’s cache key will be constructed, therefore two invocations with different metadata configured will be cached separately. This allows - for example - commands that interact with the current working directory to be cached dependent on the working directory even if the command line arguments are equal.

§Examples

let cmd = bkt::CommandDesc::new(["echo", "Hello World!"]);
let with_cwd = bkt::CommandDesc::new(["ls"]).with_cwd();
let with_env = bkt::CommandDesc::new(["date"]).with_env("TZ");

Implementations§

source§

impl CommandDesc

source

pub fn new<I, S>(command: I) -> Self
where I: IntoIterator<Item = S>, S: Into<OsString>,

Constructs a CommandDesc instance for the given command line.

let cmd = bkt::CommandDesc::new(["echo", "Hello World!"]);
source

pub fn with_cwd(self) -> Self

Specifies that the current process’ working directory should be included in the cache key. Commands that depend on the working directory (e.g. ls or git status) should call this in order to cache executions in different working directories separately.

§Examples
let cmd = bkt::CommandDesc::new(["pwd"]).with_cwd();
source

pub fn with_env<K>(self, key: K) -> Self
where K: AsRef<OsStr>,

Specifies that the given environment variable should be included in the cache key. Commands that depend on the values of certain environment variables (e.g. LANG, PATH, or TZ) should call this in order to cache such executions separately. Although it’s possible to pass PWD here calling with_cwd() is generally recommended instead for clarity and consistency with subprocesses that don’t read this environment variable.

Note: If the given variable name is not found in the current process’ environment at execution time the variable is not included in the cache key, and the execution will be cached as if the environment variable had not been specified at all.

§Examples
let cmd = bkt::CommandDesc::new(["date"]).with_env("TZ");
source

pub fn with_envs<I, E>(self, envs: I) -> Self
where I: IntoIterator<Item = E>, E: AsRef<OsStr>,

Specifies that the given environment variables should be included in the cache key. Commands that depend on the values of certain environment variables (e.g. LANG, PATH, or TZ) should call this in order to cache such executions separately. Although it’s possible to pass PWD here calling with_cwd() is generally recommended instead for clarity and consistency with subprocesses that don’t read this environment variable.

Note: If a given variable name is not found in the current process’ environment at execution time that variable is not included in the cache key, and the execution will be cached as if the environment variable had not been specified at all.

§Examples
let cmd = bkt::CommandDesc::new(["date"]).with_envs(["LANG", "TZ"]);
source

pub fn with_modtime<P>(self, file: P) -> Self
where P: AsRef<Path>,

Specifies that the modification time of the given file should be included in the cache key, causing cached commands to be invalidated if the file is modified in the future. Commands that depend on the contents of certain files should call this in order to invalidate the cache when the file changes.

It is recommended to pass absolute paths when this is used along with with_cwd() or CommandState::with_working_dir() to avoid any ambiguity in how relative paths are resolved.

Note: If the given path is not found at execution time the file is not included in the cache key, and the execution will be cached as if the file had not been specified at all.

§Examples
let cmd = bkt::CommandDesc::new(["..."]).with_modtime("/etc/passwd");
source

pub fn with_modtimes<I, P>(self, files: I) -> Self
where I: IntoIterator<Item = P>, P: AsRef<Path>,

Specifies that the modification time of the given files should be included in the cache key, causing cached commands to be invalidated if the files are modified in the future. Commands that depend on the contents of certain files should call this in order to invalidate the cache when the files change.

It is recommended to pass absolute paths when this is used along with with_cwd() or CommandState::with_working_dir() to avoid any ambiguity in how relative paths are resolved.

Note: If a given path is not found at execution time that file is not included in the cache key, and the execution will be cached as if the file had not been specified at all.

§Examples
let cmd = bkt::CommandDesc::new(["..."]).with_modtimes(["/etc/passwd", "/etc/group"]);
source

pub fn with_discard_failures(self, discard_failures: bool) -> Self

Specifies this command should only be cached if it succeeds - i.e. it returns a zero exit code. Commands that return a non-zero exit code will not be cached, and therefore will be rerun on each invocation (until they succeed).

WARNING: use this option with caution. Discarding invocations that fail can overload downstream resources that were protected by the caching layer limiting QPS. For example, if a website is rejecting a fraction of requests to shed load and then clients start sending more requests when their attempts fail the website could be taken down outright by the added load. In other words, using this option can lead to accidental DDoSes.

let cmd = bkt::CommandDesc::new(["grep", "foo", "/var/log/syslog"]).with_discard_failures(true);
source

pub fn capture_state(&self) -> Result<CommandState>

Constructs a CommandState instance, capturing application state that will be used in the cache key, such as the current working directory and any specified environment variables. The CommandState can also be further customized to change how the subprocess is invoked.

Most callers should be able to pass a CommandDesc directly to a Bkt instance without needing to construct a separate CommandState first.

Example:

let bkt = bkt::Bkt::in_tmp()?;
let cmd = bkt::CommandDesc::new(["foo", "bar"]).capture_state()?.with_env("FOO", "BAR");
let (result, age) = bkt.retrieve(cmd, Duration::from_secs(3600))?;

Trait Implementations§

source§

impl Clone for CommandDesc

source§

fn clone(&self) -> CommandDesc

Returns a copy 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 CommandDesc

source§

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

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

impl<'de> Deserialize<'de> for CommandDesc

source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
source§

impl Hash for CommandDesc

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 PartialEq for CommandDesc

source§

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

This method tests for self and other values to be equal, and is used by ==.
1.0.0 · source§

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

This method tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
source§

impl Serialize for CommandDesc

source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more
source§

impl TryFrom<&CommandDesc> for CommandState

§

type Error = Error

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

fn try_from(desc: &CommandDesc) -> Result<Self>

Performs the conversion.
source§

impl Eq for CommandDesc

source§

impl StructuralEq for CommandDesc

source§

impl StructuralPartialEq for CommandDesc

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> 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,

§

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>,

§

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>,

§

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.
§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

§

fn vzip(self) -> V

source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,