From 5d0332f51c63c5456a28c8f3f466ad805b2e0626 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Sun, 18 Sep 2022 23:11:41 +0800 Subject: [PATCH] feat: `ein tool hours -b` ignores bots. For now it only considers bots with names containing `[bot]`. --- gitoxide-core/src/hours.rs | 24 +++++++++++++++++++++--- src/porcelain/main.rs | 2 ++ src/porcelain/options.rs | 3 +++ 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/gitoxide-core/src/hours.rs b/gitoxide-core/src/hours.rs index f6c0d6d61d3..c1fe91df728 100644 --- a/gitoxide-core/src/hours.rs +++ b/gitoxide-core/src/hours.rs @@ -8,12 +8,16 @@ use std::{ use anyhow::{anyhow, bail}; use git_repository as git; -use git_repository::{actor, bstr::BString, interrupt, objs, prelude::*, progress, refs::file::ReferenceExt, Progress}; +use git_repository::{ + actor, bstr::BString, bstr::ByteSlice, interrupt, objs, prelude::*, progress, refs::file::ReferenceExt, Progress, +}; use itertools::Itertools; use rayon::prelude::*; /// Additional configuration for the hours estimation functionality. pub struct Context { + /// Ignore github bots which match the `[bot]` search string. + pub ignore_bots: bool, /// Show personally identifiable information before the summary. Includes names and email addresses. pub show_pii: bool, /// Omit unifying identities by name and email which can lead to the same author appear multiple times @@ -35,6 +39,7 @@ pub fn estimate( mut progress: P, Context { show_pii, + ignore_bots, omit_unify_identities, mut out, }: Context, @@ -110,11 +115,17 @@ where let mut current_email = &all_commits[0].email; let mut slice_start = 0; let mut results_by_hours = Vec::new(); + let mut ignored_bot_commits = 0_u32; for (idx, elm) in all_commits.iter().enumerate() { if elm.email != *current_email { - results_by_hours.push(estimate_hours(&all_commits[slice_start..idx])); + let estimate = estimate_hours(&all_commits[slice_start..idx]); slice_start = idx; current_email = &elm.email; + if ignore_bots && estimate.name.contains_str(b"[bot]") { + ignored_bot_commits += estimate.num_commits; + continue; + } + results_by_hours.push(estimate); } } if let Some(commits) = all_commits.get(slice_start..) { @@ -170,7 +181,14 @@ where (1.0 - (num_unique_authors as f32 / num_authors as f32)) * 100.0 )?; } - assert_eq!(total_commits, all_commits.len() as u32, "need to get all commits"); + if ignored_bot_commits != 0 { + writeln!(out, "commits by bots: {}", ignored_bot_commits,)?; + } + assert_eq!( + total_commits, + all_commits.len() as u32 - ignored_bot_commits, + "need to get all commits" + ); Ok(()) } diff --git a/src/porcelain/main.rs b/src/porcelain/main.rs index dd155077972..6de13d10f7c 100644 --- a/src/porcelain/main.rs +++ b/src/porcelain/main.rs @@ -39,6 +39,7 @@ pub fn main() -> Result<()> { crate::porcelain::options::ToolCommands::EstimateHours(crate::porcelain::options::EstimateHours { working_dir, refname, + no_bots, show_pii, omit_unify_identities, }) => { @@ -56,6 +57,7 @@ pub fn main() -> Result<()> { progress, hours::Context { show_pii, + ignore_bots: no_bots, omit_unify_identities, out, }, diff --git a/src/porcelain/options.rs b/src/porcelain/options.rs index af008a87371..e949fed06c2 100644 --- a/src/porcelain/options.rs +++ b/src/porcelain/options.rs @@ -96,6 +96,9 @@ pub struct EstimateHours { /// The name of the ref like 'HEAD' or 'main' at which to start iterating the commit graph. #[clap(default_value("HEAD"))] pub refname: OsString, + /// Ignore github bots which match the `[bot]` search string. + #[clap(short = 'b', long)] + pub no_bots: bool, /// Show personally identifiable information before the summary. Includes names and email addresses. #[clap(short = 'p', long)] pub show_pii: bool,