From 4471f059063b27edb36a5a6931ab66707ff8ff2d Mon Sep 17 00:00:00 2001 From: Hatter Jiang Date: Sun, 19 Jul 2020 16:55:07 +0800 Subject: [PATCH] feat(commit-msg.crs): add custom regexp and usage support --- scripts/commit-msg.crs | 60 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 57 insertions(+), 3 deletions(-) diff --git a/scripts/commit-msg.crs b/scripts/commit-msg.crs index 0feb9b4..4fc10dc 100755 --- a/scripts/commit-msg.crs +++ b/scripts/commit-msg.crs @@ -2,7 +2,6 @@ // cargo-deps: regex="1.3.9" use std::{ env, fs, process }; use std::path::PathBuf; -use std::process::Command; use std::os::unix::fs::PermissionsExt; /// Git commit message format check util @@ -36,7 +35,10 @@ fn main() { exit_with_error_message(&format!("Read commit message failed: {}", e)); }); - let re = regex::Regex::new("^(feat|fix|docs|style|refactor|test|chore)(\\([\\w\\-_]+\\))?:\\s*.*").unwrap(); + let re_str = get_commit_msg_regexp(); + let re = match regex::Regex::new(re_str.trim()) { + Ok(re) => re, Err(e) => exit_with_error_message(&format!("Parse regexp: {}, failed: {}", re_str, e)), + }; let is_commit_message_matches = re.is_match(&commit_message); print_info(&format!("Commit message: {}{}{}", UNDER, commit_message.trim(), END)); @@ -55,7 +57,11 @@ const BOLD: &str = "\x1B[1m"; const UNDER: &str = "\x1B[4m"; const END: &str = "\x1B[0m"; +const DEFAULT_COMMIT_MSG_REGEXP: &str = "^(feat|fix|docs|style|refactor|test|chore)(\\([\\w\\-_.]+\\))?:\\s*.*"; + fn print_usage() { + let usage = get_commit_msg_usage(); + if !usage.is_empty() { print_info(&usage); return; } print_info(&format!(r#"Please follow the commit spec: Format: {b}{e}(){b}: {e} is optional @@ -80,6 +86,54 @@ or mirror: {u}https://hatter.ink/wiki/view_raw.action?__access_token=PUBLIC&id=4 "#, b = BOLD, e = END, u = UNDER)); } +fn search_git_root_path() -> Option { + let mut p = PathBuf::from(".").canonicalize().unwrap_or_else(|e| + exit_with_error_message(&format!("Get current dir failed: {}", e)) + ); + loop { + if p.join(".git").is_dir() { + return Some(p); + } + if !p.pop() { + return None; + } + } +} + +fn search_git_root_path_e() -> PathBuf { + search_git_root_path().unwrap_or_else(|| exit_with_error_message("Git root path not found!")) +} + +fn get_commit_msg_file(file: &str, default_content: &str) -> String { + let mut settings_regexp = search_git_root_path_e().join("settings").join(file); + if settings_regexp.exists() { + print_info(&format!("Found file: {:?}", settings_regexp)); + return fs::read_to_string(settings_regexp).unwrap(); + } + + let mut path_regexp = search_git_root_path_e().join(".git").join("hooks").join(file); + if path_regexp.exists() { + print_info(&format!("Found file: {:?}", path_regexp)); + return fs::read_to_string(path_regexp).unwrap(); + } + + let home_path_regexp = PathBuf::from(env::var("HOME").unwrap()).join(&(".".to_owned() + file)); + if home_path_regexp.exists() { + print_info(&format!("Found file: {:?}", home_path_regexp)); + return fs::read_to_string(home_path_regexp).unwrap(); + } + + default_content.to_owned() +} + +fn get_commit_msg_regexp() -> String { + get_commit_msg_file("commit-msg-regexp", DEFAULT_COMMIT_MSG_REGEXP) +} + +fn get_commit_msg_usage() -> String { + get_commit_msg_file("commit-msg-regexp-usage", "") +} + fn install_commit_msg(force: bool) { let home_path = PathBuf::from(env::var("HOME").unwrap_or_else(|e| { exit_with_error_message(&format!("Get env HOME failed: {}!", e)); @@ -92,7 +146,7 @@ fn install_commit_msg(force: bool) { commit_msg_crs }; - let git_hooks = PathBuf::from(".git").join("hooks"); + let git_hooks = search_git_root_path_e().join(".git").join("hooks"); if !git_hooks.exists() { exit_with_error_message(&format!("Path {:?} NOT exists!", git_hooks)); }