diff options
Diffstat (limited to 'src/project/git.rs')
-rw-r--r-- | src/project/git.rs | 105 |
1 files changed, 21 insertions, 84 deletions
diff --git a/src/project/git.rs b/src/project/git.rs index 4584a7a..e2067ec 100644 --- a/src/project/git.rs +++ b/src/project/git.rs @@ -1,102 +1,39 @@ use git2::{BranchType, Repository}; -use ignore::DirEntry; use std::{path::PathBuf, time::Duration}; -use tracing::{debug, warn}; -use crate::{Error, Result}; - -use super::{ProjectParser, Timestamp}; +use super::{Project, ProjectParser}; #[derive(Debug, Clone)] pub struct GitMatcher; impl ProjectParser for GitMatcher { #[tracing::instrument] - fn parse(&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 - } - } + fn parse(&self, path_buf: PathBuf) -> Result<Project, Box<dyn std::error::Error>> { + Repository::open(&path_buf)?.parse(path_buf) } } -#[derive(Debug, Clone)] -pub struct GitProject { - path_buf: PathBuf, - latest_commit: Duration, -} +impl ProjectParser for Repository { + fn parse(&self, path_buf: PathBuf) -> Result<Project, Box<dyn std::error::Error>> { + let mut branches = self.branches(Some(BranchType::Local))?; + let timestamp = branches + .try_fold(0, |latest, branch| -> std::result::Result<u64, _> { + let (branch, _) = branch?; -impl GitProject { - fn new(path_buf: PathBuf) -> Result<Self> { - let repo = Repository::open(&path_buf)?; - let latest_commit = Self::get_timestamp(&repo); - Ok(Self { - path_buf, - latest_commit, - }) - } - - 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() - } - } - } + let name = branch + .name()? + .ok_or_else(|| git2::Error::from_str("Failed to find branch"))?; - fn latest_commit(repository: &Repository) -> Result<u64> { - let mut branches = repository.branches(Some(BranchType::Local))?; - branches.try_fold(0, |latest, branch| { - let (branch, _) = branch?; + self.revparse_single(name)? + .peel_to_commit() + .map(|c| (c.time().seconds() as u64).max(latest)) + }) + .map(Duration::from_secs) + .unwrap_or_default(); - 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_err(Into::into) + Ok(Project { + worktree: path_buf, + timestamp, }) } } - -impl Timestamp for GitProject { - fn timestamp(&self) -> &Duration { - &self.latest_commit - } -} - -impl AsRef<PathBuf> for GitProject { - fn as_ref(&self) -> &PathBuf { - &self.path_buf - } -} - -impl TryFrom<PathBuf> for GitProject { - type Error = Error; - - fn try_from(value: PathBuf) -> Result<Self> { - Self::new(value) - } -} - -impl TryFrom<DirEntry> for GitProject { - type Error = Error; - - fn try_from(value: DirEntry) -> Result<Self> { - Self::new(value.into_path()) - } -} - -impl From<GitProject> for PathBuf { - fn from(value: GitProject) -> Self { - value.path_buf - } -} |