deb: drive build_binary_package through the BuildView port
The binary build joins the source build on the reporting ports: build_binary_package takes a DebBuildOptions struct (replacing eleven positional arguments), reports target, phases, progress and the outcome through the environment-agnostic BuildView, and the Phase enum with its default classifiers moves from the terminal widget into the deb module (announced through the enter_phase helper). DebUi loses its inherent event methods and only implements the port; tee logging and the SIGINT behavior are unchanged. No behavior change for the CLI; headless consumers pass report::Quiet.
This commit is contained in:
+75
-88
@@ -1,9 +1,9 @@
|
||||
/// Local binary package building
|
||||
/// Directly calling 'debian/rules' in current context
|
||||
use crate::context::{Context, ContextCommand, LineSink};
|
||||
use crate::deb::find_dsc_file;
|
||||
use crate::deb::{Phase, enter_phase, find_dsc_file};
|
||||
use crate::logfmt::QuiltClassifier;
|
||||
use crate::ui::deb::{DebUi, Phase};
|
||||
use crate::report::BuildView;
|
||||
use log::warn;
|
||||
use std::collections::{BTreeMap, HashMap};
|
||||
use std::error::Error;
|
||||
@@ -33,13 +33,13 @@ pub async fn build(
|
||||
pocket: Option<&str>,
|
||||
build_root: &str,
|
||||
cross: bool,
|
||||
ppa: Option<&[&str]>,
|
||||
inject_packages: Option<&[&str]>,
|
||||
ppa: &[String],
|
||||
inject_packages: &[String],
|
||||
ctx: Arc<Context>,
|
||||
ui: Option<Arc<DebUi>>,
|
||||
view: &dyn BuildView,
|
||||
jobs: Option<usize>,
|
||||
) -> Result<Vec<PathBuf>, Box<dyn Error>> {
|
||||
let sink: Option<Arc<dyn LineSink>> = ui.as_ref().map(|u| u.sink());
|
||||
let sink: Option<Arc<dyn LineSink>> = view.sink();
|
||||
|
||||
// Environment
|
||||
let mut env = HashMap::<String, String>::new();
|
||||
@@ -83,55 +83,53 @@ pub async fn build(
|
||||
let mut added_ppas: Vec<(&str, &str)> = Vec::new();
|
||||
|
||||
// Add PPA repositories if specified
|
||||
if let Some(ppas) = ppa {
|
||||
for ppa_str in ppas {
|
||||
// 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]);
|
||||
for ppa_str in 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 = arch;
|
||||
// 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 = 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![series.to_string()];
|
||||
|
||||
let new_source = crate::apt::sources::SourceEntry {
|
||||
enabled: true,
|
||||
kind: crate::apt::sources::SourceKind::Deb,
|
||||
components: vec!["main".to_string()],
|
||||
architectures: architectures.clone(),
|
||||
signed_by: None,
|
||||
trusted: None,
|
||||
suite: suites,
|
||||
uri: base_url,
|
||||
// No origin: saved to the pkh-owned added-sources file
|
||||
origin: None,
|
||||
};
|
||||
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
|
||||
);
|
||||
// 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());
|
||||
}
|
||||
} else {
|
||||
return Err(
|
||||
format!("Invalid PPA format: '{}'. Expected: user/ppa_name", ppa_str).into(),
|
||||
|
||||
// Create suite list with all Ubuntu series
|
||||
let suites = vec![series.to_string()];
|
||||
|
||||
let new_source = crate::apt::sources::SourceEntry {
|
||||
enabled: true,
|
||||
kind: crate::apt::sources::SourceKind::Deb,
|
||||
components: vec!["main".to_string()],
|
||||
architectures: architectures.clone(),
|
||||
signed_by: None,
|
||||
trusted: None,
|
||||
suite: suites,
|
||||
uri: base_url,
|
||||
// No origin: saved to the pkh-owned added-sources file
|
||||
origin: None,
|
||||
};
|
||||
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 {
|
||||
return Err(
|
||||
format!("Invalid PPA format: '{}'. Expected: user/ppa_name", ppa_str).into(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -193,9 +191,7 @@ pub async fn build(
|
||||
|
||||
// Update package lists
|
||||
log::debug!("Updating package lists for local build...");
|
||||
if let Some(u) = &ui {
|
||||
u.phase(Phase::UpdatingPackageLists);
|
||||
}
|
||||
enter_phase(view, Phase::UpdatingPackageLists);
|
||||
let status = cap(
|
||||
ctx.command("apt-get").envs(env.clone()).arg("update"),
|
||||
&sink,
|
||||
@@ -234,9 +230,7 @@ pub async fn build(
|
||||
cmd.arg(format!("libc6:{arch}"));
|
||||
cmd.arg(format!("libc6-dev:{arch}"));
|
||||
}
|
||||
if let Some(u) = &ui {
|
||||
u.phase(Phase::InstallingEssentials);
|
||||
}
|
||||
enter_phase(view, Phase::InstallingEssentials);
|
||||
let status = cap(&mut cmd, &sink).status()?;
|
||||
if !status.success() {
|
||||
return Err("Could not install essential packages for the build".into());
|
||||
@@ -261,18 +255,16 @@ pub async fn build(
|
||||
}
|
||||
|
||||
// Apply quilt patches if the package provides a patch series
|
||||
apply_quilt_patches(package_dir_str, &env, ctx.clone(), &ui, &sink)?;
|
||||
apply_quilt_patches(package_dir_str, &env, ctx.clone(), view, &sink)?;
|
||||
|
||||
// Install injected packages if specified
|
||||
if let Some(packages) = inject_packages {
|
||||
install_injected_packages(packages, &env, ctx.clone(), &ui, &sink)?;
|
||||
if !inject_packages.is_empty() {
|
||||
install_injected_packages(inject_packages, &env, ctx.clone(), view, &sink)?;
|
||||
}
|
||||
|
||||
// Install arch-specific build dependencies
|
||||
log::debug!("Installing arch-specific build dependencies...");
|
||||
if let Some(u) = &ui {
|
||||
u.phase(Phase::InstallingBuildDeps);
|
||||
}
|
||||
enter_phase(view, Phase::InstallingBuildDeps);
|
||||
let mut cmd = ctx.command("apt-get");
|
||||
cmd.current_dir(package_dir_str)
|
||||
.envs(env.clone())
|
||||
@@ -286,9 +278,7 @@ pub async fn build(
|
||||
|
||||
// If build-dep fails, we try to explain the failure using dose-debcheck
|
||||
if !status.success() {
|
||||
if let Some(u) = &ui {
|
||||
u.suspend();
|
||||
}
|
||||
view.suspend();
|
||||
dose3_explain_dependencies(package, version, arch, build_root, cross, ctx.clone())?;
|
||||
return Err("Could not install build-dependencies for the build".into());
|
||||
}
|
||||
@@ -320,9 +310,7 @@ pub async fn build(
|
||||
|
||||
// If build-dep fails, we try to explain the failure using dose-debcheck
|
||||
if !status.success() {
|
||||
if let Some(u) = &ui {
|
||||
u.suspend();
|
||||
}
|
||||
view.suspend();
|
||||
dose3_explain_dependencies(package, version, arch, build_root, cross, ctx.clone())?;
|
||||
return Err("Could not install build-dependencies for the build".into());
|
||||
}
|
||||
@@ -330,9 +318,7 @@ pub async fn build(
|
||||
|
||||
// Run the build step
|
||||
log::debug!("Building (debian/rules build) package...");
|
||||
if let Some(u) = &ui {
|
||||
u.phase(Phase::Building);
|
||||
}
|
||||
enter_phase(view, Phase::Building);
|
||||
let status = cap(
|
||||
ctx.command("debian/rules")
|
||||
.current_dir(package_dir_str)
|
||||
@@ -346,9 +332,7 @@ pub async fn build(
|
||||
}
|
||||
|
||||
// Run the 'binary' step to produce deb
|
||||
if let Some(u) = &ui {
|
||||
u.phase(Phase::ProducingBinaries);
|
||||
}
|
||||
enter_phase(view, Phase::ProducingBinaries);
|
||||
let status = cap(
|
||||
ctx.command("fakeroot")
|
||||
.current_dir(package_dir_str)
|
||||
@@ -495,7 +479,7 @@ fn apply_quilt_patches(
|
||||
package_dir: &str,
|
||||
env: &HashMap<String, String>,
|
||||
ctx: Arc<Context>,
|
||||
ui: &Option<Arc<DebUi>>,
|
||||
view: &dyn BuildView,
|
||||
sink: &Option<Arc<dyn LineSink>>,
|
||||
) -> Result<(), Box<dyn Error>> {
|
||||
let series_path = Path::new(package_dir).join("debian/patches/series");
|
||||
@@ -555,12 +539,10 @@ fn apply_quilt_patches(
|
||||
}
|
||||
|
||||
// Apply all patches listed in the series
|
||||
if let Some(u) = ui {
|
||||
u.phase_with(
|
||||
Phase::ApplyingPatches,
|
||||
Box::new(QuiltClassifier::new(total_patches)),
|
||||
);
|
||||
}
|
||||
view.phase(
|
||||
Phase::ApplyingPatches.label(),
|
||||
Box::new(QuiltClassifier::new(total_patches)),
|
||||
);
|
||||
let mut patch_env = env.clone();
|
||||
patch_env.insert("QUILT_PATCHES".to_string(), "debian/patches".to_string());
|
||||
let status = cap(
|
||||
@@ -631,17 +613,15 @@ fn pin_pocket(pocket_suite: &str, ctx: &Arc<Context>) -> Result<(), Box<dyn Erro
|
||||
}
|
||||
|
||||
fn install_injected_packages(
|
||||
packages: &[&str],
|
||||
packages: &[String],
|
||||
env: &HashMap<String, String>,
|
||||
ctx: Arc<Context>,
|
||||
ui: &Option<Arc<DebUi>>,
|
||||
view: &dyn BuildView,
|
||||
sink: &Option<Arc<dyn LineSink>>,
|
||||
) -> Result<(), Box<dyn Error>> {
|
||||
log::info!("Installing injected packages: {:?}", packages);
|
||||
|
||||
if let Some(u) = ui {
|
||||
u.phase(Phase::InjectingPackages);
|
||||
}
|
||||
enter_phase(view, Phase::InjectingPackages);
|
||||
|
||||
// Separate .deb files from package names
|
||||
let mut deb_files: Vec<String> = Vec::new();
|
||||
@@ -661,7 +641,7 @@ fn install_injected_packages(
|
||||
);
|
||||
deb_files.push(chroot_path.to_string_lossy().to_string());
|
||||
} else {
|
||||
package_names.push(pkg);
|
||||
package_names.push(pkg.as_str());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -855,6 +835,13 @@ mod tests {
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
apply_quilt_patches(tree.to_str().unwrap(), &HashMap::new(), ctx, &None, &None).unwrap();
|
||||
apply_quilt_patches(
|
||||
tree.to_str().unwrap(),
|
||||
&HashMap::new(),
|
||||
ctx,
|
||||
&crate::report::Quiet,
|
||||
&None,
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user