diff --git a/backend/src/pkgbuild/build.rs b/backend/src/pkgbuild/build.rs index 0828ccc..3f3ca2f 100644 --- a/backend/src/pkgbuild/build.rs +++ b/backend/src/pkgbuild/build.rs @@ -1,16 +1,16 @@ use anyhow::anyhow; use std::fs; use std::process::Stdio; -use std::time::SystemTime; use tokio::io::{AsyncBufReadExt, BufReader, Lines}; use tokio::sync::broadcast::Sender; +// todo consider removing pkg_vers from attribute list pub async fn build_pkgbuild( folder_path: String, pkg_vers: &str, pkg_name: &str, tx: Sender, -) -> anyhow::Result { +) -> anyhow::Result> { // update pacman cache let mut child = tokio::process::Command::new("pacman") .args(["-Sy"]) @@ -71,7 +71,7 @@ pub async fn build_pkgbuild( } } - locate_built_package(pkg_name.to_string(), pkg_vers.to_string(), folder_path) + locate_built_packages(pkg_name.to_string(), folder_path) } fn spawn_broadcast_sender( @@ -86,58 +86,35 @@ fn spawn_broadcast_sender( }); } -fn locate_built_package( - pkg_name: String, - pkg_vers: String, - folder_path: String, -) -> anyhow::Result { - // check if expected built dir exists - let built_name = build_expected_repo_packagename(pkg_name.to_string(), pkg_vers.to_string()); - if fs::metadata(format!("{folder_path}/{built_name}")).is_ok() { - println!("Built {built_name}"); - return Ok(built_name.to_string()); - } +/// a pkgbuild might build multiple packages +/// todo handle case later to pick only relevant one +fn locate_built_packages(pkg_name: String, folder_path: String) -> anyhow::Result> { + let mut pkg_names: Vec = vec![]; - // the naming might not always contain the build version - // eg. mesa-git --> match pkgname and extension if multiple return latest if let Ok(paths) = fs::read_dir(folder_path) { - let mut candidate_filename: Option = None; - let mut candidate_timestamp = SystemTime::UNIX_EPOCH; - for path in paths { if let Ok(path) = path { let path = path.path(); if let Some(file_name) = path.file_name() { let file_name = file_name.to_str().unwrap(); - if file_name.ends_with(".pkg.tar.zst") - && file_name.starts_with(pkg_name.as_str()) - { - if let Ok(metadata) = path.metadata() { - if let Ok(modified_time) = metadata.modified() { - // Update the candidate filename and timestamp if the current file is newer - if modified_time > candidate_timestamp { - candidate_filename = Some(file_name.to_string()); - candidate_timestamp = modified_time; - } - } - } + if file_name.ends_with(".pkg.tar.zst") { + pkg_names.push(file_name.to_string()); } } } } - - if candidate_filename.is_some() { - println!("Built {}", candidate_filename.clone().unwrap()); - return Ok(candidate_filename.unwrap()); - } } - Err(anyhow!("Built package not found")) -} - -/// don't trust this pkg name from existing -/// pkgbuild might build different version name -pub fn build_expected_repo_packagename(pkg_name: String, pkg_vers: String) -> String { - format!("{pkg_name}-{pkg_vers}-x86_64.pkg.tar.zst") + return if pkg_names.is_empty() { + Err(anyhow!("Built package not found")) + } else { + // expect at least one of the packages to start with the package name + if !pkg_names.iter().any(|x| x.starts_with(&pkg_name)) { + return Err(anyhow!( + "None of the built packages starts with the expected name" + )); + } + Ok(pkg_names) + }; } diff --git a/backend/src/repo/repo.rs b/backend/src/repo/repo.rs index c197b77..fcb773a 100644 --- a/backend/src/repo/repo.rs +++ b/backend/src/repo/repo.rs @@ -19,7 +19,7 @@ pub async fn add_pkg( tx: Sender, ) -> anyhow::Result { let fname = download_pkgbuild(format!("{}{}", BASEURL, url).as_str(), "./builds").await?; - let pkg_file_name = build_pkgbuild( + let pkg_file_names = build_pkgbuild( format!("./builds/{fname}"), version.as_str(), name.as_str(), @@ -27,16 +27,22 @@ pub async fn add_pkg( ) .await?; - // todo force overwrite if file already exists - fs::copy( - format!("./builds/{fname}/{pkg_file_name}"), - format!("./repo/{pkg_file_name}"), - )?; - fs::remove_file(format!("./builds/{fname}/{pkg_file_name}"))?; + // todo for now we just return first one if there are multiple + // unwrap is valid because there must be at least one element -> check inside locate_built_packages + let firstpkgname: String = pkg_file_names.first().unwrap().to_string(); - repo_add(pkg_file_name.clone())?; + for pkg_file_name in pkg_file_names { + // todo force overwrite if file already exists + fs::copy( + format!("./builds/{fname}/{pkg_file_name}"), + format!("./repo/{pkg_file_name}"), + )?; + fs::remove_file(format!("./builds/{fname}/{pkg_file_name}"))?; - Ok(pkg_file_name) + repo_add(pkg_file_name.clone())?; + } + + Ok(firstpkgname) } pub async fn remove_pkg(db: &DatabaseConnection, pkg_id: i32) -> anyhow::Result<()> {