diff options
author | Toby Vincent <tobyv13@gmail.com> | 2022-11-28 16:09:29 -0600 |
---|---|---|
committer | Toby Vincent <tobyv13@gmail.com> | 2022-11-28 16:09:29 -0600 |
commit | da884530e2b3e0b9a5bef9abcf683a970b93bd6b (patch) | |
tree | 84653f0fc4e643bb2d2c6d6a1eff79fdd94fbf07 /src/project/git.rs | |
parent | f7eeef26d5a251c2a925d18d288fec2fa205f59d (diff) |
feat: add git and preview (default) features
Diffstat (limited to 'src/project/git.rs')
-rw-r--r-- | src/project/git.rs | 101 |
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 } } |