summaryrefslogtreecommitdiffstats
path: root/src/git.rs
diff options
context:
space:
mode:
authorToby Vincent <tobyv13@gmail.com>2023-05-04 19:43:08 -0500
committerToby Vincent <tobyv13@gmail.com>2023-05-04 19:43:08 -0500
commit5da4fb25f9bb72771c7f2798daa6339be0bc3900 (patch)
treec30639c7a95e1d94baff498d247eed43fdb3728e /src/git.rs
parent589cd987217755e1da7acbc304c373a75a9f7db5 (diff)
refactor: join iterators into a single walk
Diffstat (limited to 'src/git.rs')
-rw-r--r--src/git.rs39
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,
+ })
+ }
+}