deb: allow adding multiple ppas for deps
Some checks failed
CI / build (push) Failing after 13m29s
CI / snap (push) Has been skipped

This commit is contained in:
2026-02-19 15:36:08 +01:00
parent 02dbb41219
commit dce39c9a84
3 changed files with 61 additions and 46 deletions

View File

@@ -18,7 +18,7 @@ pub async fn build(
series: &str, series: &str,
build_root: &str, build_root: &str,
cross: bool, cross: bool,
ppa: Option<&str>, ppa: Option<&[&str]>,
inject_packages: Option<&[&str]>, inject_packages: Option<&[&str]>,
) -> Result<(), Box<dyn Error>> { ) -> Result<(), Box<dyn Error>> {
// Environment // Environment
@@ -58,47 +58,53 @@ pub async fn build(
let mut sources = apt::sources::load(None)?; let mut sources = apt::sources::load(None)?;
let mut modified = false; let mut modified = false;
let mut added_ppas: Vec<(&str, &str)> = Vec::new();
// Add PPA repository if specified // Add PPA repositories if specified
if let Some(ppa_str) = ppa { if let Some(ppas) = ppa {
// PPA format: user/ppa_name for ppa_str in ppas {
let parts: Vec<&str> = ppa_str.split('/').collect(); // PPA format: user/ppa_name
if parts.len() == 2 { let parts: Vec<&str> = ppa_str.split('/').collect();
let base_url = crate::package_info::ppa_to_base_url(parts[0], parts[1]); 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 // Add new PPA source if not found
if !sources.iter().any(|s| s.uri.contains(&base_url)) { if !sources.iter().any(|s| s.uri.contains(&base_url)) {
// Get host and target architectures // Get host and target architectures
let host_arch = crate::get_current_arch(); let host_arch = crate::get_current_arch();
let target_arch = arch; let target_arch = arch;
// Create architectures list with both host and target if different // Create architectures list with both host and target if different
let mut architectures = vec![host_arch.clone()]; let mut architectures = vec![host_arch.clone()];
if host_arch != *target_arch { if host_arch != *target_arch {
architectures.push(target_arch.to_string()); 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;
added_ppas.push((parts[0], parts[1]));
log::info!(
"Added PPA: {} for series {} with architectures {:?}",
ppa_str,
series,
architectures
);
} }
} else {
// Create suite list with all Ubuntu series return Err(
let suites = vec![format!("{}", series)]; format!("Invalid PPA format: '{}'. Expected: user/ppa_name", ppa_str).into(),
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());
} }
} }
@@ -113,14 +119,14 @@ pub async fn build(
if modified { if modified {
apt::sources::save_legacy(None, sources, "/etc/apt/sources.list")?; apt::sources::save_legacy(None, sources, "/etc/apt/sources.list")?;
// Download and import PPA key if we added a PPA // Download and import PPA keys for all added PPAs
if let Some(ppa_str) = ppa { for (user, ppa_name) in added_ppas {
let parts: Vec<&str> = ppa_str.split('/').collect(); if let Err(e) = crate::apt::keyring::download_trust_ppa_key(None, user, ppa_name).await
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); warn!(
"Failed to download PPA key for {}/{}: {}",
user, ppa_name, e
);
} }
} }
} }

View File

@@ -23,7 +23,7 @@ pub async fn build_binary_package(
cwd: Option<&Path>, cwd: Option<&Path>,
cross: bool, cross: bool,
mode: Option<BuildMode>, mode: Option<BuildMode>,
ppa: Option<&str>, ppa: Option<&[&str]>,
inject_packages: Option<&[&str]>, inject_packages: Option<&[&str]>,
) -> Result<(), Box<dyn Error>> { ) -> Result<(), Box<dyn Error>> {
let cwd = cwd.unwrap_or_else(|| Path::new(".")); let cwd = cwd.unwrap_or_else(|| Path::new("."));

View File

@@ -54,7 +54,8 @@ fn main() {
.about("Build the source package into binary package (.deb)") .about("Build the source package into binary package (.deb)")
.arg(arg!(-s --series <series> "Target distribution series").required(false)) .arg(arg!(-s --series <series> "Target distribution series").required(false))
.arg(arg!(-a --arch <arch> "Target architecture").required(false)) .arg(arg!(-a --arch <arch> "Target architecture").required(false))
.arg(arg!(--ppa <ppa> "Build the package adding a specific PPA for dependencies").required(false)) .arg(arg!(--ppa <ppa> "Build the package adding a specific PPA for dependencies (can be specified multiple times)")
.long_help("Build the package adding a specific PPA for dependencies. Can be specified multiple times.").required(false).action(clap::ArgAction::Append))
.arg(arg!(--inject <package> "Inject a package into the build environment (can be specified multiple times)") .arg(arg!(--inject <package> "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)) .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)") .arg(arg!(--cross "Cross-compile for target architecture (instead of qemu-binfmt)")
@@ -162,7 +163,15 @@ fn main() {
let series = sub_matches.get_one::<String>("series").map(|s| s.as_str()); let series = sub_matches.get_one::<String>("series").map(|s| s.as_str());
let arch = sub_matches.get_one::<String>("arch").map(|s| s.as_str()); let arch = sub_matches.get_one::<String>("arch").map(|s| s.as_str());
let cross = sub_matches.get_one::<bool>("cross").unwrap_or(&false); let cross = sub_matches.get_one::<bool>("cross").unwrap_or(&false);
let ppa = sub_matches.get_one::<String>("ppa").map(|s| s.as_str()); let ppa: Vec<&str> = sub_matches
.get_many::<String>("ppa")
.map(|v| v.map(|s| s.as_str()).collect())
.unwrap_or_default();
let ppa = if ppa.is_empty() {
None
} else {
Some(ppa.as_slice())
};
let inject_packages: Vec<&str> = sub_matches let inject_packages: Vec<&str> = sub_matches
.get_many::<String>("inject") .get_many::<String>("inject")
.map(|v| v.map(|s| s.as_str()).collect()) .map(|v| v.map(|s| s.as_str()).collect())