1
0
Fork 0

Implement VCS trait and GitVcs struct with repository management functions; update Cargo.toml and Cargo.lock for new dependencies

This commit is contained in:
Jordon Brooks 2025-06-24 16:32:26 +01:00
parent d94d7fef6e
commit 3b72d2e5f7
Signed by: jordon
GPG key ID: DBD9758CD53E786A
7 changed files with 206 additions and 6 deletions

93
src-tauri/Cargo.lock generated
View file

@ -433,6 +433,8 @@ version = "1.2.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d487aa071b5f64da6f19a3e848e3578944b726ee5a4854b82172f02aa876bfdc"
dependencies = [
"jobserver",
"libc",
"shlex",
]
@ -1274,6 +1276,21 @@ dependencies = [
"winapi",
]
[[package]]
name = "git2"
version = "0.20.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2deb07a133b1520dc1a5690e9bd08950108873d7ed5de38dcc74d3b5ebffa110"
dependencies = [
"bitflags 2.9.1",
"libc",
"libgit2-sys",
"log",
"openssl-probe",
"openssl-sys",
"url",
]
[[package]]
name = "glib"
version = "0.18.5"
@ -1793,6 +1810,16 @@ version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130"
[[package]]
name = "jobserver"
version = "0.1.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38f262f097c174adebe41eb73d66ae9c06b2844fb0da69969647bbddd9b0538a"
dependencies = [
"getrandom 0.3.3",
"libc",
]
[[package]]
name = "js-sys"
version = "0.3.77"
@ -1885,6 +1912,20 @@ version = "0.2.174"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776"
[[package]]
name = "libgit2-sys"
version = "0.18.2+1.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1c42fe03df2bd3c53a3a9c7317ad91d80c81cd1fb0caec8d7cc4cd2bfa10c222"
dependencies = [
"cc",
"libc",
"libssh2-sys",
"libz-sys",
"openssl-sys",
"pkg-config",
]
[[package]]
name = "libloading"
version = "0.7.4"
@ -1905,6 +1946,32 @@ dependencies = [
"libc",
]
[[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"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b70e7a7df205e92a1a4cd9aaae7898dac0aa555503cc0a649494d0d60e7651d"
dependencies = [
"cc",
"libc",
"pkg-config",
"vcpkg",
]
[[package]]
name = "linux-raw-sys"
version = "0.9.4"
@ -2354,15 +2421,35 @@ dependencies = [
"pathdiff",
]
[[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 = "openvcs"
version = "0.1.0"
dependencies = [
"git2",
"serde",
"serde_json",
"tauri",
"tauri-build",
"tauri-plugin-opener",
"thiserror 2.0.12",
]
[[package]]
@ -4195,6 +4282,12 @@ dependencies = [
"wasm-bindgen",
]
[[package]]
name = "vcpkg"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
[[package]]
name = "version-compare"
version = "0.2.0"

View file

@ -31,4 +31,6 @@ tauri = { version = "2", features = [] }
tauri-plugin-opener = "2"
serde = { version = "1", features = ["derive"] }
serde_json = "1"
git2 = "0.20.2"
thiserror = "2.0.12"

View file

@ -1,14 +1,13 @@
// Learn more about Tauri commands at https://tauri.app/develop/calling-rust/
#[tauri::command]
fn greet(name: &str) -> String {
format!("Hello, {}! You've been greeted from Rust!", name)
}
mod vcs;
mod tauri_commands;
#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
println!("Running OpenVCS...");
tauri::Builder::default()
.plugin(tauri_plugin_opener::init())
.invoke_handler(tauri::generate_handler![greet])
.invoke_handler(tauri::generate_handler![tauri_commands::greet])
.run(tauri::generate_context!())
.expect("error while running tauri application");
}

View file

@ -0,0 +1,19 @@
use std::{path::{PathBuf}, sync::Arc};
use crate::vcs::vcs::Vcs;
#[tauri::command]
pub fn greet(name: &str) -> String {
format!("Hello, {}! You've been greeted from Rust!", name)
}
#[tauri::command]
pub async fn init_repo(path: String, state: tauri::State<'_, Arc<dyn Vcs>>) -> Result<(), String> {
let p = PathBuf::from(path);
state.init_repo(&p).map_err(|e| e.to_string())
}
#[tauri::command]
pub async fn list_branches(path: String, state: tauri::State<'_, Arc<dyn Vcs>>) -> Result<Vec<String>, String> {
let p = PathBuf::from(path);
state.list_branches(&p).map_err(|e| e.to_string())
}

66
src-tauri/src/vcs/git.rs Normal file
View file

@ -0,0 +1,66 @@
use std::path::Path;
use git2::{Repository, BranchType};
use crate::vcs::vcs::{Vcs, VcsError};
pub struct GitVcs;
impl GitVcs {
#[allow(dead_code)]
pub fn new() -> Self {
GitVcs
}
}
impl Vcs for GitVcs {
fn init_repo(&self, path: &Path) -> Result<(), VcsError> {
Repository::init(path)?;
Ok(())
}
fn clone_repo(&self, url: &str, path: &Path) -> Result<(), VcsError> {
Repository::clone(url, path)?;
Ok(())
}
fn list_branches(&self, path: &Path) -> Result<Vec<String>, VcsError> {
let repo = Repository::open(path)?;
let mut names = Vec::new();
for branch in repo.branches(Some(BranchType::Local))? {
let (branch, _) = branch?;
if let Some(name) = branch.name()? {
names.push(name.to_string());
}
}
Ok(names)
}
fn commit_all(&self, path: &Path, message: &str) -> Result<(), VcsError> {
let repo = Repository::open(path)?;
let mut index = repo.index()?;
index.add_all(["*"].iter(), git2::IndexAddOption::DEFAULT, None)?;
let tree_id = index.write_tree()?;
let tree = repo.find_tree(tree_id)?;
let sig = repo.signature()?;
let parent_commit = repo.head()
.and_then(|h| h.peel_to_commit())
.ok();
let parents = parent_commit.iter().collect::<Vec<_>>();
repo.commit(
Some("HEAD"),
&sig,
&sig,
message,
&tree,
&parents
)?;
Ok(())
}
fn push(&self, path: &Path, remote: &str, branch: &str) -> Result<(), VcsError> {
let repo = Repository::open(path)?;
let mut r = repo.find_remote(remote)?;
let refspec = format!("refs/heads/{}:refs/heads/{}", branch, branch);
r.push(&[&refspec], None)?;
Ok(())
}
}

3
src-tauri/src/vcs/mod.rs Normal file
View file

@ -0,0 +1,3 @@
pub mod git;
pub mod vcs;

18
src-tauri/src/vcs/vcs.rs Normal file
View file

@ -0,0 +1,18 @@
use std::path::Path;
use thiserror::Error;
#[derive(Debug, Error)]
pub enum VcsError {
#[error("IO error: {0}")]
Io(#[from] std::io::Error),
#[error("Git error: {0}")]
Git(#[from] git2::Error),
}
pub trait Vcs: Send + Sync + 'static {
fn init_repo(&self, path: &Path) -> Result<(), VcsError>;
fn clone_repo(&self, url: &str, path: &Path) -> Result<(), VcsError>;
fn list_branches(&self, path: &Path) -> Result<Vec<String>, VcsError>;
fn commit_all(&self, path: &Path, message: &str) -> Result<(), VcsError>;
fn push(&self, path: &Path, remote: &str, branch: &str) -> Result<(), VcsError>;
}