Skip to content

Commit 5d0332f

Browse files
committed
feat: ein tool hours -b ignores bots.
For now it only considers bots with names containing `[bot]`.
1 parent f28783b commit 5d0332f

File tree

3 files changed

+26
-3
lines changed

3 files changed

+26
-3
lines changed

Diff for: gitoxide-core/src/hours.rs

+21-3
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,16 @@ use std::{
88

99
use anyhow::{anyhow, bail};
1010
use git_repository as git;
11-
use git_repository::{actor, bstr::BString, interrupt, objs, prelude::*, progress, refs::file::ReferenceExt, Progress};
11+
use git_repository::{
12+
actor, bstr::BString, bstr::ByteSlice, interrupt, objs, prelude::*, progress, refs::file::ReferenceExt, Progress,
13+
};
1214
use itertools::Itertools;
1315
use rayon::prelude::*;
1416

1517
/// Additional configuration for the hours estimation functionality.
1618
pub struct Context<W> {
19+
/// Ignore github bots which match the `[bot]` search string.
20+
pub ignore_bots: bool,
1721
/// Show personally identifiable information before the summary. Includes names and email addresses.
1822
pub show_pii: bool,
1923
/// Omit unifying identities by name and email which can lead to the same author appear multiple times
@@ -35,6 +39,7 @@ pub fn estimate<W, P>(
3539
mut progress: P,
3640
Context {
3741
show_pii,
42+
ignore_bots,
3843
omit_unify_identities,
3944
mut out,
4045
}: Context<W>,
@@ -110,11 +115,17 @@ where
110115
let mut current_email = &all_commits[0].email;
111116
let mut slice_start = 0;
112117
let mut results_by_hours = Vec::new();
118+
let mut ignored_bot_commits = 0_u32;
113119
for (idx, elm) in all_commits.iter().enumerate() {
114120
if elm.email != *current_email {
115-
results_by_hours.push(estimate_hours(&all_commits[slice_start..idx]));
121+
let estimate = estimate_hours(&all_commits[slice_start..idx]);
116122
slice_start = idx;
117123
current_email = &elm.email;
124+
if ignore_bots && estimate.name.contains_str(b"[bot]") {
125+
ignored_bot_commits += estimate.num_commits;
126+
continue;
127+
}
128+
results_by_hours.push(estimate);
118129
}
119130
}
120131
if let Some(commits) = all_commits.get(slice_start..) {
@@ -170,7 +181,14 @@ where
170181
(1.0 - (num_unique_authors as f32 / num_authors as f32)) * 100.0
171182
)?;
172183
}
173-
assert_eq!(total_commits, all_commits.len() as u32, "need to get all commits");
184+
if ignored_bot_commits != 0 {
185+
writeln!(out, "commits by bots: {}", ignored_bot_commits,)?;
186+
}
187+
assert_eq!(
188+
total_commits,
189+
all_commits.len() as u32 - ignored_bot_commits,
190+
"need to get all commits"
191+
);
174192
Ok(())
175193
}
176194

Diff for: src/porcelain/main.rs

+2
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ pub fn main() -> Result<()> {
3939
crate::porcelain::options::ToolCommands::EstimateHours(crate::porcelain::options::EstimateHours {
4040
working_dir,
4141
refname,
42+
no_bots,
4243
show_pii,
4344
omit_unify_identities,
4445
}) => {
@@ -56,6 +57,7 @@ pub fn main() -> Result<()> {
5657
progress,
5758
hours::Context {
5859
show_pii,
60+
ignore_bots: no_bots,
5961
omit_unify_identities,
6062
out,
6163
},

Diff for: src/porcelain/options.rs

+3
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,9 @@ pub struct EstimateHours {
9696
/// The name of the ref like 'HEAD' or 'main' at which to start iterating the commit graph.
9797
#[clap(default_value("HEAD"))]
9898
pub refname: OsString,
99+
/// Ignore github bots which match the `[bot]` search string.
100+
#[clap(short = 'b', long)]
101+
pub no_bots: bool,
99102
/// Show personally identifiable information before the summary. Includes names and email addresses.
100103
#[clap(short = 'p', long)]
101104
pub show_pii: bool,

0 commit comments

Comments
 (0)