use super::error::StorageError;
use std::process::{Command, Output};
pub fn run(cmd: &str, args: &[&str]) -> Result<Output, StorageError> {
let full_cmd = format!("{} {}", cmd, args.join(" "));
log::debug!("executing: {}", full_cmd);
let output =
Command::new(cmd)
.args(args)
.output()
.map_err(|e| StorageError::CommandFailed {
cmd: full_cmd.clone(),
error: e.to_string(),
})?;
let stdout = String::from_utf8_lossy(&output.stdout);
let stderr = String::from_utf8_lossy(&output.stderr);
if !stdout.is_empty() {
log::debug!("stdout: {}", stdout.trim());
}
if !stderr.is_empty() {
log::debug!("stderr: {}", stderr.trim());
}
if !output.status.success() {
return Err(StorageError::CommandFailed {
cmd: full_cmd,
error: stderr.to_string(),
});
}
Ok(output)
}
pub fn run_output(cmd: &str, args: &[&str]) -> Result<String, StorageError> {
let output = run(cmd, args)?;
Ok(String::from_utf8_lossy(&output.stdout).trim().to_string())
}
pub fn run_allow_fail(cmd: &str, args: &[&str]) -> Option<Output> {
let full_cmd = format!("{} {}", cmd, args.join(" "));
log::debug!("executing (allow fail): {}", full_cmd);
match Command::new(cmd).args(args).output() {
Ok(output) => {
let stdout = String::from_utf8_lossy(&output.stdout);
let stderr = String::from_utf8_lossy(&output.stderr);
if !stdout.is_empty() {
log::debug!("stdout: {}", stdout.trim());
}
if !stderr.is_empty() {
log::debug!("stderr: {}", stderr.trim());
}
Some(output)
}
Err(e) => {
log::debug!("command failed to execute: {}", e);
None
}
}
}
pub fn command_exists(cmd: &str) -> bool {
Command::new("which")
.arg(cmd)
.output()
.map(|o| o.status.success())
.unwrap_or(false)
}