From d447d2306f3da6cfadeada53c4e5e8007c929535 Mon Sep 17 00:00:00 2001 From: o2sh Date: Tue, 7 May 2024 13:21:28 +0200 Subject: [PATCH] init --- src/cli.rs | 11 ++++++-- src/info/git/mod.rs | 61 ++++++++++----------------------------------- src/info/mod.rs | 2 +- 3 files changed, 23 insertions(+), 51 deletions(-) diff --git a/src/cli.rs b/src/cli.rs index 4cb365670..1dae1eced 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -18,6 +18,7 @@ use std::str::FromStr; use strum::IntoEnumIterator; const COLOR_RESOLUTIONS: [&str; 5] = ["16", "32", "64", "128", "256"]; +pub const NO_BOTS_DEFAULT_REGEX_PATTERN: &str = r"(?:-|\s)[Bb]ot$|\[[Bb]ot\]"; #[derive(Clone, Debug, Parser, PartialEq, Eq)] #[command(version, about)] @@ -76,8 +77,14 @@ pub struct InfoCliOptions { #[arg(long, short, num_args = 1..)] pub exclude: Vec, /// Exclude [bot] commits. Use to override the default pattern - #[arg(long, value_name = "REGEX")] - pub no_bots: Option>, + #[arg( + long, + num_args = 0..=1, + require_equals = true, + default_missing_value = NO_BOTS_DEFAULT_REGEX_PATTERN, + value_name = "REGEX" + )] + pub no_bots: Option, /// Ignores merge commits #[arg(long)] pub no_merges: bool, diff --git a/src/info/git/mod.rs b/src/info/git/mod.rs index 7c7591ad3..a77018d39 100644 --- a/src/info/git/mod.rs +++ b/src/info/git/mod.rs @@ -9,9 +9,7 @@ use gix::object::tree::diff::Action; use gix::prelude::ObjectIdExt; use gix::traverse::commit::simple::Sorting; use gix::{Commit, ObjectId}; -use regex::Regex; use std::collections::HashMap; -use std::str::FromStr; use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering}; use std::sync::mpsc::{channel, Sender}; use std::sync::Arc; @@ -22,7 +20,7 @@ pub mod sig; pub fn traverse_commit_graph( repo: &gix::Repository, - no_bots: &Option>, + no_bots: Option, max_churn_pool_size: Option, no_merges: bool, ) -> Result { @@ -30,7 +28,6 @@ pub fn traverse_commit_graph( let mut time_of_first_commit = None; let mut number_of_commits_by_signature: HashMap = HashMap::new(); let mailmap = repo.open_mailmap(); - let bot_regex_pattern = get_no_bots_regex(no_bots)?; let has_commit_graph_traversal_ended = Arc::new(AtomicBool::default()); let total_number_of_commits = Arc::new(AtomicUsize::default()); @@ -57,7 +54,7 @@ pub fn traverse_commit_graph( )?; let author_threads = can_use_author_threads - .then(|| get_author_channel(repo, num_threads, &bot_regex_pattern, &mailmap)); + .then(|| get_author_channel(repo, num_threads, no_bots.clone(), &mailmap)); let mut count = 0; for commit in commit_iter { @@ -73,7 +70,7 @@ pub fn traverse_commit_graph( update_signature_counts( &commit.object()?, &mailmap, - &bot_regex_pattern, + no_bots.as_ref(), &mut number_of_commits_by_signature, )?; } @@ -127,7 +124,7 @@ type NumberOfCommitsBySignature = HashMap; fn get_author_channel( repo: &gix::Repository, num_threads: usize, - bot_regex_pattern: &Option, + bot_regex_pattern: Option, mailmap: &gix::mailmap::Snapshot, ) -> ( Vec>>, @@ -155,7 +152,7 @@ fn get_author_channel( update_signature_counts( &commit, &mailmap, - &bot_regex_pattern, + bot_regex_pattern.as_ref(), &mut number_of_commits_by_signature, )?; } @@ -223,7 +220,7 @@ fn should_break( fn update_signature_counts( commit: &gix::Commit, mailmap: &gix::mailmap::Snapshot, - bot_regex_pattern: &Option, + bot_regex_pattern: Option<&MyRegex>, number_of_commits_by_signature: &mut HashMap, ) -> Result<()> { let sig = mailmap.resolve(commit.author()?); @@ -275,21 +272,8 @@ fn compute_diff_with_parent( Ok(()) } -fn get_no_bots_regex(no_bots: &Option>) -> Result> { - let reg = if let Some(r) = no_bots.clone() { - match r { - Some(p) => Some(p), - None => Some(MyRegex(Regex::from_str(r"(?:-|\s)[Bb]ot$|\[[Bb]ot\]")?)), - } - } else { - None - }; - - Ok(reg) -} - -fn is_bot(author_name: &BString, bot_regex_pattern: &Option) -> bool { - bot_regex_pattern.as_ref().map_or(false, |regex| { +fn is_bot(author_name: &BString, bot_regex_pattern: Option<&MyRegex>) -> bool { + bot_regex_pattern.map_or(false, |regex| { regex.0.is_match(author_name.to_str_lossy().as_ref()) }) } @@ -297,28 +281,9 @@ fn is_bot(author_name: &BString, bot_regex_pattern: &Option) -> bool { #[cfg(test)] mod tests { use super::*; + use crate::cli::NO_BOTS_DEFAULT_REGEX_PATTERN; use rstest::rstest; - - #[test] - fn test_get_no_bots_regex() -> Result<()> { - // Test case 1: no_bots is None - let no_bots: Option> = None; - let result = get_no_bots_regex(&no_bots)?; - assert_eq!(result, None); - - // Test case 2: no_bots is Some(None) - let no_bots: Option> = Some(None); - let result = get_no_bots_regex(&no_bots)?; - assert_eq!(result.unwrap().0.as_str(), r"(?:-|\s)[Bb]ot$|\[[Bb]ot\]"); - - // Test case 3: no_bots is Some(Some(regex)) - let regex = MyRegex(Regex::new(r"foo")?); - let no_bots: Option> = Some(Some(regex)); - let result = get_no_bots_regex(&no_bots)?; - assert_eq!(result.unwrap().0.as_str(), "foo"); - - Ok(()) - } + use std::str::FromStr; #[rstest] #[case("John Doe", false)] @@ -327,9 +292,9 @@ mod tests { #[case("foo-bot", true)] #[case("bot", false)] fn test_is_bot(#[case] author_name: &str, #[case] expected: bool) -> Result<()> { - let no_bots: Option> = Some(None); - let regex = get_no_bots_regex(&no_bots)?; - assert_eq!(is_bot(&author_name.into(), ®ex), expected); + let from_str = MyRegex::from_str(NO_BOTS_DEFAULT_REGEX_PATTERN); + let no_bots: Option = Some(from_str?); + assert_eq!(is_bot(&author_name.into(), no_bots.as_ref()), expected); Ok(()) } diff --git a/src/info/mod.rs b/src/info/mod.rs index e5dd27b9d..a9a48fe9b 100644 --- a/src/info/mod.rs +++ b/src/info/mod.rs @@ -151,7 +151,7 @@ pub fn build_info(cli_options: &CliOptions) -> Result { let git_metrics = traverse_commit_graph( &repo, - &cli_options.info.no_bots, + cli_options.info.no_bots.clone(), cli_options.info.churn_pool_size, cli_options.info.no_merges, )?;