Skip to content

Commit

Permalink
init (#1340)
Browse files Browse the repository at this point in the history
  • Loading branch information
o2sh committed May 7, 2024
1 parent 2c76c06 commit 2bc5aed
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 51 deletions.
11 changes: 9 additions & 2 deletions src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down Expand Up @@ -76,8 +77,14 @@ pub struct InfoCliOptions {
#[arg(long, short, num_args = 1..)]
pub exclude: Vec<String>,
/// Exclude [bot] commits. Use <REGEX> to override the default pattern
#[arg(long, value_name = "REGEX")]
pub no_bots: Option<Option<MyRegex>>,
#[arg(
long,
num_args = 0..=1,
require_equals = true,
default_missing_value = NO_BOTS_DEFAULT_REGEX_PATTERN,
value_name = "REGEX"
)]
pub no_bots: Option<MyRegex>,
/// Ignores merge commits
#[arg(long)]
pub no_merges: bool,
Expand Down
61 changes: 13 additions & 48 deletions src/info/git/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -22,15 +20,14 @@ pub mod sig;

pub fn traverse_commit_graph(
repo: &gix::Repository,
no_bots: &Option<Option<MyRegex>>,
no_bots: Option<MyRegex>,
max_churn_pool_size: Option<usize>,
no_merges: bool,
) -> Result<GitMetrics> {
let mut time_of_most_recent_commit = None;
let mut time_of_first_commit = None;
let mut number_of_commits_by_signature: HashMap<Sig, usize> = 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());

Expand All @@ -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 {
Expand All @@ -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,
)?;
}
Expand Down Expand Up @@ -127,7 +124,7 @@ type NumberOfCommitsBySignature = HashMap<Sig, usize>;
fn get_author_channel(
repo: &gix::Repository,
num_threads: usize,
bot_regex_pattern: &Option<MyRegex>,
bot_regex_pattern: Option<MyRegex>,
mailmap: &gix::mailmap::Snapshot,
) -> (
Vec<JoinHandle<Result<NumberOfCommitsBySignature>>>,
Expand Down Expand Up @@ -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,
)?;
}
Expand Down Expand Up @@ -223,7 +220,7 @@ fn should_break(
fn update_signature_counts(
commit: &gix::Commit,
mailmap: &gix::mailmap::Snapshot,
bot_regex_pattern: &Option<MyRegex>,
bot_regex_pattern: Option<&MyRegex>,
number_of_commits_by_signature: &mut HashMap<Sig, usize>,
) -> Result<()> {
let sig = mailmap.resolve(commit.author()?);
Expand Down Expand Up @@ -275,50 +272,18 @@ fn compute_diff_with_parent(
Ok(())
}

fn get_no_bots_regex(no_bots: &Option<Option<MyRegex>>) -> Result<Option<MyRegex>> {
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<MyRegex>) -> 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())
})
}

#[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<Option<MyRegex>> = 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<Option<MyRegex>> = 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<Option<MyRegex>> = 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)]
Expand All @@ -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<Option<MyRegex>> = Some(None);
let regex = get_no_bots_regex(&no_bots)?;
assert_eq!(is_bot(&author_name.into(), &regex), expected);
let from_str = MyRegex::from_str(NO_BOTS_DEFAULT_REGEX_PATTERN);
let no_bots: Option<MyRegex> = Some(from_str?);
assert_eq!(is_bot(&author_name.into(), no_bots.as_ref()), expected);
Ok(())
}

Expand Down
2 changes: 1 addition & 1 deletion src/info/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ pub fn build_info(cli_options: &CliOptions) -> Result<Info> {

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,
)?;
Expand Down

0 comments on commit 2bc5aed

Please sign in to comment.