diff --git a/src/backend.rs b/src/backend.rs index 1c85d0d..11b8858 100644 --- a/src/backend.rs +++ b/src/backend.rs @@ -49,14 +49,16 @@ use std::{ path::{ PathBuf, Path }, }; -use git2::{ Commit, ErrorClass, ErrorCode, Repository, Sort }; +use git2::{ Commit, Repository, Sort }; use serde::Serialize; #[derive(Serialize)] pub struct GitCommit { + author: (Option, Option), // name, e-mail hash: String, - message: String, - short_hash: String, + message: Option, + short_hash: Option, + time: i64, // seconds since Unix epoch } impl TryFrom> for GitCommit { @@ -64,46 +66,34 @@ impl TryFrom> for GitCommit { fn try_from(commit: Commit) -> Result { let hash = commit.id().to_string(); - let short_hash = commit.as_object().short_id()?.as_str().ok_or( - Self::Error::new(ErrorCode::Invalid, ErrorClass::Object, "Short ID is not valid UTF-8") - )?.to_owned(); - let message = commit.message().ok_or( - Self::Error::new(ErrorCode::NotFound, ErrorClass::None, "No commit message") - )?.to_owned(); - Ok(GitCommit { hash, message, short_hash }) + let short_hash = commit.as_object().short_id()?.as_str().map(|f| f.to_owned()); + let message = commit.message().map(|f| f.to_owned()); + let commit_signature = commit.author(); + let name = commit_signature.name().map(|f| f.to_owned()); + let address = commit_signature.email().map(|f| f.to_owned()); + let author = (name, address); + let time = commit.time().seconds(); + + Ok(GitCommit { author, hash, message, short_hash, time }) } } #[derive(Serialize)] struct GitEntry { - committer: String, - last_commit: String, - last_commit_short: String, - last_commit_time: i64, + last_commit: GitCommit, path: String, } impl GitEntry { - fn new(commit: &Commit, path: String) -> Result { - let commit_id = commit.id(); - - Ok(GitEntry { - committer: commit - .committer() - .name() - .unwrap_or("") - .to_owned(), - last_commit: commit_id.to_string(), - last_commit_short: commit.as_object().short_id()?.as_str().unwrap_or("").to_owned(), - last_commit_time: commit.time().seconds(), - path, - }) + fn new(commit: GitCommit, path: String) -> Self { + GitEntry { last_commit: commit, path } } } #[derive(Serialize)] pub struct GitRepo { + branch: Option, entries: Vec, last_commit: GitCommit, name: String, @@ -138,9 +128,12 @@ impl GitRepo { .to_vec() )?; - let last_commit = GitCommit::try_from(repo.head()?.peel_to_commit()?)?; + let head = repo.head()?; + let branch = head.shorthand().map(|f| f.to_owned()); - Ok(GitRepo { entries, last_commit, name, owner }) + let last_commit = GitCommit::try_from(head.peel_to_commit()?)?; + + Ok(GitRepo { branch, entries, last_commit, name, owner }) } fn get_remote_repo() { // for AP repos @@ -165,7 +158,9 @@ impl GitRepo { _ => unreachable!(), }; - let diff = repo.diff_tree_to_tree(prev_tree.as_ref(), Some(&tree), None)?; + let diff = repo + .diff_tree_to_tree(prev_tree.as_ref(), Some(&tree), None)?; + for delta in diff.deltas() { if let Some(file_path) = delta.new_file().path() { let p = String::from_utf8(file_path @@ -174,7 +169,8 @@ impl GitRepo { .as_encoded_bytes() .to_vec() )?; - entries.push(GitEntry::new(&commit, p)?); + let c = GitCommit::try_from(commit.clone())?; + entries.push(GitEntry::new(c, p)); } } }