Skip to content

Commit bde2d86

Browse files
committed
Display current commit and its references' names
Signed-off-by: Nikos Filippakis <[email protected]>
1 parent 34bd253 commit bde2d86

File tree

1 file changed

+63
-1
lines changed

1 file changed

+63
-1
lines changed

src/main.rs

+63-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ extern crate clap;
88

99
use colored::Color;
1010
use colored::*;
11-
use git2::Repository;
11+
use git2::{Repository, Oid};
1212
use license::License;
1313
use clap::{App, Arg};
1414
use std::{
@@ -28,6 +28,7 @@ type Result<T> = result::Result<T, Error>;
2828

2929
struct Info {
3030
project_name: String,
31+
current_commit: CommitInfo,
3132
version: String,
3233
dominant_language: Language,
3334
languages: Vec<(Language, f64)>,
@@ -54,6 +55,13 @@ impl fmt::Display for Info {
5455
self.project_name
5556
)?;
5657

58+
writeln!(
59+
buffer,
60+
"{}{}",
61+
"HEAD: ".color(color).bold(),
62+
self.current_commit
63+
)?;
64+
5765
writeln!(
5866
buffer,
5967
"{}{}",
@@ -220,6 +228,30 @@ fn true_len(line: &str) -> usize {
220228
.len()
221229
}
222230

231+
struct CommitInfo {
232+
commit: Oid,
233+
refs: Vec<String>,
234+
}
235+
236+
impl CommitInfo {
237+
fn new(commit: Oid, refs: Vec<String>) -> CommitInfo {
238+
CommitInfo { commit, refs }
239+
}
240+
}
241+
242+
impl fmt::Display for CommitInfo {
243+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
244+
if self.refs.len() > 0 {
245+
let refs_str = self.refs.iter().map(|ref_name| {
246+
ref_name.as_str()
247+
}).collect::<Vec<&str>>().join(", ");
248+
write!(f, "{} ({})", self.commit, refs_str)
249+
} else {
250+
write!(f, "{}", self.commit)
251+
}
252+
}
253+
}
254+
223255
#[derive(PartialEq, Eq, Hash, Clone)]
224256
enum Language {
225257
Assembly,
@@ -303,13 +335,15 @@ fn main() -> Result<()> {
303335
let dominant_language = languages_stat_vec[0].0.clone();
304336

305337
let authors = get_authors(&dir, 3);
338+
let current_commit_info = get_current_commit_info(&dir)?;
306339
let config = get_configuration(&dir)?;
307340
let version = get_version(&dir)?;
308341
let commits = get_commits(&dir)?;
309342
let last_change = get_last_change(&dir)?;
310343

311344
let info = Info {
312345
project_name: config.repository_name,
346+
current_commit: current_commit_info,
313347
version,
314348
dominant_language,
315349
languages: languages_stat_vec,
@@ -527,6 +561,31 @@ fn get_authors(dir: &str, n: usize) -> Vec<String> {
527561
authors
528562
}
529563

564+
fn get_current_commit_info(dir: &str) -> Result<CommitInfo> {
565+
let repo = Repository::open(dir).map_err(|_| Error::NotGitRepo)?;
566+
let head = repo.head().map_err(|_| Error::ReferenceInfoError)?;
567+
let head_oid = head.target().ok_or(Error::ReferenceInfoError)?;
568+
let refs = repo.references().map_err(|_| Error::ReferenceInfoError)?;
569+
let refs_info = refs.into_iter().filter_map(|reference| {
570+
match reference {
571+
Ok(reference) => {
572+
match (reference.target(), reference.shorthand()) {
573+
(Some(oid), Some(shorthand)) if oid == head_oid => {
574+
Some(if reference.is_tag() {
575+
String::from("tags/") + shorthand
576+
} else {
577+
String::from(shorthand)
578+
})
579+
},
580+
_ => None
581+
}
582+
},
583+
Err(_) => None,
584+
}
585+
}).collect::<Vec<String>>();
586+
Ok(CommitInfo::new(head_oid, refs_info))
587+
}
588+
530589
fn get_total_loc(languages: &tokei::Languages) -> usize {
531590
languages
532591
.values()
@@ -670,6 +729,8 @@ enum Error {
670729
ReadDirectory,
671730
/// Not in a Git Repo
672731
NotGitRepo,
732+
/// Error while getting branch info
733+
ReferenceInfoError,
673734
}
674735

675736
impl fmt::Debug for Error {
@@ -680,6 +741,7 @@ impl fmt::Debug for Error {
680741
Error::NoGitData => "Could not retrieve git configuration data",
681742
Error::ReadDirectory => "Could not read directory",
682743
Error::NotGitRepo => "This is not a Git Repo",
744+
Error::ReferenceInfoError => "Error while retrieving reference information",
683745
};
684746
write!(f, "{}", content)
685747
}

0 commit comments

Comments
 (0)