Skip to content

Commit 12df1fa

Browse files
authored
Merge pull request #453 from o2sh/feature/use-mailmap
Use mailmap bindings
2 parents f352e98 + 9b1aa16 commit 12df1fa

File tree

2 files changed

+55
-50
lines changed

2 files changed

+55
-50
lines changed

src/info/mod.rs

Lines changed: 7 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ impl Info {
231231
let number_of_branches = internal_repo.get_number_of_branches()?;
232232
let creation_date = internal_repo.get_creation_date(config.iso_time)?;
233233
let number_of_commits = internal_repo.get_number_of_commits();
234-
let authors = internal_repo.get_authors(config.number_of_authors, config.show_email);
234+
let authors = internal_repo.get_authors(config.number_of_authors, config.show_email)?;
235235
let last_change = internal_repo.get_date_of_last_commit(config.iso_time);
236236
let (repo_size, file_count) = internal_repo.get_repo_size();
237237
let workdir = internal_repo.get_work_dir()?;
@@ -431,39 +431,25 @@ impl Serialize for Info {
431431
where
432432
S: serde::Serializer,
433433
{
434-
let mut state = serializer.serialize_struct("Info", 20)?;
435-
436-
// Only collect the version number
437-
let git_version = if !self.git_version.is_empty() {
438-
self.git_version.split(' ').collect::<Vec<_>>()[2]
439-
} else {
440-
""
441-
};
442-
443-
state.serialize_field("gitVersion", &git_version)?;
444-
state.serialize_field("gitUsername", &self.git_username)?;
434+
let mut state = serializer.serialize_struct("Info", 15)?;
435+
let langs: Vec<String> = self.languages.iter().map(|(l, _)| format!("{}", l)).collect();
436+
let auths: Vec<String> = self.authors.iter().map(|(l, _, _, _)| format!("{}", l)).collect();
445437
state.serialize_field("repoName", &self.repo_name)?;
446438
state.serialize_field("numberOfTags", &self.number_of_tags)?;
447439
state.serialize_field("numberOfBranches", &self.number_of_branches)?;
448440
state.serialize_field("headRefs", &self.head_refs)?;
449-
state.serialize_field("pendingChanges", &self.pending_changes)?;
450441
state.serialize_field("version", &self.version)?;
451442
state.serialize_field("creationDate", &self.creation_date)?;
452-
state.serialize_field("languages", &self.languages)?;
453-
454-
let dependencies_split: Vec<String> =
455-
self.dependencies.split(' ').map(|s| s.to_string()).collect();
456-
457-
state.serialize_field("dependencies", &dependencies_split[0])?;
458-
state.serialize_field("authors", &self.authors)?;
443+
state.serialize_field("languages", &langs)?;
444+
state.serialize_field("authors", &auths)?;
459445
state.serialize_field("lastChange", &self.last_change)?;
460446
state.serialize_field("repoUrl", &self.repo_url)?;
461447
state.serialize_field("numberOfCommits", &self.number_of_commits)?;
462448
state.serialize_field("linesOfCode", &self.lines_of_code)?;
463449
state.serialize_field("repoSize", &self.repo_size)?;
464450
state.serialize_field("filesCount", &self.file_count)?;
465451
state.serialize_field("license", &self.license)?;
466-
state.serialize_field("dominantLanguage", &self.dominant_language)?;
452+
467453
state.end()
468454
}
469455
}

src/info/repo.rs

Lines changed: 48 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,28 @@ use git2::{
99
StatusShow,
1010
};
1111
use regex::Regex;
12+
use std::collections::HashMap;
1213
use std::path::Path;
1314

1415
pub struct Repo<'a> {
1516
repo: &'a Repository,
1617
logs: Vec<Commit<'a>>,
1718
}
1819

20+
#[derive(Hash, PartialEq, Eq)]
21+
pub struct Sig {
22+
name: String,
23+
email: String,
24+
}
25+
26+
impl From<Signature<'_>> for Sig {
27+
fn from(sig: Signature) -> Self {
28+
let name = String::from_utf8_lossy(sig.name_bytes()).into_owned();
29+
let email = String::from_utf8_lossy(sig.email_bytes()).into_owned();
30+
Self { name, email }
31+
}
32+
}
33+
1934
impl<'a> Repo<'a> {
2035
pub fn new(
2136
repo: &'a Repository,
@@ -70,42 +85,46 @@ impl<'a> Repo<'a> {
7085

7186
pub fn get_authors(
7287
&self,
73-
n: usize,
88+
number_of_author: usize,
7489
show_email: bool,
75-
) -> Vec<(String, Option<String>, usize, usize)> {
76-
let mut authors = std::collections::HashMap::new();
77-
let mut author_name_by_email = std::collections::HashMap::new();
90+
) -> Result<Vec<(String, Option<String>, usize, usize)>> {
91+
let mut author_to_number_of_commits: HashMap<Sig, usize> = HashMap::new();
7892
let mut total_nbr_of_commits = 0;
93+
let mailmap = self.repo.mailmap()?;
7994
for commit in &self.logs {
80-
let author = commit.author();
81-
let author_name = String::from_utf8_lossy(author.name_bytes()).into_owned();
82-
let author_email = String::from_utf8_lossy(author.email_bytes()).into_owned();
83-
84-
let author_nbr_of_commits = authors.entry(author_email.to_string()).or_insert(0);
85-
author_name_by_email.entry(author_email.to_string()).or_insert(author_name);
95+
let author = match commit.author_with_mailmap(&mailmap) {
96+
Ok(val) => val,
97+
Err(_) => commit.author(),
98+
};
99+
let author_nbr_of_commits =
100+
author_to_number_of_commits.entry(Sig::from(author)).or_insert(0);
86101
*author_nbr_of_commits += 1;
87102
total_nbr_of_commits += 1;
88103
}
89104

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

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

0 commit comments

Comments
 (0)