From 44eb962938c52a458e432dcbd09f3af5707cd8e3 Mon Sep 17 00:00:00 2001 From: Hatter Jiang Date: Sat, 28 Nov 2020 10:48:00 +0800 Subject: [PATCH] feat: add util --- src/cmd_install.rs | 2 ++ src/main.rs | 1 + src/util.rs | 70 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 73 insertions(+) create mode 100644 src/util.rs diff --git a/src/cmd_install.rs b/src/cmd_install.rs index 44c3641..1ca826d 100644 --- a/src/cmd_install.rs +++ b/src/cmd_install.rs @@ -1,5 +1,6 @@ use clap::{ArgMatches, SubCommand, App}; use crate::cmd::{Command, CommandError}; +use crate::util as commit_msg_uti; pub struct CommandImpl; @@ -12,6 +13,7 @@ impl Command for CommandImpl { } fn run(&self, _arg_matches: &ArgMatches, _sub_arg_matches: &ArgMatches) -> CommandError { + commit_msg_uti::install_commit_msg(false); Ok(()) } } \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 421cd29..8622adf 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,6 @@ #[macro_use] extern crate rust_util; +mod util; mod cmd; mod cmd_default; mod cmd_usage; diff --git a/src/util.rs b/src/util.rs new file mode 100644 index 0000000..faca315 --- /dev/null +++ b/src/util.rs @@ -0,0 +1,70 @@ +use std::{env, fs, process}; +use std::path::PathBuf; +use std::process::Command; +use std::os::unix::fs::PermissionsExt; +use rust_util::util_term::{BOLD, END}; + +pub fn exit_with_error() -> ! { + process::exit(1) +} + +pub fn exit_with_error_message(msg: &str) -> ! { + failure!("{}", msg); + exit_with_error() +} + +pub fn copy_file_and_apply_executable_permission(from: &PathBuf, to: &PathBuf) { + information!("Copy file: {:?} to: {:?}", from, to); + let from_content = fs::read(&from).unwrap_or_else(|e| + exit_with_error_message(&format!("Read file: {:?}, failed: {}", from, e)) + ); + fs::write(to, from_content).unwrap_or_else(|e| + exit_with_error_message(&format!("Write file: {:?}, failed: {}", to, e)) + ); + fs::set_permissions(to, PermissionsExt::from_mode(0o755)).unwrap_or_else(|e| + exit_with_error_message(&format!("Apply executable permission on file: {:?}, failed: {}", to, e)) + ); +} + +pub 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 is_verbose() { print_info(&format!("Check git path: {:?}", p)); } + if p.join(".git").is_dir() { + // if is_verbose() { print_ok(&format!("Found git path: {:?}", p)); } + return Some(p); + } + if !p.pop() { return None; } + } +} + +pub fn search_git_root_path_e() -> PathBuf { + search_git_root_path().unwrap_or_else(|| exit_with_error_message("Git root path not found!")) +} + +pub fn install_commit_msg(force: bool) { + let mut commig_msg_exec_file = PathBuf::from(env::args().next().expect("Get args0 failed!")); + if !commig_msg_exec_file.exists() { + let which_output = Command::new("which").arg(commig_msg_exec_file).output().unwrap_or_else( + |e| exit_with_error_message(&format!("Error in get git root path: {}", e)) + ); + commig_msg_exec_file = PathBuf::from(&String::from_utf8(which_output.stdout).unwrap_or_else( + |e| exit_with_error_message(&format!("Error in get git root path: {}", e)) + )); + } + + 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)); + } + let git_hooks_commit_msg = git_hooks.join("commit-msg"); + if git_hooks_commit_msg.exists() && !force { + exit_with_error_message(&format!("File {:?} exists! or try {}forceinstall{}.", git_hooks_commit_msg, BOLD, END)); + } + + copy_file_and_apply_executable_permission(&commig_msg_exec_file, &git_hooks_commit_msg); + + success!("Install commit-msg to repo successed!"); +}