diff --git a/Cargo.lock b/Cargo.lock index 9a516d2..d6d3126 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -65,9 +65,9 @@ checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" [[package]] name = "cc" -version = "1.2.31" +version = "1.2.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3a42d84bb6b69d3a8b3eaacf0d88f179e1929695e1ad012b6cf64d9caaa5fd2" +checksum = "2352e5597e9c544d5e6d9c95190d5d27738ade584fa8db0a16e130e5c2b5296e" dependencies = [ "jobserver", "libc", @@ -243,8 +243,6 @@ dependencies = [ "libc", "libgit2-sys", "log", - "openssl-probe", - "openssl-sys", "url", ] @@ -480,9 +478,7 @@ checksum = "1c42fe03df2bd3c53a3a9c7317ad91d80c81cd1fb0caec8d7cc4cd2bfa10c222" dependencies = [ "cc", "libc", - "libssh2-sys", "libz-sys", - "openssl-sys", "pkg-config", ] @@ -492,20 +488,6 @@ version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" -[[package]] -name = "libssh2-sys" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "220e4f05ad4a218192533b300327f5150e809b54c4ec83b5a1d91833601811b9" -dependencies = [ - "cc", - "libc", - "libz-sys", - "openssl-sys", - "pkg-config", - "vcpkg", -] - [[package]] name = "libz-sys" version = "1.1.22" @@ -561,24 +543,6 @@ version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" -[[package]] -name = "openssl-probe" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" - -[[package]] -name = "openssl-sys" -version = "0.9.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90096e2e47630d78b7d1c20952dc621f957103f8bc2c8359ec81290d75238571" -dependencies = [ - "cc", - "libc", - "pkg-config", - "vcpkg", -] - [[package]] name = "parse-zoneinfo" version = "0.3.1" @@ -785,9 +749,9 @@ checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "rustversion" -version = "1.0.21" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a0d197bd2c9dc6e53b84da9556a69ba4cdfab8619eb41a8bd1cc2027a0f6b1d" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" [[package]] name = "ryu" diff --git a/Cargo.toml b/Cargo.toml index b36d374..a2af26e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,7 +8,7 @@ name = "frontend" path = "src/frontend.rs" [dependencies] -git2 = "0.20.2" +git2 = { version = "0.20.2", default-features = false } serde = { version = "1.0.219", default-features = false, features = ["derive"] } #inkjet = "0.11.1" #markdown = "1.0.0" diff --git a/src/backend.rs b/src/git.rs similarity index 65% rename from src/backend.rs rename to src/git.rs index 80153e9..b3dda57 100644 --- a/src/backend.rs +++ b/src/git.rs @@ -46,15 +46,14 @@ use std::{ error::Error, - path::{ PathBuf, Path }, + path::PathBuf, }; -use git2::{ Commit, Repository, Sort }; -use serde::Serialize; +use git2::{ Branch, Commit, Repository, Sort, TreeEntry }; -#[derive(Serialize)] pub struct GitCommit { author: (Option, Option), // name, e-mail + entries: Vec, hash: String, message: Option, short_hash: Option, @@ -62,7 +61,7 @@ pub struct GitCommit { } impl TryFrom> for GitCommit { - type Error = git2::Error; + type Error = Box; fn try_from(commit: Commit) -> Result { let hash = commit.id().to_string(); @@ -73,29 +72,77 @@ impl TryFrom> for GitCommit { let address = commit_signature.email().map(|f| f.to_owned()); let author = (name, address); let time = commit.time().seconds(); + let entries = commit + .tree()? + .iter() + .map(|c| -> Result { + Ok(GitEntry::try_from(c)?) + }).collect::, _>>()?; - Ok(GitCommit { author, hash, message, short_hash, time }) + Ok(GitCommit { author, entries, hash, message, short_hash, time }) } } -#[derive(Serialize)] pub struct GitEntry { - last_commit: GitCommit, path: String, } impl GitEntry { - fn new(commit: GitCommit, path: String) -> Self { - GitEntry { last_commit: commit, path } + fn new(path: String) -> Self { + GitEntry { path } } } +impl TryFrom> for GitEntry { + type Error = std::string::FromUtf8Error; + + fn try_from(entry: TreeEntry) -> Result { + let path = String::from_utf8(entry.name_bytes().to_vec())?; + Ok(Self { path }) + } +} + +pub struct GitBranch { + commits: Vec, + name: String, +} + +struct GitBranchWrapper<'a> { + branch: Branch<'a>, + repo: &'a Repository, +} + +impl<'a> GitBranchWrapper<'a> { + fn new(branch: Branch<'a>, repo: &'a Repository) -> Self { + Self { branch, repo } + } +} + +impl TryFrom> for GitBranch { + type Error = Box; + + fn try_from(branch: GitBranchWrapper) -> Result { + let name = String::from_utf8(branch.branch.name_bytes()?.to_vec())?; + let repo = branch.repo; + let branch_oid = branch.branch.get().target().unwrap(); + + let mut revwalk = repo.revwalk()?; + revwalk.set_sorting(Sort::TOPOLOGICAL | Sort::TIME)?; + revwalk.push(branch_oid)?; + + let commits = revwalk + .into_iter() + .map(|o| -> Result> { + Ok(GitCommit::try_from(repo.find_commit(o?)?)?) + }).collect::, _>>()?; + + Ok(GitBranch { commits, name }) + } + +} -#[derive(Serialize)] pub struct GitRepo { - branch: Option, - entries: Vec, - last_commit: GitCommit, + branches: Vec, name: String, owner: String, } @@ -103,7 +150,23 @@ pub struct GitRepo { impl GitRepo { fn open(path: PathBuf) -> Result> { let repo = Repository::open(path.clone())?; - let entries = Self::get_entries(&repo)?; + + let branches = repo + .branches(None)? + .map(|b| -> Result> { + Ok(GitBranch::try_from(GitBranchWrapper::new(b?.0, &repo))?) + }).collect::, _>>()?; + /* + let mut revwalk = repo.revwalk()?; + + revwalk.set_sorting(Sort::TOPOLOGICAL | Sort::TIME)?; + revwalk.push_head()?; + let commits = revwalk + .into_iter() + .map(|o| -> Result> { + Ok(GitCommit::try_from(repo.find_commit(o?)?)?) + }).collect::, _>>()?; + */ let full_path = path.clone().as_path().canonicalize()?; @@ -128,53 +191,10 @@ impl GitRepo { .to_vec() )?; - let head = repo.head()?; - let branch = head.shorthand().map(|f| f.to_owned()); - - let last_commit = GitCommit::try_from(head.peel_to_commit()?)?; - - Ok(GitRepo { branch, entries, last_commit, name, owner }) + Ok(GitRepo { branches, name, owner }) } fn get_remote_repo() { // for AP repos todo!(); } - - fn get_entries(repo: &Repository) -> Result, Box> { - let mut entries = Vec::new(); - let mut revwalk = repo.revwalk()?; - - revwalk.set_sorting(Sort::TOPOLOGICAL | Sort::TIME)?; - revwalk.push_head()?; - - for commit_id in revwalk { - let commit_id = commit_id?; - let commit = repo.find_commit(commit_id)?; - if commit.parent_count() <= 1 { - let tree = commit.tree()?; - let prev_tree = match commit.parent_count() { - 1 => Some(commit.parent(0)?.tree()?), - 0 => None, - _ => unreachable!(), - }; - - 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 - .to_path_buf() - .as_mut_os_string() - .as_encoded_bytes() - .to_vec() - )?; - let c = GitCommit::try_from(commit.clone())?; - entries.push(GitEntry::new(c, p)); - } - } - } - } - Ok(entries) - } }