use std::collections::HashMap;
use std::env;
use std::ffi::{OsStr, OsString};
use std::path::PathBuf;
use std::process::{Command, Stdio};
#[derive(Clone, Debug, Default)]
pub struct InternalScarbCommandBuilder {
args: Vec<OsString>,
current_dir: Option<PathBuf>,
env: HashMap<OsString, Option<OsString>>,
env_clear: bool,
inherit_stderr: bool,
inherit_stdout: bool,
json: bool,
manifest_path: Option<PathBuf>,
scarb_path: Option<PathBuf>,
}
impl InternalScarbCommandBuilder {
pub fn new() -> Self {
Self::default()
}
pub fn scarb_path(&mut self, path: impl Into<PathBuf>) -> &mut Self {
self.scarb_path = Some(path.into());
self
}
pub fn manifest_path(&mut self, path: impl Into<PathBuf>) -> &mut Self {
self.manifest_path = Some(path.into());
self
}
pub fn current_dir(&mut self, path: impl Into<PathBuf>) -> &mut Self {
self.current_dir = Some(path.into());
self
}
pub fn arg<S: AsRef<OsStr>>(&mut self, arg: S) -> &mut Self {
self.args.push(arg.as_ref().to_os_string());
self
}
pub fn args<I, S>(&mut self, args: I) -> &mut Self
where
I: IntoIterator<Item = S>,
S: AsRef<OsStr>,
{
self.args
.extend(args.into_iter().map(|s| s.as_ref().to_os_string()));
self
}
pub fn env(&mut self, key: impl AsRef<OsStr>, val: impl AsRef<OsStr>) -> &mut Self {
self.env.insert(
key.as_ref().to_os_string(),
Some(val.as_ref().to_os_string()),
);
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>,
{
for (ref key, ref val) in vars {
self.env(key, val);
}
self
}
pub fn env_remove(&mut self, key: impl AsRef<OsStr>) -> &mut Self {
let key = key.as_ref();
if self.env_clear {
self.env.remove(key);
} else {
self.env.insert(key.to_os_string(), None);
}
self
}
pub fn env_clear(&mut self) -> &mut Self {
self.env.clear();
self.env_clear = true;
self
}
pub fn inherit_stderr(&mut self) -> &mut Self {
self.inherit_stderr = true;
self
}
pub fn inherit_stdout(&mut self) -> &mut Self {
self.inherit_stdout = true;
self
}
pub fn json(&mut self) -> &mut Self {
self.json = true;
self
}
pub fn command(&self) -> Command {
let scarb = self
.scarb_path
.clone()
.or_else(|| env::var("SCARB").map(PathBuf::from).ok())
.unwrap_or_else(|| PathBuf::from("scarb"));
let mut cmd = Command::new(scarb);
if self.json {
cmd.arg("--json");
}
if let Some(manifest_path) = &self.manifest_path {
cmd.arg("--manifest-path").arg(manifest_path);
}
cmd.args(&self.args);
if let Some(path) = &self.current_dir {
cmd.current_dir(path);
}
for (key, val) in &self.env {
if let Some(val) = val {
cmd.env(key, val);
} else {
cmd.env_remove(key);
}
}
if self.env_clear {
cmd.env_clear();
}
if self.inherit_stderr {
cmd.stderr(Stdio::inherit());
}
if self.inherit_stdout {
cmd.stdout(Stdio::inherit());
}
cmd
}
}