diff options
author | Toby Vincent <tobyv13@gmail.com> | 2023-05-04 19:43:08 -0500 |
---|---|---|
committer | Toby Vincent <tobyv13@gmail.com> | 2023-05-04 19:43:08 -0500 |
commit | 5da4fb25f9bb72771c7f2798daa6339be0bc3900 (patch) | |
tree | c30639c7a95e1d94baff498d247eed43fdb3728e /src/git.rs | |
parent | 589cd987217755e1da7acbc304c373a75a9f7db5 (diff) |
refactor: join iterators into a single walk
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, + }) + } +} |