use super::{Substrate, SubstrateCommand, SubstrateError, SubstrateResult};
use std::process::Command;
use std::time::Instant;
pub struct LocalSubstrate;
impl Substrate for LocalSubstrate {
fn execute(&self, cmd: SubstrateCommand) -> Result<SubstrateResult, SubstrateError> {
let start = Instant::now();
let mut builder = Command::new(&cmd.program);
builder.args(&cmd.args);
if let Some(ref cwd) = cmd.working_dir {
builder.current_dir(cwd);
}
let inherited_path = std::env::var("PATH").unwrap_or_default();
let augmented = if inherited_path.is_empty() {
"/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin".to_string()
} else {
format!("/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:{inherited_path}")
};
builder.env("PATH", augmented);
for (k, v) in &cmd.env {
builder.env(k, v);
}
let output = builder.output().map_err(|e| {
if e.kind() == std::io::ErrorKind::NotFound {
SubstrateError::NotFound(cmd.program.clone())
} else {
SubstrateError::Io(e)
}
})?;
let duration_ms = start.elapsed().as_millis() as u64;
Ok(SubstrateResult {
stdout: output.stdout,
stderr: output.stderr,
exit_code: output.status.code().unwrap_or(-1),
duration_ms,
})
}
fn is_available(&self) -> bool {
true
}
}