Skip to content

Commit 6fbad3b

Browse files
authored
Merge pull request #44 from nikofil/master
Display current commit and its references as well as repository size
2 parents 34bd253 + 004e687 commit 6fbad3b

File tree

1 file changed

+92
-1
lines changed

1 file changed

+92
-1
lines changed

Diff for: src/main.rs

+92-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,13 +28,15 @@ 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)>,
3435
authors: Vec<String>,
3536
last_change: String,
3637
repo: String,
3738
commits: String,
39+
repo_size: String,
3840
number_of_lines: usize,
3941
license: String,
4042
}
@@ -54,6 +56,13 @@ impl fmt::Display for Info {
5456
self.project_name
5557
)?;
5658

59+
writeln!(
60+
buffer,
61+
"{}{}",
62+
"HEAD: ".color(color).bold(),
63+
self.current_commit
64+
)?;
65+
5766
writeln!(
5867
buffer,
5968
"{}{}",
@@ -122,6 +131,12 @@ impl fmt::Display for Info {
122131
"Lines of code: ".color(color).bold(),
123132
self.number_of_lines
124133
)?;
134+
writeln!(
135+
buffer,
136+
"{}{}",
137+
"Repository size: ".color(color).bold(),
138+
self.repo_size
139+
)?;
125140
writeln!(
126141
buffer,
127142
"{}{}",
@@ -220,6 +235,30 @@ fn true_len(line: &str) -> usize {
220235
.len()
221236
}
222237

238+
struct CommitInfo {
239+
commit: Oid,
240+
refs: Vec<String>,
241+
}
242+
243+
impl CommitInfo {
244+
fn new(commit: Oid, refs: Vec<String>) -> CommitInfo {
245+
CommitInfo { commit, refs }
246+
}
247+
}
248+
249+
impl fmt::Display for CommitInfo {
250+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
251+
if self.refs.len() > 0 {
252+
let refs_str = self.refs.iter().map(|ref_name| {
253+
ref_name.as_str()
254+
}).collect::<Vec<&str>>().join(", ");
255+
write!(f, "{} ({})", self.commit, refs_str)
256+
} else {
257+
write!(f, "{}", self.commit)
258+
}
259+
}
260+
}
261+
223262
#[derive(PartialEq, Eq, Hash, Clone)]
224263
enum Language {
225264
Assembly,
@@ -303,20 +342,24 @@ fn main() -> Result<()> {
303342
let dominant_language = languages_stat_vec[0].0.clone();
304343

305344
let authors = get_authors(&dir, 3);
345+
let current_commit_info = get_current_commit_info(&dir)?;
306346
let config = get_configuration(&dir)?;
307347
let version = get_version(&dir)?;
308348
let commits = get_commits(&dir)?;
349+
let repo_size = get_packed_size(&dir)?;
309350
let last_change = get_last_change(&dir)?;
310351

311352
let info = Info {
312353
project_name: config.repository_name,
354+
current_commit: current_commit_info,
313355
version,
314356
dominant_language,
315357
languages: languages_stat_vec,
316358
authors,
317359
last_change,
318360
repo: config.repository_url,
319361
commits,
362+
repo_size,
320363
number_of_lines: get_total_loc(&tokei_langs),
321364
license: project_license(&dir)?,
322365
};
@@ -438,6 +481,26 @@ fn get_commits(dir: &str) -> Result<String> {
438481
}
439482
}
440483

484+
fn get_packed_size(dir: &str) -> Result<String> {
485+
let output = Command::new("git")
486+
.arg("-C")
487+
.arg(dir)
488+
.arg("count-objects")
489+
.arg("-vH")
490+
.output()
491+
.expect("Failed to execute git.");
492+
493+
let output = String::from_utf8_lossy(&output.stdout);
494+
let lines = output.to_string();
495+
let size_line = lines.split("\n").find(|line| {
496+
line.starts_with("size-pack:")
497+
});
498+
match size_line {
499+
None => Ok("??".into()),
500+
Some(size_str) => Ok(size_str[11..].into())
501+
}
502+
}
503+
441504
fn is_git_installed() -> bool {
442505
Command::new("git")
443506
.arg("--version")
@@ -527,6 +590,31 @@ fn get_authors(dir: &str, n: usize) -> Vec<String> {
527590
authors
528591
}
529592

593+
fn get_current_commit_info(dir: &str) -> Result<CommitInfo> {
594+
let repo = Repository::open(dir).map_err(|_| Error::NotGitRepo)?;
595+
let head = repo.head().map_err(|_| Error::ReferenceInfoError)?;
596+
let head_oid = head.target().ok_or(Error::ReferenceInfoError)?;
597+
let refs = repo.references().map_err(|_| Error::ReferenceInfoError)?;
598+
let refs_info = refs.into_iter().filter_map(|reference| {
599+
match reference {
600+
Ok(reference) => {
601+
match (reference.target(), reference.shorthand()) {
602+
(Some(oid), Some(shorthand)) if oid == head_oid => {
603+
Some(if reference.is_tag() {
604+
String::from("tags/") + shorthand
605+
} else {
606+
String::from(shorthand)
607+
})
608+
},
609+
_ => None
610+
}
611+
},
612+
Err(_) => None,
613+
}
614+
}).collect::<Vec<String>>();
615+
Ok(CommitInfo::new(head_oid, refs_info))
616+
}
617+
530618
fn get_total_loc(languages: &tokei::Languages) -> usize {
531619
languages
532620
.values()
@@ -670,6 +758,8 @@ enum Error {
670758
ReadDirectory,
671759
/// Not in a Git Repo
672760
NotGitRepo,
761+
/// Error while getting branch info
762+
ReferenceInfoError,
673763
}
674764

675765
impl fmt::Debug for Error {
@@ -680,6 +770,7 @@ impl fmt::Debug for Error {
680770
Error::NoGitData => "Could not retrieve git configuration data",
681771
Error::ReadDirectory => "Could not read directory",
682772
Error::NotGitRepo => "This is not a Git Repo",
773+
Error::ReferenceInfoError => "Error while retrieving reference information",
683774
};
684775
write!(f, "{}", content)
685776
}

0 commit comments

Comments
 (0)