use std::path::Path;
use anyhow::{Error, anyhow, bail};
use execute::{Execute, shell};
use is_executable::IsExecutable;
pub fn run_hook(hook_opt: Option<&str>) -> Result<i32, Error> {
let hook = hook_opt.ok_or_else(|| anyhow!("Hook command is empty"))?;
let mut command = shell(hook);
let output = command.execute_output()?;
if let Some(exit_code) = output.status.code() {
if exit_code != 0 {
bail!(
"Error: the hook failed with return code={}. \
I will not continue.",
exit_code
);
}
Ok(exit_code)
} else {
bail!("Error: the hook was interrupted, will not continue.")
}
}
pub fn check_hook_perms(hook_opt: Option<&str>) -> Result<(), Error> {
let hook = hook_opt.ok_or_else(|| anyhow!("Hook command is empty"))?;
let program_name = hook
.split(' ')
.next()
.ok_or_else(|| anyhow!("Could not parse hook command"))?;
let hookpath = Path::new(program_name);
if !hookpath.exists() {
bail!("Error: the hook file does not exist.")
} else if !hookpath.is_executable() {
bail!("Error: the hook file is not executable.")
} else {
Ok(())
}
}