use crate::cfg::config::Config; use crate::pkgtoolkit::types::Package; use git2::Repository; use std::fs; use std::path::Path; use toml; pub struct GitSource; impl GitSource { /// Clone a git repository to a local directory pub fn clone_repo(git_url: &str, target_dir: &Path) -> Result<(), git2::Error> { Repository::clone(git_url, target_dir)?; Ok(()) } /// Get source code for a package from its git repository pub fn get_package_source( package: &Package, config: &Config, ) -> Result> { let git_repo = package .git_repo .as_ref() .ok_or("Package does not have a git repository specified")?; let source_dir = Path::new(&config.paths.cache_dir) .join("sources") .join(&package.name) .join(&package.version); fs::create_dir_all(&source_dir)?; println!("Cloning {} from {}", package.name, git_repo); Self::clone_repo(git_repo, &source_dir)?; let source_path = source_dir.to_string_lossy().to_string(); println!("Source code downloaded to: {}", source_path); Ok(source_path) } /// Get source code for a package by name, first checking INSTALL file, then falling back to index pub fn get_source_by_name( pkg_name: &str, config: &Config, ) -> Result> { let install_path = Path::new(&config.paths.cache_dir).join(format!("{}/INSTALL", pkg_name)); if install_path.exists() { let install_content = fs::read_to_string(&install_path)?; let install_data: crate::pkgtoolkit::types::Install = toml::from_str(&install_content) .map_err(|e| format!("Failed to parse INSTALL file: {}", e))?; // Check if InstallMeta has git_repo if let Some(git_repo) = install_data.install.git_repo { println!("Found git repository in INSTALL file: {}", git_repo); let source_dir = Path::new(&config.paths.cache_dir) .join("sources") .join(&install_data.package.name) .join(&install_data.package.version); fs::create_dir_all(&source_dir)?; println!("Cloning {} from {}", install_data.package.name, git_repo); Self::clone_repo(&git_repo, &source_dir)?; let source_path = source_dir.to_string_lossy().to_string(); println!("Source code downloaded to: {}", source_path); return Ok(source_path); } } let index_path = Path::new(&config.paths.cache_dir).join("INDEX.toml"); if !index_path.exists() { return Err("Index file not found. Please run 'mesk update' first.".into()); } let index_content = fs::read_to_string(&index_path)?; let index: crate::pkgtoolkit::types::Index = toml::from_str(&index_content).map_err(|e| format!("Failed to parse index: {}", e))?; let package = index .packages .iter() .find(|pkg| pkg.name == pkg_name) .ok_or(format!("Package '{}' not found in index", pkg_name))?; Self::get_package_source(package, config) } }