Skip to content
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
5d7b5c8
Add gitoxide as dependency
Byron Mar 29, 2022
1bb11e6
get_logs() with gitoxide
Byron Mar 29, 2022
e3b29b0
Use gitoxide in all methods related to commits
Byron Mar 29, 2022
8df0d19
obtain all but author information on the fly
Byron Mar 30, 2022
954de84
no cloning for `Sig` and `Author` by using BString directly
Byron Mar 30, 2022
0652bbe
Calculate authors on the fly as much as possible; don't store commits
Byron Mar 30, 2022
65da5be
fix commit count
Byron Mar 30, 2022
28deadf
refactor
Byron Mar 30, 2022
2a67bb4
Use `gitoxide` for calculating repo size
Byron Mar 30, 2022
9b2774c
refactor
Byron Mar 30, 2022
c42a1ef
gitoxide for tags; Fix author name and email printing; avoid doing un…
Byron Mar 30, 2022
615e071
Retrieve all branches with `gitoxide`
Byron Mar 30, 2022
2c6016e
get most recent version with gitoxide
Byron Mar 30, 2022
f61761d
Collect branches at current head-commit with gitoxide
Byron Mar 30, 2022
1942087
Assure short ids are not ambiguous
Byron Mar 30, 2022
4fc3334
refactor
Byron Mar 30, 2022
4085053
refactor
Byron Mar 30, 2022
5394f3c
get worktree status in parallel
Byron Mar 30, 2022
d178a5c
gather language statistics in parallel to everything else
Byron Mar 30, 2022
633f0ce
Do three things in parallel, don't wait for `Repo::new()`
Byron Mar 30, 2022
6817e48
Don't take risks when making assumptions about what branches point at
Byron Mar 30, 2022
a5ab965
Tune the object cache based on scienceℒ️
Byron Mar 31, 2022
04ff547
Improve unification of contributors by taking the lower-case email as…
Byron Mar 31, 2022
397b4ae
Compute contributor identity using emails, lowercase, only
Byron Mar 31, 2022
3f94c51
thanks clippy
Byron Mar 31, 2022
82fbbb2
See if running onefetch on itself can reproduce the crashing on windows
Byron Mar 31, 2022
1a494a9
support for shallow clones
Byron Mar 31, 2022
d3d20ed
Use email and name to identify contributors, similar to what git does
Byron Mar 31, 2022
eb753f9
Don't peel references - this would resolve remotes/origin/HEAD to …main…
Byron Mar 31, 2022
927815a
Make clear that the commit count might be truncated due to shallow cl…
Byron Apr 1, 2022
b9b65c7
Update to use gitoxide's built-in shallow clone detection
Byron Apr 1, 2022
fb4d449
Remove additional deduplication of contributors by email
Byron Apr 2, 2022
80f4710
switch gitoxide crates from git to crates.io
Byron Apr 3, 2022
4159442
Improve Cargo.toml dependency declaration
Byron Apr 4, 2022
c6d7cba
Make expect("msg") more informative to help users file an issue
Byron Apr 4, 2022
d00ab45
refactor: put all commit-traversal related initialization into own st…
Byron Apr 4, 2022
7b34b0a
refactor: completely separate `Commits` and `Repo` structure
Byron Apr 4, 2022
b6cd415
refactor: git2 repository can now be owned by the `Repo` type
Byron Apr 4, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,130 changes: 984 additions & 146 deletions Cargo.lock

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,12 @@ section = "utility"
[dependencies]
anyhow = "1.0"
askalono = "0.4.4"
byte-unit = "4.0.14"
byte-unit = "=4.0.13" # to match git-repository's lower requirement, which it needs for MSRV
bytecount = "0.6.2"
clap = {version = "3.1.6", features = ["cargo", "wrap_help"]}
color_quant = "1.1.0"
git2 = {version = "0.14.2", default-features = false}
git-repository = { version = "0.15.0", git = "https://github.com/Byron/gitoxide", branch = "for-onefetch", features = ["max-performance", "unstable", "serde1"] }
image = "0.24.1"
owo-colors = "3.3.0"
regex = "1.5.5"
Expand Down
13 changes: 9 additions & 4 deletions src/info/author.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use git_repository as git;
use serde::ser::SerializeStruct;
use serde::Serialize;

