diff --git a/src/deb/local.rs b/src/deb/local.rs index 183ec74..a6e506e 100644 --- a/src/deb/local.rs +++ b/src/deb/local.rs @@ -10,6 +10,7 @@ use std::path::Path; use crate::apt; use crate::deb::cross; +#[allow(clippy::too_many_arguments)] pub async fn build( package: &str, version: &str, @@ -18,6 +19,7 @@ pub async fn build( build_root: &str, cross: bool, ppa: Option<&str>, + inject_packages: Option<&[&str]>, ) -> Result<(), Box> { // Environment let mut env = HashMap::::new(); @@ -166,6 +168,20 @@ pub async fn build( .to_str() .ok_or("Invalid package directory path")?; + // Install injected packages if specified + if let Some(packages) = inject_packages { + log::info!("Installing injected packages: {:?}", packages); + let mut cmd = ctx.command("apt-get"); + cmd.envs(env.clone()) + .arg("-y") + .arg("install") + .args(packages); + let status = cmd.status()?; + if !status.success() { + return Err(format!("Could not install injected packages: {:?}", packages).into()); + } + } + // Install arch-specific build dependencies log::debug!("Installing arch-specific build dependencies..."); let mut cmd = ctx.command("apt-get"); diff --git a/src/deb/mod.rs b/src/deb/mod.rs index 33a6e5d..605e248 100644 --- a/src/deb/mod.rs +++ b/src/deb/mod.rs @@ -24,6 +24,7 @@ pub async fn build_binary_package( cross: bool, mode: Option, ppa: Option<&str>, + inject_packages: Option<&[&str]>, ) -> Result<(), Box> { let cwd = cwd.unwrap_or_else(|| Path::new(".")); @@ -77,7 +78,17 @@ pub async fn build_binary_package( // Run the build using target build mode match mode { BuildMode::Local => { - local::build(&package, &version, arch, series, &build_root, cross, ppa).await? + local::build( + &package, + &version, + arch, + series, + &build_root, + cross, + ppa, + inject_packages, + ) + .await? } BuildMode::Sbuild => sbuild::build(&package, &version, arch, series, &build_root, cross)?, }; @@ -237,7 +248,7 @@ mod tests { log::debug!("Package directory: {}", cwd.display()); log::info!("Starting binary package build..."); - crate::deb::build_binary_package(arch, Some(series), Some(&cwd), cross, None, None) + crate::deb::build_binary_package(arch, Some(series), Some(&cwd), cross, None, None, None) .await .expect("Cannot build binary package (deb)"); log::info!("Successfully built binary package"); diff --git a/src/main.rs b/src/main.rs index 121a867..390b9e7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -55,6 +55,8 @@ fn main() { .arg(arg!(-s --series "Target distribution series").required(false)) .arg(arg!(-a --arch "Target architecture").required(false)) .arg(arg!(--ppa "Build the package adding a specific PPA for dependencies").required(false)) + .arg(arg!(--inject "Inject a package into the build environment (can be specified multiple times)") + .long_help("Inject a package into the build environment before build-dep. Can be a .deb file path, a package name from the archive, or a package from a previously added PPA. Can be specified multiple times.").required(false).action(clap::ArgAction::Append)) .arg(arg!(--cross "Cross-compile for target architecture (instead of qemu-binfmt)") .long_help("Cross-compile for target architecture (instead of using qemu-binfmt)\nNote that most packages cannot be cross-compiled").required(false)) .arg(arg!(--mode "Change build mode [sbuild, local]").required(false) @@ -161,6 +163,15 @@ fn main() { let arch = sub_matches.get_one::("arch").map(|s| s.as_str()); let cross = sub_matches.get_one::("cross").unwrap_or(&false); let ppa = sub_matches.get_one::("ppa").map(|s| s.as_str()); + let inject_packages: Vec<&str> = sub_matches + .get_many::("inject") + .map(|v| v.map(|s| s.as_str()).collect()) + .unwrap_or_default(); + let inject_packages = if inject_packages.is_empty() { + None + } else { + Some(inject_packages.as_slice()) + }; let mode: Option<&str> = sub_matches.get_one::("mode").map(|s| s.as_str()); let mode: Option = match mode { Some("sbuild") => Some(pkh::deb::BuildMode::Sbuild), @@ -169,8 +180,16 @@ fn main() { }; if let Err(e) = rt.block_on(async { - pkh::deb::build_binary_package(arch, series, Some(cwd.as_path()), *cross, mode, ppa) - .await + pkh::deb::build_binary_package( + arch, + series, + Some(cwd.as_path()), + *cross, + mode, + ppa, + inject_packages, + ) + .await }) { error!("{}", e); std::process::exit(1);