aboutsummaryrefslogtreecommitdiffstats
path: root/src/project/git.rs
diff options
context:
space:
mode:
authorToby Vincent <tobyv13@gmail.com>2022-11-28 16:09:29 -0600
committerToby Vincent <tobyv13@gmail.com>2022-11-28 16:09:29 -0600
commitda884530e2b3e0b9a5bef9abcf683a970b93bd6b (patch)
tree84653f0fc4e643bb2d2c6d6a1eff79fdd94fbf07 /src/project/git.rs
parentf7eeef26d5a251c2a925d18d288fec2fa205f59d (diff)
feat: add git and preview (default) features
Diffstat (limited to 'src/project/git.rs')
-rw-r--r--src/project/git.rs101
1 files changed, 51 insertions, 50 deletions
diff --git a/src/project/git.rs b/src/project/git.rs
index 876af1c..efe4ade 100644
--- a/src/project/git.rs
+++ b/src/project/git.rs
@@ -2,71 +2,84 @@ use git2::{BranchType, Repository};
use ignore::DirEntry;
use onefetch::ui::printer::Printer;
use std::io;
-use std::{cmp::Ordering, path::PathBuf, time::Duration};
+use std::{path::PathBuf, time::Duration};
+use tracing::{debug, warn};
-use crate::project::Error;
-use crate::project::Preview;
-use crate::project::Timestamp;
-use crate::Project;
+use super::{Error, Preview, ProjectParser, Timestamp};
+
+#[derive(Debug, Clone)]
+pub struct GitMatcher;
+
+impl ProjectParser for GitMatcher {
+ #[tracing::instrument]
+ fn parse_project(&self, path_buf: PathBuf) -> Option<super::ProjectItem> {
+ match GitProject::new(path_buf) {
+ Ok(g) => Some(Box::new(g)),
+ Err(err) => {
+ debug!(%err, "Failed to create git project");
+ None
+ }
+ }
+ }
+}
#[derive(Debug, Clone)]
pub struct GitProject {
path_buf: PathBuf,
- latest_commit: Option<Duration>,
+ latest_commit: Duration,
}
impl GitProject {
fn new(path_buf: PathBuf) -> Result<Self, Error> {
let repo = Repository::open(&path_buf)?;
+ let latest_commit = Self::get_timestamp(&repo);
Ok(Self {
path_buf,
- latest_commit: Self::latest_commit(&repo).ok(),
+ latest_commit,
})
}
- fn latest_commit(repository: &Repository) -> Result<Duration, Error> {
- let mut branches = repository.branches(Some(BranchType::Local))?;
- branches
- .try_fold(0, |latest, branch| {
- let (branch, _) = branch?;
-
- let name = branch
- .name()?
- .ok_or_else(|| git2::Error::from_str("Failed to find branch"))?;
-
- repository
- .revparse_single(name)?
- .peel_to_commit()
- .map(|c| (c.time().seconds() as u64).max(latest))
- })
- .map(Duration::from_secs)
- .map_err(Into::into)
+ fn get_timestamp(repo: &Repository) -> Duration {
+ match Self::latest_commit(repo) {
+ Ok(s) => Duration::from_secs(s),
+ Err(err) => {
+ warn!(%err, "Failed to get latest commit from repository");
+ Duration::default()
+ }
+ }
}
-}
-impl Timestamp for GitProject {
- type Error = Error;
+ fn latest_commit(repository: &Repository) -> Result<u64, git2::Error> {
+ let mut branches = repository.branches(Some(BranchType::Local))?;
+ branches.try_fold(0, |latest, branch| {
+ let (branch, _) = branch?;
- fn timestamp(&self) -> Result<Duration, Self::Error> {
- self.latest_commit.ok_or(Error::Git(git2::Error::from_str(
- "Failed to get latest commit",
- )))
+ let name = branch
+ .name()?
+ .ok_or_else(|| git2::Error::from_str("Failed to find branch"))?;
+
+ repository
+ .revparse_single(name)?
+ .peel_to_commit()
+ .map(|c| (c.time().seconds() as u64).max(latest))
+ })
}
}
-impl Project for GitProject {
- fn to_path_buf(&self) -> &PathBuf {
- &self.path_buf
+impl Timestamp for GitProject {
+ fn timestamp(&self) -> &Duration {
+ &self.latest_commit
}
}
+#[cfg(feature = "preview")]
impl Preview for GitProject {
type Error = Error;
fn preview(&self) -> Result<(), Self::Error> {
- // onefetch --include-hidden --show-logo=auto
let config = onefetch::cli::Config {
input: self.path_buf.to_owned(),
+ include_hidden: true,
..Default::default()
};
@@ -77,21 +90,9 @@ impl Preview for GitProject {
}
}
-impl PartialEq for GitProject {
- fn eq(&self, other: &Self) -> bool {
- match (self.latest_commit, other.latest_commit) {
- (Some(time), Some(other_time)) => time.eq(&other_time),
- _ => false,
- }
- }
-}
-
-impl PartialOrd for GitProject {
- fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
- match (self.latest_commit, other.latest_commit) {
- (Some(time), Some(other_time)) => time.partial_cmp(&other_time),
- _ => None,
- }
+impl AsRef<PathBuf> for GitProject {
+ fn as_ref(&self) -> &PathBuf {
+ &self.path_buf
}
}