Expand All @@ -10,20 +11,24 @@ pub struct Author {

impl Author {
pub fn new(
name: String,
email: Option<String>,
name: git::bstr::BString,
email: Option<git::bstr::BString>,
nbr_of_commits: usize,
total_nbr_of_commits: usize,
) -> Self {
let contribution =
(nbr_of_commits as f32 * 100. / total_nbr_of_commits as f32).round() as usize;
Self {
name,
email,
name: name.to_string(),
email: email.map(|e| e.to_string()),
nbr_of_commits,
contribution,
}
}

pub fn clear_email(&mut self) {
self.email = None;
}
}

impl std::fmt::Display for Author {
Expand Down
3 changes: 2 additions & 1 deletion src/info/deps/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use anyhow::Result;
use std::collections::HashMap;
use std::path::Path;
use std::{ffi::OsStr, fs};

pub mod package_manager;
Expand All @@ -17,7 +18,7 @@ impl DependencyDetector {
DependencyDetector { package_managers }
}

pub fn get_dependencies(&self, dir: &str) -> Result<String> {
pub fn get_dependencies(&self, dir: &Path) -> Result<String> {
let deps = fs::read_dir(dir)?
.filter_map(std::result::Result::ok)
.map(|entry| entry.path())
Expand Down
20 changes: 9 additions & 11 deletions src/info/head_refs.rs
Original file line number Diff line number Diff line change
@@ -1,31 +1,32 @@
use git2::Oid;
use serde::ser::SerializeStruct;
use serde::Serialize;

pub struct HeadRefs {
commit: Oid,
short_commit_id: String,
refs: Vec<String>,
}

impl HeadRefs {
pub fn new(commit: Oid, refs: Vec<String>) -> HeadRefs {
HeadRefs { commit, refs }
pub fn new(short_commit_id: String, refs: Vec<String>) -> HeadRefs {
HeadRefs {
short_commit_id,
refs,
}
}
}

impl std::fmt::Display for HeadRefs {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
let short_commit = self.commit.to_string().chars().take(7).collect::<String>();
if !self.refs.is_empty() {
let refs_str = self
.refs
.iter()
.map(|ref_name| ref_name.as_str())
.collect::<Vec<&str>>()
.join(", ");
write!(f, "{} ({})", short_commit, refs_str)
write!(f, "{} ({})", self.short_commit_id, refs_str)
} else {
write!(f, "{}", short_commit)
write!(f, "{}", self.short_commit_id)
}
}
}
Expand All @@ -37,10 +38,7 @@ impl Serialize for HeadRefs {
{
let mut state = serializer.serialize_struct("HeadRefs", 2)?;
state.serialize_field("refs", &self.refs)?;
state.serialize_field(
"oid",
&self.commit.to_string().chars().take(7).collect::<String>(),
)?;
state.serialize_field("oid", &self.short_commit_id)?;
state.end()
}
}
2 changes: 1 addition & 1 deletion src/info/langs/language.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ macro_rules! define_colors {
( [ $($bc:ident),+ ] : [ $($c:ident($r:expr, $g:expr, $b:expr)),+ ] ) => { Colors { basic_colors: vec![$(clean_color!($bc)),+], true_colors: Some(vec![$(DynColors::$c($r, $g, $b)),+]) } };
}

#[derive(PartialEq, EnumString, EnumIter, IntoStaticStr)]
#[derive(Clone, PartialEq, EnumString, EnumIter, IntoStaticStr)]
#[strum(serialize_all = "lowercase")]
pub enum LanguageType {
Programming,
Expand Down
5 changes: 3 additions & 2 deletions src/info/langs/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use anyhow::{Context, Result};
use language::{Language, LanguageType};
use regex::Regex;
use std::collections::HashMap;
use std::path::Path;
use strum::IntoEnumIterator;

pub mod language;
Expand All @@ -11,7 +12,7 @@ pub fn get_dominant_language(languages_stat_vec: &[(Language, f64)]) -> Language
}

pub fn get_language_statistics(
dir: &str,
dir: &Path,
ignored_directories: &[String],
language_types: &[LanguageType],
include_hidden: bool,
Expand Down Expand Up @@ -71,7 +72,7 @@ fn get_total_loc(languages: &tokei::Languages) -> usize {
}

fn get_statistics(
dir: &str,
dir: &Path,
ignored_directories: &[String],
language_types: &[LanguageType],
include_hidden: bool,
Expand Down
3 changes: 2 additions & 1 deletion src/info/license.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use anyhow::{bail, Result};
use askalono::{Store, TextData};
use std::path::Path;
use std::{ffi::OsStr, fs};

const LICENSE_FILES: [&str; 3] = ["LICENSE", "LICENCE", "COPYING"];
Expand All @@ -24,7 +25,7 @@ impl Detector {
}
}

pub fn get_license(&self, dir: &str) -> Result<String> {
pub fn get_license(&self, dir: &Path) -> Result<String> {
fn is_license_file<S: AsRef<str>>(file_name: S) -> bool {
LICENSE_FILES
.iter()
Expand Down
56 changes: 43 additions & 13 deletions src/info/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::cli::{self, Config};
use crate::ui::get_ascii_colors;
use crate::ui::text_colors::TextColors;
use anyhow::Result;
use anyhow::{Context, Result};
use author::Author;
use deps::DependencyDetector;
use git2::Repository;
Expand Down Expand Up @@ -159,29 +159,59 @@ impl Info {
pub fn new(config: Config) -> Result<Self> {
let git_version = cli::get_git_version();
let repo = Repository::discover(&config.repo_path)?;
let internal_repo = Repo::new(&repo, config.no_merges, &config.bot_regex_pattern)?;
let workdir = repo.workdir().expect("non-bare repo").to_owned();

let pending_changes = std::thread::spawn({
let git_dir = repo.path().to_owned();
move || {
let repo = git2::Repository::open(git_dir)?;
repo::get_pending_changes(&repo)
}
});
let languages_handle = std::thread::spawn({
let ignored_directories = config.ignored_directories.clone();
let language_types = config.language_types.clone();
let include_hidden = config.include_hidden;
let workdir = workdir.clone();
move || {
langs::get_language_statistics(
&workdir,
&ignored_directories,
&language_types,
include_hidden,
)
}
});

let mut internal_repo = Repo::new(
&repo,
config.no_merges,
&config.bot_regex_pattern,
config.number_of_authors,
)?;
let (repo_name, repo_url) = internal_repo.get_name_and_url()?;
let head_refs = internal_repo.get_head_refs()?;
let pending_changes = internal_repo.get_pending_changes()?;
let version = internal_repo.get_version()?;
let git_username = internal_repo.get_git_username()?;
let number_of_tags = internal_repo.get_number_of_tags()?;
let number_of_branches = internal_repo.get_number_of_branches()?;
let creation_date = internal_repo.get_creation_date(config.iso_time)?;
let creation_date = internal_repo.get_creation_date(config.iso_time);
let number_of_commits = internal_repo.get_number_of_commits();
let (authors, contributors) =
internal_repo.get_authors(config.number_of_authors, config.show_email)?;
let (authors, contributors) = internal_repo.take_authors(config.show_email);
let last_change = internal_repo.get_date_of_last_commit(config.iso_time);
let (repo_size, file_count) = internal_repo.get_repo_size();
let workdir = internal_repo.get_work_dir()?;
let license = Detector::new()?.get_license(&workdir)?;
let dependencies = DependencyDetector::new().get_dependencies(&workdir)?;
let (languages, lines_of_code) = langs::get_language_statistics(
&workdir,
&config.ignored_directories,
&config.language_types,
config.include_hidden,
)?;

let pending_changes = pending_changes
.join()
.ok()
.context("BUG: panic in pending-changes thread")??;

let (languages, lines_of_code) = languages_handle
.join()
.ok()
.context("BUG: panic in language statistics thread")??;
let dominant_language = langs::get_dominant_language(&languages);
let ascii_colors = get_ascii_colors(
&config.ascii_language,
Expand Down
Loading