aboutsummaryrefslogtreecommitdiffstats
path: root/src/project
diff options
context:
space:
mode:
authorToby Vincent <tobyv13@gmail.com>2023-04-28 17:32:24 -0500
committerToby Vincent <tobyv13@gmail.com>2023-04-28 17:32:24 -0500
commit589cd987217755e1da7acbc304c373a75a9f7db5 (patch)
tree2730a697e4f7b2f779fcd96b0452719cc67f36e3 /src/project
parenta98b50667bc6a11e4b8be464969adc14601e9e78 (diff)
refactor: simplify logic and clean up dep.
Diffstat (limited to 'src/project')
-rw-r--r--src/project/git.rs105
-rw-r--r--src/project/path.rs57
2 files changed, 32 insertions, 130 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
- }
-}
diff --git a/src/project/path.rs b/src/project/path.rs
index 5954ff9..0e38990 100644
--- a/src/project/path.rs
+++ b/src/project/path.rs
@@ -1,57 +1,22 @@
-use std::path::{Path, PathBuf};
-use std::time::{Duration, SystemTime};
-use tracing::debug;
+use std::{io::ErrorKind, path::PathBuf};
-use super::{ProjectItem, ProjectParser};
+use super::{Project, ProjectParser};
#[derive(Debug, Clone)]
pub enum PathMatcher {
- All(PathBuf),
+ All,
Pattern(String),
}
impl ProjectParser for PathMatcher {
#[tracing::instrument]
- fn parse(&self, path_buf: PathBuf) -> Option<ProjectItem> {
- match self {
- PathMatcher::All(p) if &path_buf != p => Some(Box::new(PathProject::new(path_buf))),
- PathMatcher::Pattern(p) if path_buf.join(p).exists() => {
- Some(Box::new(PathProject::new(path_buf)))
- }
- _ => {
- debug!("Failed to match pattern in directory");
- None
- }
- }
- }
-}
-
-#[derive(Debug, PartialEq, Eq, Clone, Default)]
-pub struct PathProject(PathBuf, Duration);
-
-impl PathProject {
- pub fn new(path_buf: PathBuf) -> Self {
- let modified = Self::get_modified(&path_buf).unwrap_or_default();
- Self(path_buf, modified)
- }
-
- fn get_modified(path_buf: &Path) -> Result<Duration, std::io::Error> {
- path_buf
- .metadata()?
- .modified()?
- .duration_since(SystemTime::UNIX_EPOCH)
- .map_err(|err| std::io::Error::new(std::io::ErrorKind::Other, err.to_string()))
- }
-}
-
-impl AsRef<PathBuf> for PathProject {
- fn as_ref(&self) -> &PathBuf {
- &self.0
- }
-}
-
-impl AsRef<Duration> for PathProject {
- fn as_ref(&self) -> &Duration {
- &self.1
+ fn parse(&self, path_buf: PathBuf) -> Result<Project, Box<dyn std::error::Error>> {
+ let project = match self {
+ PathMatcher::All => path_buf.try_into()?,
+ PathMatcher::Pattern(p) if path_buf.join(p).exists() => path_buf.try_into()?,
+ _ => return Err(Box::new(std::io::Error::from(ErrorKind::NotFound))),
+ };
+
+ Ok(project)
}
}