diff options
Diffstat (limited to 'src/git.rs')
-rw-r--r-- | src/git.rs | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/src/git.rs b/src/git.rs new file mode 100644 index 0000000..afa4a9a --- /dev/null +++ b/src/git.rs @@ -0,0 +1,39 @@ +use git2::{BranchType, Repository}; +use std::{path::PathBuf, time::Duration}; + +use crate::{parser::Parser, project::Project}; + +#[derive(Debug, Clone)] +pub struct Git; + +impl Parser for Git { + #[tracing::instrument] + fn parse(&self, path_buf: PathBuf) -> Result<Project, Box<dyn std::error::Error>> { + Repository::open(&path_buf)?.parse(path_buf) + } +} + +impl Parser 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?; + + let name = branch + .name()? + .ok_or_else(|| git2::Error::from_str("Failed to find branch"))?; + + self.revparse_single(name)? + .peel_to_commit() + .map(|c| (c.time().seconds() as u64).max(latest)) + }) + .map(Duration::from_secs) + .unwrap_or_default(); + + Ok(Project { + worktree: path_buf, + timestamp, + }) + } +} |