diff --git a/Cargo.lock b/Cargo.lock index 9c3cc07..b745c2f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -944,9 +944,9 @@ dependencies = [ [[package]] name = "rust_util" -version = "0.6.23" +version = "0.6.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6149797f0ee27329552a951e08f4b0482aadb986ad7dfeb2758f9fe1aa0f6669" +checksum = "947d43eb0c81799bdc22bd2c403680ccc60fbee365568662df3e4c7163d3239d" dependencies = [ "lazy_static", "libc", diff --git a/Cargo.toml b/Cargo.toml index dd1cedd..f5d2fa4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,7 +14,7 @@ repository = "https://git.hatter.ink/hatter/cargotool" [dependencies] clap = "2.33.3" toml = "0.5.6" -rust_util = "0.6.23" +rust_util = "0.6.24" crates_io_api = "0.6" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" diff --git a/src/cmd_gitcheck.rs b/src/cmd_gitcheck.rs index 90b25bd..3867956 100644 --- a/src/cmd_gitcheck.rs +++ b/src/cmd_gitcheck.rs @@ -1,10 +1,15 @@ +use std::fs; use clap::{ArgMatches, SubCommand, App, Arg}; -use rust_util::util_git; +use rust_util::{util_git, util_os}; use serde::{Serialize, Deserialize}; use crate::cmd::{Command, CommandResult}; +const GIT_BRANCH_MASTER: &str = "master"; +const GIT_BRANCH_MAIN: &str = "main"; +const GIT_CHECK_JSON: &str = "gitcheck.json"; + // filename: gitcheck.json -#[derive(Serialize, Deserialize, Debug)] +#[derive(Serialize, Deserialize, Debug, Default)] #[serde(rename_all = "camelCase")] struct GitCheckConfig { is_master_protected: Option, // default true @@ -17,7 +22,7 @@ impl GitCheckConfig { } fn is_branch_protected(&self, branch: &str) -> bool { - if branch == "master" { + if branch == GIT_BRANCH_MASTER || branch == GIT_BRANCH_MAIN { return self.is_master_protected(); } match &self.protected_branches { @@ -36,10 +41,20 @@ impl Command for CommandImpl { fn subcommand<'a>(&self) -> App<'a, 'a> { SubCommand::with_name(self.name()).about("Git check subcommand") .arg(Arg::with_name("dir").long("dir").required(false).takes_value(true).help("Git check dir")) + .arg(Arg::with_name("allow-master").long("allow-master").required(false).takes_value(false).help("Allow master")) } fn run(&self, _arg_matches: &ArgMatches, sub_arg_matches: &ArgMatches) -> CommandResult { let dir = sub_arg_matches.value_of("dir"); + let allow_master = sub_arg_matches.is_present("allow-master"); + let git_check_json = match dir { + None => GIT_CHECK_JSON.to_string(), + Some(dir) => util_os::join_path(dir.to_string(), GIT_CHECK_JSON), + }; + let git_check_config = match fs::read_to_string(&git_check_json) { + Ok(s) => serde_json::from_str::(&s).expect(&format!("Parse file failed: {}", GIT_CHECK_JSON)), + Err(_) => GitCheckConfig{ ..Default::default() }, + }; let has_remote_cannotbe_fetched = util_git::git_fetch_dry_run(dir)?; if !has_remote_cannotbe_fetched { failure!("Git repo has not fetched codes"); @@ -55,6 +70,14 @@ impl Command for CommandImpl { failure!("Git repo has un-push changes"); return Ok(-3); } + if let Some(branch) = util_git::git_branch(dir).expect("Get git branch failed") { + if allow_master && (branch == GIT_BRANCH_MASTER || branch == GIT_BRANCH_MAIN) { + // just allow + } else if git_check_config.is_branch_protected(&branch) { + failure!("Git branch check failed, current branch: {} is protected", branch); + return Ok(-4); + } + } Ok(0) } }