use std::error::Error; use std::path::Path; use std::process::Command; use crate::changelog::parse_changelog_footer; use crate::utils::gpg; /// Build a Debian source package (to a .dsc) pub fn build_source_package(cwd: Option<&Path>) -> Result<(), Box> { let cwd = cwd.unwrap_or_else(|| Path::new(".")); // Parse changelog to get maintainer information from the last modification entry let changelog_path = cwd.join("debian/changelog"); let (maintainer_name, maintainer_email) = parse_changelog_footer(&changelog_path)?; // Check if a GPG key matching the maintainer's email exists let signing_key = match gpg::find_signing_key_for_email(&maintainer_email) { Ok(key) => key, Err(e) => { // If GPG is not available or there's an error, continue without signing log::warn!("Failed to check for GPG key: {}", e); None } }; // Build command arguments let mut command = Command::new("dpkg-buildpackage"); command .current_dir(cwd) .arg("-S") .arg("-I") .arg("-i") .arg("-nc") .arg("-d"); // If a signing key is found, use it for signing if let Some(key_id) = &signing_key { command.arg(format!("--sign-keyid={}", key_id)); log::info!("Using GPG key {} for signing", key_id); } else { command.arg("--no-sign"); log::info!( "No GPG key found for {} ({}), building without signing", maintainer_name, maintainer_email ); } let status = command.status()?; if !status.success() { return Err(format!("dpkg-buildpackage failed with status: {}", status).into()); } if signing_key.is_some() { println!("Package built and signed successfully!"); } else { println!("Package built successfully (unsigned)."); } Ok(()) } #[cfg(test)] mod tests { // We are not testing the build part, as for now this is just a wrapper // around dpkg-buildpackage. }