x-git-hooks 0.0.1

Git Hooks Manager
Documentation
use crate::config::{GitHooksConfig, GitHooksMode};
use crate::fs::{create_directory, write_file};

const HOOK_MULTI_MODE_SAMPLE_SCRIPT: &str = include_str!("scripts/multi-mode-sample-script");
const HOOK_MULTI_MODE_RUNNER: &str = include_str!("scripts/multi-mode-runner");
const HOOK_SINGLE_MODE_RUNNER: &str = include_str!("scripts/single-mode-runner");

const HOOK_NAMES: [&str; 19] = [
    "applypatch-msg",
    "pre-applypatch",
    "post-applypatch",
    "pre-commit",
    "pre-merge-commit",
    "prepare-commit-msg",
    "commit-msg",
    "post-commit",
    "pre-rebase",
    "post-checkout",
    "post-merge",
    "pre-push",
    "reference-transaction",
    "pre-auto-gc",
    "post-rewrite",
    "rebase",
    "sendemail-validate",
    "fsmonitor-watchman",
    "post-index-change",
];

fn is_valid_hook_name(hook_name: &str) -> bool {
    HOOK_NAMES.iter().any(|v| v == &hook_name)
}

pub fn add_hook(config: &GitHooksConfig, hook_name: &str) -> Result<(), String> {
    match is_valid_hook_name(hook_name) {
        true => (),
        false => return Err("invalid hook name".to_string()),
    };

    if !config.hooks_path.exists() {
        create_directory(&config.hooks_path).unwrap_or_else(|_| {
            panic!(
                "failed to create hooks directory: {}",
                &config.hooks_path.to_str().unwrap()
            )
        })
    }

    let hook_path = config.hooks_path.join(hook_name);

    if config.mode == GitHooksMode::Single && !hook_path.exists() {
        write_file(&hook_path, HOOK_SINGLE_MODE_RUNNER, true)?;
    }

    if config.mode == GitHooksMode::Multi {
        if !hook_path.exists() {
            write_file(&hook_path, HOOK_MULTI_MODE_RUNNER, true)?;
        }

        let scripts_path = config.hooks_path.join(format!(".{}", hook_name));

        if !scripts_path.exists() {
            create_directory(&scripts_path).unwrap_or_else(|_| {
                panic!("failed to create scripts directory for hook: {}", hook_name)
            });

            write_file(
                &scripts_path.join("sample-script"),
                HOOK_MULTI_MODE_SAMPLE_SCRIPT,
                true,
            )?;
        }
    }

    Ok(())
}