use std::process::Command;
use proc_macro2::Span;
use syn::{Error, Result};
pub fn run_command(args: Vec<&str>, path: &std::path::Path) -> Result<()> {
execute_command(Command::new(&args[0]).args(&args[1..]).current_dir(path))?;
Ok(())
}
fn execute_command(command: &mut Command) -> Result<std::process::ExitStatus> {
let status = command.status().map_err(|error| {
Error::new(
Span::call_site(),
format!("failed to execute command: {}", error),
)
})?;
verbose_command_error(status).map_err(|message| Error::new(Span::call_site(), message))
}
fn verbose_command_error(
status: std::process::ExitStatus,
) -> std::result::Result<std::process::ExitStatus, String> {
if status.success() {
Ok(status)
} else if let Some(status) = status.code() {
Err(format!("external command exited with status {}", status))
} else {
#[cfg(target_family = "unix")]
{
use std::os::unix::process::ExitStatusExt;
if let Some(signal) = status.signal() {
Err(format!("external command killed by signal {}", signal))
} else {
Err(format!("external command failed, but did not exit and was not killed by a signal, this can only be a bug in std::process"))
}
}
#[cfg(not(target_family = "unix"))]
{
Err(format!("external command killed by signal"))
}
}
}