1
0
mirror of https://github.com/o2sh/onefetch synced 2024-06-30 22:54:20 +00:00
This commit is contained in:
Ossama Hjaji 2024-05-07 14:51:17 +02:00 committed by GitHub
parent 2c76c06583
commit 2bc5aed55b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 23 additions and 51 deletions

View File

@ -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<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,

View File

@ -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<Option<MyRegex>>,
no_bots: Option<MyRegex>,
max_churn_pool_size: Option<usize>,
no_merges: bool,
) -> Result<GitMetrics> {
@ -30,7 +28,6 @@ pub fn traverse_commit_graph(
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());
@ -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<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>>>,
@ -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<MyRegex>,
bot_regex_pattern: Option<&MyRegex>,
number_of_commits_by_signature: &mut HashMap<Sig, usize>,
) -> 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<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())
})
}
@ -297,28 +281,9 @@ fn is_bot(author_name: &BString, bot_regex_pattern: &Option<MyRegex>) -> 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<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)]
@ -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(())
}

View File

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