Multiple changes:
All checks were successful
CI / build (push) Successful in 16m23s
CI / snap (push) Successful in 4m1s

- deb: can use ppa as dependency
- deb: cross and regular are using parallel nocheck builds
- deb: ephemeral will not pull keyring if no root powers
This commit is contained in:
2026-02-06 12:04:25 +01:00
parent 225157be63
commit 8345f51d2f
11 changed files with 233 additions and 16 deletions

View File

@@ -2,6 +2,7 @@
/// Directly calling 'debian/rules' in current context
use crate::context;
use crate::deb::find_dsc_file;
use log::warn;
use std::collections::HashMap;
use std::error::Error;
use std::path::Path;
@@ -9,13 +10,14 @@ use std::path::Path;
use crate::apt;
use crate::deb::cross;
pub fn build(
pub async fn build(
package: &str,
version: &str,
arch: &str,
series: &str,
build_root: &str,
cross: bool,
ppa: Option<&str>,
) -> Result<(), Box<dyn Error>> {
// Environment
let mut env = HashMap::<String, String>::new();
@@ -39,9 +41,11 @@ pub fn build(
}
})
.unwrap_or(1); // Default to 1 if we can't execute the command
// Build options: parallel, disable tests by default
env.insert(
"DEB_BUILD_OPTIONS".to_string(),
format!("parallel={}", num_cores),
format!("parallel={} nocheck", num_cores),
);
if cross {
@@ -50,17 +54,73 @@ pub fn build(
cross::ensure_repositories(arch, series)?;
}
// UBUNTU: Ensure 'universe' repository is enabled
let mut sources = apt::sources::load(None)?;
let mut modified = false;
// Add PPA repository if specified
if let Some(ppa_str) = ppa {
// PPA format: user/ppa_name
let parts: Vec<&str> = ppa_str.split('/').collect();
if parts.len() == 2 {
let base_url = crate::package_info::ppa_to_base_url(parts[0], parts[1]);
// Add new PPA source if not found
if !sources.iter().any(|s| s.uri.contains(&base_url)) {
// Get host and target architectures
let host_arch = crate::get_current_arch();
let target_arch = if cross { arch } else { &host_arch };
// Create architectures list with both host and target if different
let mut architectures = vec![host_arch.clone()];
if host_arch != *target_arch {
architectures.push(target_arch.to_string());
}
// Create suite list with all Ubuntu series
let suites = vec![format!("{}", series)];
let new_source = crate::apt::sources::SourceEntry {
enabled: true,
components: vec!["main".to_string()],
architectures: architectures.clone(),
suite: suites,
uri: base_url,
};
sources.push(new_source);
modified = true;
log::info!(
"Added PPA: {} for series {} with architectures {:?}",
ppa_str,
series,
architectures
);
}
} else {
return Err("Invalid PPA format. Expected: user/ppa_name".into());
}
}
// UBUNTU: Ensure 'universe' repository is enabled
for source in &mut sources {
if source.uri.contains("ubuntu") && !source.components.contains(&"universe".to_string()) {
source.components.push("universe".to_string());
modified = true;
}
}
if modified {
apt::sources::save_legacy(None, sources, "/etc/apt/sources.list")?;
// Download and import PPA key if we added a PPA
if let Some(ppa_str) = ppa {
let parts: Vec<&str> = ppa_str.split('/').collect();
if parts.len() == 2
&& let Err(e) =
crate::apt::keyring::download_trust_ppa_key(None, parts[0], parts[1]).await
{
warn!("Failed to download PPA key for {}: {}", ppa_str, e);
}
}
}
// Update package lists
@@ -106,8 +166,8 @@ pub fn build(
.to_str()
.ok_or("Invalid package directory path")?;
// Install build dependencies
log::debug!("Installing build dependencies...");
// Install arch-specific build dependencies
log::debug!("Installing arch-specific build dependencies...");
let mut cmd = ctx.command("apt-get");
cmd.current_dir(package_dir_str)
.envs(env.clone())
@@ -116,6 +176,7 @@ pub fn build(
if cross {
cmd.arg(format!("--host-architecture={arch}"));
}
cmd.arg("--arch-only");
let status = cmd.arg("./").status()?;
// If build-dep fails, we try to explain the failure using dose-debcheck
@@ -124,6 +185,23 @@ pub fn build(
return Err("Could not install build-dependencies for the build".into());
}
// // Install arch-independant build dependencies
// log::debug!("Installing arch-independant build dependencies...");
// let status = ctx.command("apt-get")
// .current_dir(package_dir_str)
// .envs(env.clone())
// .arg("-y")
// .arg("build-dep")
// .arg("--indep-only")
// .arg("./")
// .status()?;
// // If build-dep fails, we try to explain the failure using dose-debcheck
// if !status.success() {
// dose3_explain_dependencies(package, version, arch, build_root, cross)?;
// return Err("Could not install build-dependencies for the build".into());
// }
// Run the build step
log::debug!("Building (debian/rules build) package...");
let status = ctx