Skip to content

Commit 98f5756

Browse files
committed
merge authors by signature ~ username + email
1 parent 9ba9533 commit 98f5756

File tree

1 file changed

+42
-27
lines changed

1 file changed

+42
-27
lines changed

Diff for: src/onefetch/repo.rs

+42-27
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,28 @@ use git2::{
44
StatusShow,
55
};
66
use regex::Regex;
7+
use std::collections::HashMap;
78
use std::path::Path;
89

910
pub struct Repo<'a> {
1011
repo: &'a Repository,
1112
logs: Vec<Commit<'a>>,
1213
}
1314

15+
#[derive(Hash, PartialEq, Eq)]
16+
pub struct Sig {
17+
name: String,
18+
email: String,
19+
}
20+
21+
impl From<Signature<'_>> for Sig {
22+
fn from(sig: Signature) -> Self {
23+
let name = String::from_utf8_lossy(sig.name_bytes()).into_owned();
24+
let email = String::from_utf8_lossy(sig.email_bytes()).into_owned();
25+
Self { name, email }
26+
}
27+
}
28+
1429
impl<'a> Repo<'a> {
1530
pub fn new(
1631
repo: &'a Repository,
@@ -65,43 +80,43 @@ impl<'a> Repo<'a> {
6580

6681
pub fn get_authors(
6782
&self,
68-
n: usize,
83+
number_of_author: usize,
6984
show_email: bool,
7085
) -> Result<Vec<(String, Option<String>, usize, usize)>> {
71-
let mut authors = std::collections::HashMap::new();
72-
let mut author_name_by_email = std::collections::HashMap::new();
86+
let mut author_to_number_of_commits: HashMap<Sig, usize> = HashMap::new();
7387
let mut total_nbr_of_commits = 0;
7488
let mailmap = self.repo.mailmap()?;
7589
for commit in &self.logs {
7690
let author = commit.author_with_mailmap(&mailmap)?;
77-
let author_name = String::from_utf8_lossy(author.name_bytes()).into_owned();
78-
let author_email = String::from_utf8_lossy(author.email_bytes()).into_owned();
79-
80-
let author_nbr_of_commits = authors.entry(author_email.to_string()).or_insert(0);
81-
author_name_by_email.entry(author_email.to_string()).or_insert(author_name);
91+
let author_nbr_of_commits =
92+
author_to_number_of_commits.entry(Sig::from(author)).or_insert(0);
8293
*author_nbr_of_commits += 1;
8394
total_nbr_of_commits += 1;
8495
}
8596

86-
let mut authors: Vec<(String, usize)> = authors.into_iter().collect();
87-
authors.sort_by(|(_, a_count), (_, b_count)| b_count.cmp(a_count));
88-
89-
authors.truncate(n);
90-
91-
let authors: Vec<(String, Option<String>, usize, usize)> = authors
92-
.into_iter()
93-
.map(|(author_email, author_nbr_of_commits)| {
94-
(
95-
author_name_by_email.get(&author_email).unwrap().trim_matches('\'').to_string(),
96-
show_email.then(|| author_email),
97-
author_nbr_of_commits,
98-
(author_nbr_of_commits as f32 * 100. / total_nbr_of_commits as f32).round()
99-
as usize,
100-
)
101-
})
102-
.collect();
103-
104-
Ok(authors)
97+
let mut authors_sorted_by_number_of_commits: Vec<(Sig, usize)> =
98+
author_to_number_of_commits.into_iter().collect();
99+
100+
authors_sorted_by_number_of_commits
101+
.sort_by(|(_, a_count), (_, b_count)| b_count.cmp(a_count));
102+
103+
authors_sorted_by_number_of_commits.truncate(number_of_author);
104+
105+
let result: Vec<(String, Option<String>, usize, usize)> =
106+
authors_sorted_by_number_of_commits
107+
.into_iter()
108+
.map(|(author, author_nbr_of_commits)| {
109+
(
110+
author.name.clone(),
111+
show_email.then(|| author.email),
112+
author_nbr_of_commits,
113+
(author_nbr_of_commits as f32 * 100. / total_nbr_of_commits as f32).round()
114+
as usize,
115+
)
116+
})
117+
.collect();
118+
119+
Ok(result)
105120
}
106121

107122
pub fn get_date_of_last_commit(&self, iso_time: bool) -> String {

0 commit comments

Comments
 (0)