use std::fs; use std::os::unix::fs::MetadataExt; use crate::utils::parser::{self, env::get_install_env}; use crate::utils::shell::{run_install_script,run_install_script_hook}; use crate::commands::link::link; use super::download::download; use super::patch::patch; pub fn build( repo: &String, pkgname: &String, ) -> Result<(), bool> { let src_dir = &crate::commands::get_aeropkg_base().join("src").join(&pkgname); let pkg_md_path = &crate::commands::get_var_path().join(format!("{}/{}.md", &repo, &pkgname)); let builded_pkg_md_path = crate::commands::get_aeropkg_base().join(&repo).join(&pkgname).join("build-script.md"); if builded_pkg_md_path.exists() { if fs::metadata(&builded_pkg_md_path).unwrap().ino() == fs::metadata(&pkg_md_path).unwrap().ino() { println!("package {} already installed in {} repo", &pkgname, &repo); return Ok(()) } } let build_script = match parser::get_build_script(pkg_md_path) { Ok(script) => script, Err(error) => { eprintln!("Failed to parse build script: {}", error); return Err(false); } }; if src_dir.join("aeropkg.applied-build").exists() { let src_build = fs::read_to_string(src_dir.join("aeropkg.applied-build")).unwrap_or("".to_string()); if build_script == src_build { return Ok(()) } else { println!("build:\n{}\nend build", build_script); println!("src build:\n{}\nend src build", src_build); fs::remove_dir_all(src_dir).unwrap(); download(&repo, &pkgname)?; patch(&repo, &pkgname)?; } } let full_env = get_install_env(repo, pkgname, pkg_md_path, "build"); run_install_script(&build_script, src_dir, &full_env)?; run_install_script_hook(repo, "build", &full_env)?; let dest_dir = crate::commands::get_aeropkg_base().join(repo).join(pkgname); if let Err(e) = fs::create_dir_all(&dest_dir) { eprintln!("Failed to create destination directory: {}", e); return Err(false); } let dest_path = dest_dir.join("build-script.md"); fs::remove_file(&dest_path).ok(); if let Err(e) = fs::hard_link(pkg_md_path, &dest_path) { eprintln!("Failed to copy build script to destination: {}", e); return Err(false); } fs::write(src_dir.join("aeropkg.build-script"), &build_script).unwrap(); let link_flag = full_env.get("disable").map_or(true, |v| v != "true"); if !link_flag { let _ = fs::File::create(crate::commands::get_aeropkg_base().join(repo).join(pkgname).join("disabled")); } link(&repo, &pkgname).expect("Failed link package"); let save_source_flag = full_env.get("save_source").map_or(false, |v| v == "true"); if !save_source_flag { if let Err(e) = fs::remove_dir_all(&src_dir) { eprintln!("Failed to remove source directory: {}", e); return Err(false); } } hook(&repo, &pkgname); Ok(()) } fn hook(repo: &String, pkgname: &String) { let pkg_dir = crate::commands::get_aeropkg_base().join(&repo).join(&pkgname); let lib_dir = &pkg_dir.join("lib"); let lib64_dir = &pkg_dir.join("lib64"); let lib32_dir = &pkg_dir.join("lib32"); crate::utils::fs::mv::mv(&lib64_dir, &lib_dir).ok(); crate::utils::fs::mv::mv(&lib32_dir, &lib_dir).ok(); fs::remove_dir_all(&lib64_dir).ok(); fs::remove_dir_all(&lib32_dir).ok(); }