diff --git a/assets/etc/aeropkg.md b/assets/etc/aeropkg.md index abf108b..e8d9752 100644 --- a/assets/etc/aeropkg.md +++ b/assets/etc/aeropkg.md @@ -54,3 +54,7 @@ mount_usr_dir !** !aeropkg ``` + +``` sh *** hook *** + +``` diff --git a/src/commands/download.rs b/src/commands/download.rs index 1b60ecd..5b30338 100644 --- a/src/commands/download.rs +++ b/src/commands/download.rs @@ -5,7 +5,8 @@ use std::io::{self, Write}; use std::cell::RefCell; use super::get_aeropkg_base; -use crate::utils::parser::{self, env::get_install_env, pkginfo, repoinfo}; +use crate::utils::parser::{self, env::get_install_env, repoinfo, pkginfo, env::get_custom_env}; +use crate::utils::shell; use crate::commands::link::link; use crate::commands::run::config::config; @@ -58,11 +59,15 @@ pub fn download_packages( ) { for pkgname in packages { let effective_repo = match repo { - Some(r) => r.to_string(), - None => pkginfo::get_priority_repo(pkgname), + Some(r) => &r.to_string(), + None => &pkginfo::get_priority_repo(pkgname), }; - download(&effective_repo, pkgname, force, recursive); + download(effective_repo, pkgname, force, recursive); + let pkg_md_path = &crate::commands::get_aeropkg_var().join(format!("{}/{}.md", effective_repo, pkgname)); + let full_env = &get_custom_env(effective_repo, pkgname, pkg_md_path); + shell::run_install_repo_hook_script(effective_repo, full_env); + shell::run_install_hook_script(full_env); } } diff --git a/src/commands/install.rs b/src/commands/install.rs index 956a44a..a6d5bcf 100644 --- a/src/commands/install.rs +++ b/src/commands/install.rs @@ -2,7 +2,8 @@ use std::path::Path; use std::fs; use std::os::unix::fs::MetadataExt; -use crate::utils::parser::{self, pkginfo}; +use crate::utils::parser::{self, pkginfo, env::get_custom_env}; +use crate::utils::shell; use super::run::download::download; use super::run::patch::patch; use super::run::build::build; @@ -22,6 +23,9 @@ pub fn install(repo: &String, pkgname: &String) { patch(repo, pkgname); build(repo, pkgname); config(repo, pkgname); + let full_env = &get_custom_env(repo, pkgname, pkg_md_path); + shell::run_install_repo_hook_script(repo, full_env); + shell::run_install_hook_script(full_env); } fn check_build_dependency(repo: &String, pkg_md_path: &Path) { diff --git a/src/commands/run/build.rs b/src/commands/run/build.rs index d345b45..6e3ce04 100644 --- a/src/commands/run/build.rs +++ b/src/commands/run/build.rs @@ -1,7 +1,7 @@ use std::fs; use crate::commands::link::link; use crate::utils::parser::{self, env::get_install_env}; -use crate::utils::shell::{run_install_script, run_install_script_hook}; +use crate::utils::shell::self; use super::{download, patch}; pub fn build(repo: &String, pkgname: &String) { @@ -38,8 +38,9 @@ pub fn build(repo: &String, pkgname: &String) { save_env(&applied_env, &full_env); - run_install_script(&build_script, &src_dir, &full_env); - run_install_script_hook(repo, "build", &full_env); + shell::run_install_script(&build_script, &src_dir, &full_env); + shell::run_install_repo_stage_hook_script(repo, "build", &full_env); + shell::run_install_stage_hook_script("download", &full_env); fs::create_dir_all(&pkg_dir).ok(); fs::write(&applied_build, &build_script).unwrap(); diff --git a/src/commands/run/config.rs b/src/commands/run/config.rs index ff4696d..ffbfba5 100644 --- a/src/commands/run/config.rs +++ b/src/commands/run/config.rs @@ -1,6 +1,6 @@ use crate::commands::link::link; use crate::utils::parser::{self, env::get_install_env}; -use crate::utils::shell::{run_install_script,run_install_script_hook}; +use crate::utils::shell; pub fn config(repo: &String, pkgname: &String) { @@ -13,8 +13,10 @@ pub fn config(repo: &String, pkgname: &String) { }; let full_env = get_install_env(repo, pkgname, pkg_md_path, "config"); - run_install_script(&config_script, pkg_dir, &full_env); - run_install_script_hook(repo, "config", &full_env); + shell::run_install_script(&config_script, pkg_dir, &full_env); + shell::run_install_repo_stage_hook_script(repo, "config", &full_env); + shell::run_install_stage_hook_script("download", &full_env); + if !crate::commands::get_aeropkg_base().join(repo).join(pkgname).join("disabled").exists() { link(repo, pkgname) diff --git a/src/commands/run/download.rs b/src/commands/run/download.rs index 484cd5c..7eccc2b 100644 --- a/src/commands/run/download.rs +++ b/src/commands/run/download.rs @@ -3,7 +3,7 @@ use std::path::Path; use std::process::{Command, Stdio}; use crate::utils::parser::{self, env::get_install_env}; -use crate::utils::shell::run_install_script_hook; +use crate::utils::shell; pub fn download(repo: &String, pkgname: &String) { let pkg_md_path = &crate::commands::get_aeropkg_var().join(format!("{}/{}.md", repo, pkgname)); @@ -156,7 +156,8 @@ pub fn download(repo: &String, pkgname: &String) { fs::write(src.join(".aeropkg.download-url"), &url).unwrap(); - run_install_script_hook(repo, "download", &full_env) + shell::run_install_repo_stage_hook_script(repo, "download", &full_env); + shell::run_install_stage_hook_script("download", &full_env); } fn upload_from_repo(repo: &String, pkgname: &String, pkg_md_path: &Path) { diff --git a/src/commands/run/patch.rs b/src/commands/run/patch.rs index 68094cb..8996fa2 100644 --- a/src/commands/run/patch.rs +++ b/src/commands/run/patch.rs @@ -1,7 +1,7 @@ use std::fs; use crate::utils::parser::{self, env::get_install_env}; -use crate::utils::shell::{run_install_script,run_install_script_hook}; +use crate::utils::shell; use super::download::download; pub fn patch(repo: &String, pkgname: &String) { @@ -21,7 +21,9 @@ pub fn patch(repo: &String, pkgname: &String) { } let full_env = get_install_env(repo, pkgname, pkg_md_path, "patch"); - run_install_script(patch_script, src, &full_env); - run_install_script_hook(repo, "patch", &full_env); + shell::run_install_script(patch_script, src, &full_env); + shell::run_install_repo_stage_hook_script(repo, "patch", &full_env); + shell::run_install_stage_hook_script("download", &full_env); + fs::write(src.join(".aeropkg.applied-patch"), &patch_script).unwrap() } diff --git a/src/utils/parser/mod.rs b/src/utils/parser/mod.rs index de6db32..c3b2d23 100644 --- a/src/utils/parser/mod.rs +++ b/src/utils/parser/mod.rs @@ -6,6 +6,15 @@ use std::fs; use std::io::{self, BufRead}; use std::path::Path; +pub fn get_general_hook() -> io::Result { + let cfg_path = &crate::commands::get_aeropkg_etc().join("aeropkg.md"); + extract_block(cfg_path, &format!("``` sh *** hook ***"), "```") +} + +pub fn get_repo_hook(stage: &str) -> io::Result { + let cfg_path = &crate::commands::get_aeropkg_etc().join("aeropkg.md"); + extract_block(cfg_path, &format!("``` sh *** hook {} ***", &stage), "```") +} pub fn get_stage_hook(stage: &str) -> io::Result { let cfg_path = &crate::commands::get_aeropkg_etc().join("aeropkg.md"); diff --git a/src/utils/shell.rs b/src/utils/shell.rs index a9f3634..3693e8f 100644 --- a/src/utils/shell.rs +++ b/src/utils/shell.rs @@ -68,7 +68,7 @@ pub fn shell_update() { if !output_ldconfig.status.success() { panic!("ldconfig failed: {}", String::from_utf8_lossy(&output_ldconfig.stderr)) } } -pub fn run_install_script_hook(repo: &str, stage: &str, full_env: &HashMap) { +pub fn run_install_repo_stage_hook_script(repo: &str, stage: &str, full_env: &HashMap) { let hook_script = match parser::get_repo_and_stage_hook(repo, stage) { Ok(script) => Ok(script), Err(_) => parser::get_stage_hook(stage) @@ -89,6 +89,52 @@ pub fn run_install_script_hook(repo: &str, stage: &str, full_env: &HashMap) { + run_install_stage_hook_script(repo, full_env); +} + +pub fn run_install_stage_hook_script(stage: &str, full_env: &HashMap) { + let hook_script = match parser::get_stage_hook(stage) { + Ok(script) => Ok(script), + Err(_) => parser::get_stage_hook(stage) + }; + + let shell = env::var("SHELL").unwrap_or_else(|_| "/bin/sh".to_string()); + + if let Ok(script) = hook_script { + let output = Command::new(&shell) + .arg("-c") + .arg(format!("set -e\n{}", script)) + .envs(full_env) + .output(); + + if let Err(e) = output { panic!("Failed to execute hook script: {}", e) } + let output = output.unwrap(); + if !output.status.success() { panic!("Hook script failed: {:?}", output) } + } +} + +pub fn run_install_hook_script(full_env: &HashMap) { + let hook_script = match parser::get_general_hook() { + Ok(script) => Ok(script), + Err(_) => parser::get_general_hook() + }; + + let shell = env::var("SHELL").unwrap_or_else(|_| "/bin/sh".to_string()); + + if let Ok(script) = hook_script { + let output = Command::new(&shell) + .arg("-c") + .arg(format!("set -e\n{}", script)) + .envs(full_env) + .output(); + + if let Err(e) = output { panic!("Failed to execute hook script: {}", e) } + let output = output.unwrap(); + if !output.status.success() { panic!("Hook script failed: {:?}", output) } + } +} + pub fn run_install_script(script: &str, work_dir: &Path, full_env: &HashMap) { let shell = env::var("SHELL").unwrap_or_else(|_| "/bin/sh".to_string());