scarb_metadata/command/
scarb_command.rs

1use std::ffi::OsStr;
2use std::io;
3use std::path::PathBuf;
4
5use crate::command::internal_command::InternalScarbCommandBuilder;
6use thiserror::Error;
7
8/// Error thrown while trying to execute `scarb` command.
9#[derive(Error, Debug)]
10#[non_exhaustive]
11pub enum ScarbCommandError {
12    /// Failed to read `scarb` output.
13    #[error("failed to read `scarb` output")]
14    Io(#[from] io::Error),
15    /// Error during execution of `scarb` command.
16    #[error("`scarb` command exited with error")]
17    ScarbError,
18}
19
20/// A builder for `scarb` command invocation.
21#[derive(Clone, Debug, Default)]
22pub struct ScarbCommand {
23    inner: InternalScarbCommandBuilder,
24}
25
26impl ScarbCommand {
27    /// Creates a default `scarb` command, which will look for `scarb` in `$PATH` and
28    /// for `Scarb.toml` in the current directory or its ancestors.
29    pub fn new() -> Self {
30        let mut cmd = InternalScarbCommandBuilder::new();
31        cmd.inherit_stderr();
32        cmd.inherit_stdout();
33        Self { inner: cmd }
34    }
35
36    /// Path to `scarb` executable.
37    ///
38    /// If not set, this will use the `$SCARB` environment variable, and if that is not set, it
39    /// will simply be `scarb` and the system will look it up in `$PATH`.
40    pub fn scarb_path(&mut self, path: impl Into<PathBuf>) -> &mut Self {
41        self.inner.scarb_path(path);
42        self
43    }
44
45    /// Path to `Scarb.toml`.
46    ///
47    /// If not set, this will look for `Scarb.toml` in the current directory or its ancestors.
48    pub fn manifest_path(&mut self, path: impl Into<PathBuf>) -> &mut Self {
49        self.inner.manifest_path(path);
50        self
51    }
52
53    /// Current directory of the `scarb metadata` process.
54    pub fn current_dir(&mut self, path: impl Into<PathBuf>) -> &mut Self {
55        self.inner.current_dir(path);
56        self
57    }
58
59    /// Adds an argument to pass to `scarb`.
60    pub fn arg<S: AsRef<OsStr>>(&mut self, arg: S) -> &mut Self {
61        self.inner.arg(arg);
62        self
63    }
64
65    /// Adds multiple arguments to pass to `scarb`.
66    pub fn args<I, S>(&mut self, args: I) -> &mut Self
67    where
68        I: IntoIterator<Item = S>,
69        S: AsRef<OsStr>,
70    {
71        self.inner.args(args);
72        self
73    }
74
75    /// Inserts or updates an environment variable mapping.
76    pub fn env(&mut self, key: impl AsRef<OsStr>, val: impl AsRef<OsStr>) -> &mut Self {
77        self.inner.env(key, val);
78        self
79    }
80
81    /// Adds or updates multiple environment variable mappings.
82    pub fn envs<I, K, V>(&mut self, vars: I) -> &mut Self
83    where
84        I: IntoIterator<Item = (K, V)>,
85        K: AsRef<OsStr>,
86        V: AsRef<OsStr>,
87    {
88        self.inner.envs(vars);
89        self
90    }
91
92    /// Removes an environment variable mapping.
93    pub fn env_remove(&mut self, key: impl AsRef<OsStr>) -> &mut Self {
94        self.inner.env_remove(key);
95        self
96    }
97
98    /// Clears the entire environment map for the child process.
99    pub fn env_clear(&mut self) -> &mut Self {
100        self.inner.env_clear();
101        self
102    }
103
104    /// Runs configured `scarb` command.
105    pub fn run(&self) -> Result<(), ScarbCommandError> {
106        let mut cmd = self.inner.command();
107        if cmd.status()?.success() {
108            Ok(())
109        } else {
110            Err(ScarbCommandError::ScarbError)
111        }
112    }
113}