use std::ffi::OsStr;
use std::io;
use std::path::PathBuf;
use crate::command::internal_command::InternalScarbCommandBuilder;
use thiserror::Error;
#[derive(Error, Debug)]
#[non_exhaustive]
pub enum ScarbCommandError {
#[error("failed to read `scarb` output")]
Io(#[from] io::Error),
#[error("`scarb` command exited with error")]
ScarbError,
}
#[derive(Clone, Debug, Default)]
pub struct ScarbCommand {
inner: InternalScarbCommandBuilder,
}
impl ScarbCommand {
pub fn new() -> Self {
let mut cmd = InternalScarbCommandBuilder::new();
cmd.inherit_stderr();
cmd.inherit_stdout();
Self { inner: cmd }
}
pub fn scarb_path(&mut self, path: impl Into<PathBuf>) -> &mut Self {
self.inner.scarb_path(path);
self
}
pub fn manifest_path(&mut self, path: impl Into<PathBuf>) -> &mut Self {
self.inner.manifest_path(path);
self
}
pub fn current_dir(&mut self, path: impl Into<PathBuf>) -> &mut Self {
self.inner.current_dir(path);
self
}
pub fn arg<S: AsRef<OsStr>>(&mut self, arg: S) -> &mut Self {
self.inner.arg(arg);
self
}
pub fn args<I, S>(&mut self, args: I) -> &mut Self
where
I: IntoIterator<Item = S>,
S: AsRef<OsStr>,
{
self.inner.args(args);
self
}
pub fn env(&mut self, key: impl AsRef<OsStr>, val: impl AsRef<OsStr>) -> &mut Self {
self.inner.env(key, val);
self
}
pub fn envs<I, K, V>(&mut self, vars: I) -> &mut Self
where
I: IntoIterator<Item = (K, V)>,
K: AsRef<OsStr>,
V: AsRef<OsStr>,
{
self.inner.envs(vars);
self
}
pub fn env_remove(&mut self, key: impl AsRef<OsStr>) -> &mut Self {
self.inner.env_remove(key);
self
}
pub fn env_clear(&mut self) -> &mut Self {
self.inner.env_clear();
self
}
pub fn run(&self) -> Result<(), ScarbCommandError> {
let mut cmd = self.inner.command();
if cmd.status()?.success() {
Ok(())
} else {
Err(ScarbCommandError::ScarbError)
}
}
}