backend.rs: expanded git convenience types and moved to git.rs
This commit is contained in:
		
							parent
							
								
									2229656a20
								
							
						
					
					
						commit
						1d50384bb8
					
				
							
								
								
									
										44
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										44
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							@ -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"
 | 
			
		||||
 | 
			
		||||
@ -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"
 | 
			
		||||
 | 
			
		||||
@ -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<String>, Option<String>), // name, e-mail
 | 
			
		||||
	entries: Vec<GitEntry>,
 | 
			
		||||
	hash: String,
 | 
			
		||||
	message: Option<String>,
 | 
			
		||||
	short_hash: Option<String>,
 | 
			
		||||
@ -62,7 +61,7 @@ pub struct GitCommit {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl TryFrom<Commit<'_>> for GitCommit {
 | 
			
		||||
	type Error = git2::Error;
 | 
			
		||||
	type Error = Box<dyn Error>;
 | 
			
		||||
 | 
			
		||||
	fn try_from(commit: Commit) -> Result<Self, Self::Error> {
 | 
			
		||||
		let hash = commit.id().to_string();
 | 
			
		||||
@ -73,29 +72,77 @@ impl TryFrom<Commit<'_>> 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<GitEntry, std::string::FromUtf8Error> {
 | 
			
		||||
				Ok(GitEntry::try_from(c)?)
 | 
			
		||||
			}).collect::<Result<Vec<_>, _>>()?;
 | 
			
		||||
 | 
			
		||||
		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<TreeEntry<'_>> for GitEntry {
 | 
			
		||||
	type Error = std::string::FromUtf8Error;
 | 
			
		||||
 | 
			
		||||
	fn try_from(entry: TreeEntry) -> Result<Self, Self::Error> {
 | 
			
		||||
		let path = String::from_utf8(entry.name_bytes().to_vec())?;
 | 
			
		||||
		Ok(Self { path })
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub struct GitBranch {
 | 
			
		||||
	commits: Vec<GitCommit>,
 | 
			
		||||
	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<GitBranchWrapper<'_>> for GitBranch {
 | 
			
		||||
	type Error = Box<dyn Error>;
 | 
			
		||||
 | 
			
		||||
	fn try_from(branch: GitBranchWrapper) -> Result<Self, Self::Error> {
 | 
			
		||||
		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<GitCommit, Box<dyn Error>> {
 | 
			
		||||
				Ok(GitCommit::try_from(repo.find_commit(o?)?)?)
 | 
			
		||||
			}).collect::<Result<Vec<_>, _>>()?;
 | 
			
		||||
 | 
			
		||||
		Ok(GitBranch { commits, name })
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Serialize)]
 | 
			
		||||
pub struct GitRepo {
 | 
			
		||||
	branch: Option<String>,
 | 
			
		||||
	entries: Vec<GitEntry>,
 | 
			
		||||
	last_commit: GitCommit,
 | 
			
		||||
	branches: Vec<GitBranch>,
 | 
			
		||||
	name: String,
 | 
			
		||||
	owner: String,
 | 
			
		||||
}
 | 
			
		||||
@ -103,7 +150,23 @@ pub struct GitRepo {
 | 
			
		||||
impl GitRepo {
 | 
			
		||||
	fn open(path: PathBuf) -> Result<Self, Box<dyn Error>> {
 | 
			
		||||
		let repo = Repository::open(path.clone())?;
 | 
			
		||||
		let entries = Self::get_entries(&repo)?;
 | 
			
		||||
 | 
			
		||||
		let branches = repo
 | 
			
		||||
			.branches(None)?
 | 
			
		||||
			.map(|b| -> Result<GitBranch, Box<dyn Error>> {
 | 
			
		||||
				Ok(GitBranch::try_from(GitBranchWrapper::new(b?.0, &repo))?)
 | 
			
		||||
			}).collect::<Result<Vec<_>, _>>()?;
 | 
			
		||||
		/*
 | 
			
		||||
		let mut revwalk = repo.revwalk()?;
 | 
			
		||||
		
 | 
			
		||||
		revwalk.set_sorting(Sort::TOPOLOGICAL | Sort::TIME)?;
 | 
			
		||||
		revwalk.push_head()?;
 | 
			
		||||
		let commits = revwalk
 | 
			
		||||
			.into_iter()
 | 
			
		||||
			.map(|o| -> Result<GitCommit, Box<dyn Error>> {
 | 
			
		||||
				Ok(GitCommit::try_from(repo.find_commit(o?)?)?)
 | 
			
		||||
			}).collect::<Result<Vec<_>, _>>()?;
 | 
			
		||||
		*/
 | 
			
		||||
 | 
			
		||||
		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<Vec<GitEntry>, Box<dyn Error>> {
 | 
			
		||||
		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)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user