use crate::git::{Git, Hook};
use strum::IntoEnumIterator;
use std::fs;
use std::io::Write;
use std::os::unix::fs::PermissionsExt;
use std::path::Path;
use log::info;
use miette::{IntoDiagnostic, Result};
impl Hook {
pub fn enable() -> Result<()> {
info!("enabling git hooks.");
for hook in Hook::iter() {
if Git::new().repo.is_some() {
Hook::create_script(&hook)?;
Hook::create_subscripts_caller(&hook)?;
}
}
Ok(())
}
pub fn disable() -> Result<()> {
info!("disabling git hooks.");
let dir = Path::new(".git/hooks/");
if dir.exists() {
fs::remove_dir_all(dir).into_diagnostic()?;
}
Ok(())
}
fn create_subscripts_caller(hook: &Hook) -> Result<()> {
let git = Git::new();
let hook = String::from(hook);
let hook_rel_dir;
if git.repo.unwrap().is_bare() {
hook_rel_dir = format!("./hooks/{}", &hook);
} else {
hook_rel_dir = format!(".git/hooks/{}", &hook);
}
let path = Path::new(&hook_rel_dir);
let mut file = fs::File::create(path).into_diagnostic()?;
let s = format!(
"#!/bin/sh \n\
dir=\"{root}.d\" \n\
for file in \"$dir/*\"; do \n\
./$file \n\
done",
root = hook_rel_dir,
);
file.write_all(s.as_bytes()).into_diagnostic()?;
let metadata = file.metadata().into_diagnostic()?;
let mut perms = metadata.permissions();
perms.set_mode(0o755);
fs::set_permissions(path, perms).into_diagnostic()?;
Ok(())
}
fn create_script(hook: &Hook) -> Result<()> {
let git = Git::new();
let hook = String::from(hook);
#[cfg(debug_assertions)]
let script = format!(
"#!/bin/sh \n\
cargo run --bin \
pipelight trigger \
--flag {} \
--attach\
",
&hook,
);
#[cfg(not(debug_assertions))]
let script = format!(
"#!/bin/sh \n\
pipelight trigger \
--flag {} \
--attach\
",
&hook
);
let hook_rel_dir;
if git.repo.unwrap().is_bare() {
hook_rel_dir = format!("./hooks/{}.d", &hook);
} else {
hook_rel_dir = format!(".git/hooks/{}.d", &hook);
}
let dir_path = Path::new(&hook_rel_dir);
fs::create_dir_all(dir_path).into_diagnostic()?;
let file_path = format!("{}/_pipelight", &hook_rel_dir);
let mut file = fs::File::create(file_path.clone()).into_diagnostic()?;
let bytes = script.as_bytes();
file.write_all(bytes).into_diagnostic()?;
let metadata = file.metadata().into_diagnostic()?;
let mut perms = metadata.permissions();
perms.set_mode(0o755);
fs::set_permissions(file_path, perms).into_diagnostic()?;
Ok(())
}
}