use crate::error::AppError; use crate::models::project::Project; use crate::AppState; use std::process::Command; use tauri::State; #[tauri::command] pub fn create_project( state: State<'_, AppState>, name: String, path_or_url: String, base_branch: String, ) -> Result { let is_url = path_or_url.starts_with("http://") || path_or_url.starts_with("https://") || path_or_url.starts_with("git@"); let (local_path, cloned_from) = if is_url { let home = dirs::home_dir().ok_or_else(|| AppError::from("Cannot determine home directory".to_string()))?; let clone_dir = home.join("orchai-repos").join(&name); std::fs::create_dir_all(&clone_dir)?; let output = Command::new("git") .args(["clone", &path_or_url, clone_dir.to_str().unwrap()]) .output()?; if !output.status.success() { let stderr = String::from_utf8_lossy(&output.stderr); return Err(AppError::from(format!("git clone failed: {}", stderr))); } (clone_dir.to_string_lossy().to_string(), Some(path_or_url)) } else { let path = std::path::Path::new(&path_or_url); if !path.exists() { return Err(AppError::from(format!("Path does not exist: {}", path_or_url))); } if !path.join(".git").exists() { return Err(AppError::from(format!("Not a git repository: {}", path_or_url))); } (path_or_url, None) }; let db = state.db.lock().unwrap(); let project = Project::insert(&db, &name, &local_path, cloned_from.as_deref(), &base_branch)?; Ok(project) } #[tauri::command] pub fn list_projects(state: State<'_, AppState>) -> Result, AppError> { let db = state.db.lock().unwrap(); let projects = Project::list(&db)?; Ok(projects) } #[tauri::command] pub fn get_project(state: State<'_, AppState>, id: String) -> Result { let db = state.db.lock().unwrap(); let project = Project::get_by_id(&db, &id)?; Ok(project) } #[tauri::command] pub fn update_project( state: State<'_, AppState>, id: String, name: String, base_branch: String, ) -> Result<(), AppError> { let db = state.db.lock().unwrap(); Project::update(&db, &id, &name, &base_branch)?; Ok(()) } #[tauri::command] pub fn delete_project(state: State<'_, AppState>, id: String) -> Result<(), AppError> { let db = state.db.lock().unwrap(); Project::delete(&db, &id)?; Ok(()) }