lintje 0.11.1

Lintje is an opinionated linter for Git.
use std::fs::OpenOptions;
use std::io::Write;
#[cfg(target_family = "unix")]
use std::os::unix::fs::PermissionsExt;
use std::path::Path;

#[derive(clap::ArgEnum, Clone, Debug)]
pub enum CommitHook {
    CommitMsg,
    PostCommit,
}

impl CommitHook {
    pub fn name(&self) -> String {
        match self {
            CommitHook::CommitMsg => "commit-msg",
            CommitHook::PostCommit => "post-commit",
        }
        .to_string()
    }

    pub fn command(&self) -> String {
        match self {
            CommitHook::CommitMsg => "\n\nlintje --hook-message-file=$1",
            CommitHook::PostCommit => "\n\nlintje",
        }
        .to_string()
    }
}

pub fn install_hook(hook: &CommitHook) -> Result<String, String> {
    let file_path = format!(".git/hooks/{}", hook.name());
    let hook_file = Path::new(&file_path);
    match OpenOptions::new()
        .write(true)
        .create(true)
        .append(true)
        .open(hook_file)
    {
        Ok(mut file) => {
            if let Err(e) = set_file_permissions(hook_file) {
                return Err(format!(
                    "Cannot set file permissions for: {:?}\n{:?}",
                    hook_file, e
                ));
            }
            let hook_content = hook.command();
            match file.write_all(hook_content.as_bytes()) {
                Ok(()) => Ok(hook_file.to_str().unwrap().to_string()),
                Err(e) => Err(format!(
                    "Unable to open write to Git hook file: {}\n{}",
                    hook_file.to_str().unwrap(),
                    e
                )),
            }
        }
        Err(e) => Err(format!(
            "Unable to open Git hook file: {}\n{}",
            hook_file.to_str().unwrap(),
            e
        )),
    }
}

#[cfg(target_family = "unix")]
fn set_file_permissions(path: &Path) -> std::io::Result<()> {
    std::fs::set_permissions(path, std::fs::Permissions::from_mode(0o744))
}

#[cfg(not(target_family = "unix"))]
fn set_file_permissions(file: &Path) -> std::io::Result<()> {
    Ok(())
}