From fe02a4bf0d8a15d57cbdf17640500372d768827f Mon Sep 17 00:00:00 2001 From: Wynd Date: Thu, 24 Apr 2025 16:57:47 +0300 Subject: [PATCH] Added a list of repos and amount of commits in those based on the heatmap data --- benches/heatmap.rs | 4 ++- rust-toolchain.toml | 2 +- src/cli.rs | 5 ++- src/heatmap.rs | 78 ++++++++++++++++++++++++++++++++++----------- src/lib.rs | 14 ++++++++ src/main.rs | 2 ++ 6 files changed, 83 insertions(+), 22 deletions(-) diff --git a/benches/heatmap.rs b/benches/heatmap.rs index 0fdd300..61a6caf 100644 --- a/benches/heatmap.rs +++ b/benches/heatmap.rs @@ -16,12 +16,13 @@ fn main() { let title = mockd::words::sentence(10); let author = mockd::name::full(); let email = mockd::contact::email(); + let repo = "project".to_string(); let time = mockd::datetime::date_range( "2024-01-01T00:00:00Z".to_string(), "2025-01-01T00:00:00Z".to_string(), ) .with_timezone(&Local); - commits.push(Commit::new(id, title, author, email, time)); + commits.push(Commit::new(id, title, author, email, repo, time)); } COMMITS.set(commits).expect("unable to generate commits"); @@ -51,5 +52,6 @@ fn heatmap_generation() { false, 13, heatmap::Format::Chars, + true, ); } diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 97e304e..e821ab8 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,2 +1,2 @@ [toolchain] -channel = "nightly-2025-03-20" +channel = "nightly-2025-04-07" \ No newline at end of file diff --git a/src/cli.rs b/src/cli.rs index 284f027..1b7bf3b 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -53,9 +53,12 @@ pub struct CliArgs { #[arg(short, long("format"), value_enum, default_value_t = Format::Chars)] pub format: Format, + + #[arg(long("list-repos"), default_value_t = false)] + pub list_repos: bool, } fn get_since_date() -> String { let date = Local::now() - Duration::days(365); date.format("%Y-%m-%d").to_string() -} +} \ No newline at end of file diff --git a/src/heatmap.rs b/src/heatmap.rs index d5b7be4..0f11234 100644 --- a/src/heatmap.rs +++ b/src/heatmap.rs @@ -1,5 +1,5 @@ use std::{ - collections::BTreeMap, + collections::{BTreeMap, HashMap}, fmt::{Display, Write}, }; @@ -13,14 +13,17 @@ pub struct Heatmap { since: NaiveDate, until: NaiveDate, commits: Vec, + repo_commits: Vec<(String, Vec)>, highest_count: i32, branches: usize, repos: usize, chunks: Vec, format: Format, + list_repos: bool, } +#[allow(clippy::too_many_arguments)] impl Heatmap { pub fn new( since: NaiveDate, @@ -31,24 +34,37 @@ impl Heatmap { split_months: bool, months_per_row: u16, format: Format, + list_repos: bool, ) -> Self { - let mut heatmap = Self { - since, - until, - commits, - highest_count: 0, - branches, - repos, - chunks: vec![], - format, - }; - + let mut chunks = vec![]; + let mut highest_count: i32 = 0; let mut grouped_commits = BTreeMap::new(); + let mut repo_commits_map: HashMap> = HashMap::new(); + let mut repo_commits = Vec::<(String, Vec)>::new(); - for commit in &heatmap.commits { + for commit in &commits { let commit_day = commit.time.date_naive(); let record = grouped_commits.entry(commit_day).or_insert(0); *record += 1; + + if list_repos { + if repo_commits_map.contains_key(&commit.repo) { + let list = repo_commits_map.get_mut(&commit.repo).unwrap(); + list.push(commit.clone()); + } + else { + repo_commits_map.insert(commit.repo.clone(), vec![commit.clone()]); + } + } + } + + if list_repos { + repo_commits.extend( + repo_commits_map + .into_iter() + .sorted_by(|c1, c2| c2.1.len().cmp(&c1.1.len())) + .map(|e| (e.0, e.1)), + ); } let mut current_day = since; @@ -82,7 +98,7 @@ impl Heatmap { chunk_idx += 1; if chunk_idx > months_per_row - 1 { - heatmap.chunks.push(chunk); + chunks.push(chunk); chunk = Chunk::new(day_of_week); chunk_idx = 0; } @@ -96,8 +112,8 @@ impl Heatmap { match value { Some(val) => { chunk.data[day_of_week as usize].push(*val); - if *val > heatmap.highest_count { - heatmap.highest_count = *val; + if *val > highest_count { + highest_count = *val; } } None => { @@ -110,10 +126,21 @@ impl Heatmap { } if chunk_idx <= months_per_row { - heatmap.chunks.push(chunk); + chunks.push(chunk); } - heatmap + Self { + since, + until, + commits, + repo_commits, + highest_count, + branches, + repos, + chunks, + format, + list_repos, + } } } @@ -142,7 +169,20 @@ impl Display for Heatmap { ) .unwrap(); writeln!(f, "{} {}", authors, authors_label).unwrap(); - writeln!(f, "{} {}\n", commits, commits_label).unwrap(); + writeln!(f, "{} {}", commits, commits_label).unwrap(); + + if self.list_repos { + for (repo, commits_vec) in &self.repo_commits { + let commits_label = if commits_vec.len() == 1 { + "commit" + } + else { + "commits" + }; + writeln!(f, " {}: {} {}", repo, commits_vec.len(), commits_label).unwrap(); + } + } + writeln!(f).unwrap(); for chunk in &self.chunks { chunk.display(self, f); diff --git a/src/lib.rs b/src/lib.rs index 9701268..5f15817 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -53,6 +53,7 @@ pub struct Commit { id: ObjectId, title: String, author: Author, + repo: String, time: DateTime, } @@ -62,6 +63,7 @@ impl Commit { title: String, author: String, email: String, + repo: String, time: DateTime, ) -> Self { Self { @@ -71,6 +73,7 @@ impl Commit { name: author, email, }, + repo, time, } } @@ -153,6 +156,16 @@ pub fn get_commits( for (i, repo_path) in repos.iter().enumerate() { let repo = ThreadSafeRepository::open(repo_path).unwrap(); + let repo_name = match repo_path.parent() { + Some(parent) => parent.file_name(), + None => repo_path.file_name(), + }; + let repo_name = repo_name + .iter() + .filter_map(|r| r.to_str()) + .next() + .unwrap_or("unknown"); + let branch_names = &*branches[i]; let branches = get_repo_branches(&repo, branch_names).unwrap(); @@ -212,6 +225,7 @@ pub fn get_commits( id: c.id, title, author, + repo: repo_name.to_string(), time, }) }) diff --git a/src/main.rs b/src/main.rs index 6e69dcf..cfdbadc 100644 --- a/src/main.rs +++ b/src/main.rs @@ -16,6 +16,7 @@ fn main() -> Result<()> { let split_months = args.split_months; let months_per_row = args.months_per_row; let format = args.format; + let list_repos = args.list_repos; let commits = libgitheatmap::get_commits(args, since, until) .with_context(|| "Could not fetch commit list")?; @@ -29,6 +30,7 @@ fn main() -> Result<()> { split_months, months_per_row, format, + list_repos, ); println!("{heatmap}");