pull,deb: add top-level --pocket option
- pull: select the pocket to download the source package from
- deb: build against dependencies from a specific pocket:
- local mode: enable '{series}-{pocket}' suite on archive sources
- cross mode: include the pocket suite in required repositories
This commit is contained in:
@@ -18,6 +18,7 @@ Options:
|
|||||||
-d, --dist <dist> Target package distribution (debian, ubuntu)
|
-d, --dist <dist> Target package distribution (debian, ubuntu)
|
||||||
-v, --version <version> Target package version
|
-v, --version <version> Target package version
|
||||||
-a, --arch <arch> Target architecture (amd64, arm64, riscv64, ...)
|
-a, --arch <arch> Target architecture (amd64, arm64, riscv64, ...)
|
||||||
|
-p, --pocket <pocket> Target distribution pocket (updates, security, proposed, ...)
|
||||||
--ppa <ppa> Do the action in/for a specific PPA
|
--ppa <ppa> Do the action in/for a specific PPA
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
+22
-7
@@ -38,6 +38,7 @@ pub fn setup_environment(
|
|||||||
pub fn ensure_repositories(
|
pub fn ensure_repositories(
|
||||||
arch: &str,
|
arch: &str,
|
||||||
series: &str,
|
series: &str,
|
||||||
|
pocket: Option<&str>,
|
||||||
ctx: Arc<Context>,
|
ctx: Arc<Context>,
|
||||||
) -> Result<(), Box<dyn Error>> {
|
) -> Result<(), Box<dyn Error>> {
|
||||||
let local_arch = crate::get_current_arch();
|
let local_arch = crate::get_current_arch();
|
||||||
@@ -74,12 +75,19 @@ pub fn ensure_repositories(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Ensure all suites (pockets) are enabled, excluding 'proposed'
|
// Ensure all suites (pockets) are enabled, excluding 'proposed'
|
||||||
let required_suites = [
|
// unless explicitly requested through the 'pocket' option
|
||||||
|
let mut required_suites = vec![
|
||||||
series.to_string(),
|
series.to_string(),
|
||||||
format!("{}-updates", series),
|
format!("{}-updates", series),
|
||||||
format!("{}-backports", series),
|
format!("{}-backports", series),
|
||||||
format!("{}-security", series),
|
format!("{}-security", series),
|
||||||
];
|
];
|
||||||
|
if let Some(p) = pocket {
|
||||||
|
let pocket_suite = format!("{series}-{p}");
|
||||||
|
if !required_suites.contains(&pocket_suite) {
|
||||||
|
required_suites.push(pocket_suite);
|
||||||
|
}
|
||||||
|
}
|
||||||
for suite in required_suites {
|
for suite in required_suites {
|
||||||
if !source.suite.contains(&suite) {
|
if !source.suite.contains(&suite) {
|
||||||
source.suite.push(suite);
|
source.suite.push(suite);
|
||||||
@@ -95,6 +103,18 @@ pub fn ensure_repositories(
|
|||||||
|
|
||||||
if !has_ports {
|
if !has_ports {
|
||||||
// Add ports repository for the target architecture
|
// Add ports repository for the target architecture
|
||||||
|
let mut ports_suites = vec![
|
||||||
|
format!("{series}"),
|
||||||
|
format!("{series}-updates"),
|
||||||
|
format!("{series}-backports"),
|
||||||
|
format!("{series}-security"),
|
||||||
|
];
|
||||||
|
if let Some(p) = pocket {
|
||||||
|
let pocket_suite = format!("{series}-{p}");
|
||||||
|
if !ports_suites.contains(&pocket_suite) {
|
||||||
|
ports_suites.push(pocket_suite);
|
||||||
|
}
|
||||||
|
}
|
||||||
let ports_entry = crate::apt::sources::SourceEntry {
|
let ports_entry = crate::apt::sources::SourceEntry {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
components: vec![
|
components: vec![
|
||||||
@@ -105,12 +125,7 @@ pub fn ensure_repositories(
|
|||||||
],
|
],
|
||||||
architectures: vec![arch.to_string()],
|
architectures: vec![arch.to_string()],
|
||||||
uri: "http://ports.ubuntu.com/ubuntu-ports".to_string(),
|
uri: "http://ports.ubuntu.com/ubuntu-ports".to_string(),
|
||||||
suite: vec![
|
suite: ports_suites,
|
||||||
format!("{series}"),
|
|
||||||
format!("{series}-updates"),
|
|
||||||
format!("{series}-backports"),
|
|
||||||
format!("{series}-security"),
|
|
||||||
],
|
|
||||||
};
|
};
|
||||||
sources.push(ports_entry);
|
sources.push(ports_entry);
|
||||||
}
|
}
|
||||||
|
|||||||
+15
-1
@@ -17,6 +17,7 @@ pub async fn build(
|
|||||||
version: &str,
|
version: &str,
|
||||||
arch: &str,
|
arch: &str,
|
||||||
series: &str,
|
series: &str,
|
||||||
|
pocket: Option<&str>,
|
||||||
build_root: &str,
|
build_root: &str,
|
||||||
cross: bool,
|
cross: bool,
|
||||||
ppa: Option<&[&str]>,
|
ppa: Option<&[&str]>,
|
||||||
@@ -53,7 +54,7 @@ pub async fn build(
|
|||||||
if cross {
|
if cross {
|
||||||
log::debug!("Setting up environment for local cross build...");
|
log::debug!("Setting up environment for local cross build...");
|
||||||
cross::setup_environment(&mut env, arch, ctx.clone())?;
|
cross::setup_environment(&mut env, arch, ctx.clone())?;
|
||||||
cross::ensure_repositories(arch, series, ctx.clone())?;
|
cross::ensure_repositories(arch, series, pocket, ctx.clone())?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut sources = apt::sources::load(Some(ctx.clone()))?;
|
let mut sources = apt::sources::load(Some(ctx.clone()))?;
|
||||||
@@ -116,6 +117,19 @@ pub async fn build(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Enable the requested pocket on archive sources, so build-dependencies
|
||||||
|
// are resolved from that pocket
|
||||||
|
if let Some(pocket_name) = pocket {
|
||||||
|
let pocket_suite = format!("{series}-{pocket_name}");
|
||||||
|
log::info!("Enabling pocket '{}' for build dependencies", pocket_suite);
|
||||||
|
for source in &mut sources {
|
||||||
|
if crate::deb::is_archive_source(&source.uri) && !source.suite.contains(&pocket_suite) {
|
||||||
|
source.suite.push(pocket_suite.clone());
|
||||||
|
modified = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if modified {
|
if modified {
|
||||||
apt::sources::save_legacy(Some(ctx.clone()), sources, "/etc/apt/sources.list")?;
|
apt::sources::save_legacy(Some(ctx.clone()), sources, "/etc/apt/sources.list")?;
|
||||||
|
|
||||||
|
|||||||
+13
-1
@@ -19,6 +19,7 @@ pub enum BuildMode {
|
|||||||
pub async fn build_binary_package(
|
pub async fn build_binary_package(
|
||||||
arch: Option<&str>,
|
arch: Option<&str>,
|
||||||
series: Option<&str>,
|
series: Option<&str>,
|
||||||
|
pocket: Option<&str>,
|
||||||
cwd: Option<&Path>,
|
cwd: Option<&Path>,
|
||||||
cross: bool,
|
cross: bool,
|
||||||
mode: Option<BuildMode>,
|
mode: Option<BuildMode>,
|
||||||
@@ -99,6 +100,7 @@ pub async fn build_binary_package(
|
|||||||
&version,
|
&version,
|
||||||
arch,
|
arch,
|
||||||
series,
|
series,
|
||||||
|
pocket,
|
||||||
&build_root,
|
&build_root,
|
||||||
cross,
|
cross,
|
||||||
ppa,
|
ppa,
|
||||||
@@ -107,7 +109,7 @@ pub async fn build_binary_package(
|
|||||||
)
|
)
|
||||||
.await?
|
.await?
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
// Retrieve produced .deb files
|
// Retrieve produced .deb files
|
||||||
let remote_files = build_ctx.list_files(Path::new(&build_root))?;
|
let remote_files = build_ctx.list_files(Path::new(&build_root))?;
|
||||||
@@ -256,6 +258,15 @@ fn find_dsc_file(
|
|||||||
Ok(dsc_path)
|
Ok(dsc_path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Check whether an apt source URI points to a distribution archive
|
||||||
|
/// (as opposed to a PPA or another third-party repository)
|
||||||
|
pub(crate) fn is_archive_source(uri: &str) -> bool {
|
||||||
|
uri.contains("archive.ubuntu.com")
|
||||||
|
|| uri.contains("security.ubuntu.com")
|
||||||
|
|| uri.contains("ports.ubuntu.com")
|
||||||
|
|| uri.contains("deb.debian.org")
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
@@ -303,6 +314,7 @@ mod tests {
|
|||||||
crate::deb::build_binary_package(
|
crate::deb::build_binary_package(
|
||||||
arch,
|
arch,
|
||||||
Some(series),
|
Some(series),
|
||||||
|
None,
|
||||||
Some(&cwd),
|
Some(&cwd),
|
||||||
cross,
|
cross,
|
||||||
None,
|
None,
|
||||||
|
|||||||
+10
-1
@@ -50,6 +50,7 @@ fn main() {
|
|||||||
.arg(arg!(-v --version <version> "Target package version").required(false))
|
.arg(arg!(-v --version <version> "Target package version").required(false))
|
||||||
.arg(arg!(--archive "Only use the archive to download package source, not git").required(false))
|
.arg(arg!(--archive "Only use the archive to download package source, not git").required(false))
|
||||||
.arg(arg!(--ppa <ppa> "Download the package from a specific PPA").required(false))
|
.arg(arg!(--ppa <ppa> "Download the package from a specific PPA").required(false))
|
||||||
|
.arg(arg!(-p --pocket <pocket> "Target package distribution pocket (updates, security, proposed)").required(false))
|
||||||
.arg(arg!(<package> "Target package")),
|
.arg(arg!(<package> "Target package")),
|
||||||
)
|
)
|
||||||
.subcommand(
|
.subcommand(
|
||||||
@@ -65,6 +66,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!(-p --pocket <pocket> "Build against dependencies from a specific distribution pocket (updates, security, proposed)").required(false)
|
||||||
|
.long_help("Build against dependencies from a specific distribution pocket (e.g. updates, security, proposed).\nThe '<series>-<pocket>' suite will be enabled on archive sources when resolving build-dependencies."))
|
||||||
.arg(arg!(--ppa <ppa> "Build the package adding a specific PPA for dependencies (can be specified multiple times)")
|
.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))
|
.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)")
|
||||||
@@ -130,6 +133,10 @@ fn main() {
|
|||||||
let dist = sub_matches.get_one::<String>("dist").map(|s| s.as_str());
|
let dist = sub_matches.get_one::<String>("dist").map(|s| s.as_str());
|
||||||
let version = sub_matches.get_one::<String>("version").map(|s| s.as_str());
|
let version = sub_matches.get_one::<String>("version").map(|s| s.as_str());
|
||||||
let ppa = sub_matches.get_one::<String>("ppa").map(|s| s.as_str());
|
let ppa = sub_matches.get_one::<String>("ppa").map(|s| s.as_str());
|
||||||
|
let pocket = sub_matches
|
||||||
|
.get_one::<String>("pocket")
|
||||||
|
.map(|s| s.as_str())
|
||||||
|
.unwrap_or("");
|
||||||
let archive = sub_matches.get_one::<bool>("archive").unwrap_or(&false);
|
let archive = sub_matches.get_one::<bool>("archive").unwrap_or(&false);
|
||||||
|
|
||||||
let (pb, progress_callback) = ui::create_progress_bar(&multi);
|
let (pb, progress_callback) = ui::create_progress_bar(&multi);
|
||||||
@@ -151,7 +158,7 @@ fn main() {
|
|||||||
package,
|
package,
|
||||||
version,
|
version,
|
||||||
series,
|
series,
|
||||||
"",
|
pocket,
|
||||||
dist,
|
dist,
|
||||||
base_url.as_deref(),
|
base_url.as_deref(),
|
||||||
Some(&progress_callback),
|
Some(&progress_callback),
|
||||||
@@ -251,6 +258,7 @@ fn main() {
|
|||||||
Some(("deb", sub_matches)) => {
|
Some(("deb", sub_matches)) => {
|
||||||
let cwd = current_dir_or_exit();
|
let cwd = current_dir_or_exit();
|
||||||
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 pocket = sub_matches.get_one::<String>("pocket").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: Vec<&str> = sub_matches
|
let ppa: Vec<&str> = sub_matches
|
||||||
@@ -281,6 +289,7 @@ fn main() {
|
|||||||
pkh::deb::build_binary_package(
|
pkh::deb::build_binary_package(
|
||||||
arch,
|
arch,
|
||||||
series,
|
series,
|
||||||
|
pocket,
|
||||||
Some(cwd.as_path()),
|
Some(cwd.as_path()),
|
||||||
*cross,
|
*cross,
|
||||||
mode,
|
mode,
|
||||||
|
|||||||
Reference in New Issue
Block a user