This commit is contained in:
2026-08-24 11:58:19 +02:00
parent 42fcfc2dfa
commit 429429e414
10 changed files with 477 additions and 189 deletions
+33 -51
View File
@@ -15,7 +15,7 @@ use std::sync::Arc;
use crate::context::Context;
use crate::debian::{
parse_changelog_entry_from_str, ChecksumEntry, ControlInfo, FileChecksums, FilesList,
ChecksumEntry, ControlInfo, FileChecksums, FilesList, parse_changelog_entry_from_str,
};
/// Digests of one artifact.
@@ -80,16 +80,12 @@ pub fn generate_binary_metadata(
// ------------------------------------------------------------------
let artifact_names: Vec<String> = files_list
.iter()
.filter(|e| {
matches!(e.package_type.as_deref(), Some("deb") | Some("udeb"))
})
.filter(|e| matches!(e.package_type.as_deref(), Some("deb") | Some("udeb")))
.map(|e| e.filename.clone())
.collect();
if artifact_names.is_empty() {
return Err(
"binary build with no binary artifacts found; cannot distribute".into(),
);
return Err("binary build with no binary artifacts found; cannot distribute".into());
}
let mut hashes = hashes_in_context(ctx, upload_dir, &artifact_names)?;
@@ -98,9 +94,9 @@ pub fn generate_binary_metadata(
let mut arch_values: Vec<String> = Vec::new();
let mut arch_seen = std::collections::HashSet::new();
for name in &artifact_names {
let entry_hashes = hashes.remove(name).ok_or_else(|| {
format!("artifact '{name}' listed in debian/files but not found")
})?;
let entry_hashes = hashes
.remove(name)
.ok_or_else(|| format!("artifact '{name}' listed in debian/files but not found"))?;
checksums.insert_entry(
name,
ChecksumEntry {
@@ -112,9 +108,10 @@ pub fn generate_binary_metadata(
);
// Architecture accumulation in encounter order (dpkg-genchanges).
if let Some(file_entry) = files_list.get(name)
&& let Some(arch) = file_entry.arch.as_ref().or_else(|| {
file_entry.attrs.get("architecture")
})
&& let Some(arch) = file_entry
.arch
.as_ref()
.or_else(|| file_entry.attrs.get("architecture"))
&& arch_seen.insert(arch.clone())
{
arch_values.push(arch.clone());
@@ -129,19 +126,15 @@ pub fn generate_binary_metadata(
let mut binary_only_changes = None;
if entry.binary_only
&& let Ok(prev_entry) =
crate::debian::changelog::parse_previous_version_from_str(&ctx.read_file(
&package_dir.join("debian/changelog"),
)?)
&& let Ok(prev_entry) = crate::debian::changelog::parse_previous_version_from_str(
&ctx.read_file(&package_dir.join("debian/changelog"))?,
)
&& let Some(prev) = prev_entry
{
source_display = format!("{} ({})", entry.source, prev);
binary_only_changes = Some(format!(
"{}\n\n -- {} <{}> {}",
entry.changes_field,
entry.maintainer_name,
entry.maintainer_email,
entry.date_raw
entry.changes_field, entry.maintainer_name, entry.maintainer_email, entry.date_raw
));
let prev_version = crate::debian::DebianVersion::parse(&prev)?;
let dsc_name = format!("{}_{}.dsc", entry.source, prev_version.no_epoch());
@@ -210,10 +203,7 @@ pub fn generate_binary_metadata(
control.source.get("Build-Depends-Indep").unwrap_or(""),
];
let installed_build_depends =
crate::build::buildinfo::installed_build_depends_from_content(
&status_content,
&bd_fields,
)?;
crate::build::buildinfo::installed_build_depends_from_content(&status_content, &bd_fields)?;
// ------------------------------------------------------------------
// .buildinfo generation, then registration in debian/files
@@ -226,14 +216,9 @@ pub fn generate_binary_metadata(
let mut buildinfo_arch_values = arch_values.clone();
buildinfo_arch_values.sort();
let buildinfo_name = format!(
"{}_{}_{}.buildinfo",
entry.source,
sversion,
opts.host_arch
);
let buildinfo_doc = crate::build::buildinfo::render_buildinfo(
&crate::build::buildinfo::BuildInfoInput {
let buildinfo_name = format!("{}_{}_{}.buildinfo", entry.source, sversion, opts.host_arch);
let buildinfo_doc =
crate::build::buildinfo::render_buildinfo(&crate::build::buildinfo::BuildInfoInput {
source: source_display.clone(),
binaries: binaries.clone(),
architecture: buildinfo_arch_values.join(" "),
@@ -245,10 +230,12 @@ pub fn generate_binary_metadata(
checksums: checksums.clone(),
installed_build_depends,
environment,
},
);
});
let buildinfo_path = upload_dir.join(&buildinfo_name);
ctx.write_file(&buildinfo_path, &crate::debian::control::write_paragraph(&buildinfo_doc))?;
ctx.write_file(
&buildinfo_path,
&crate::debian::control::write_paragraph(&buildinfo_doc),
)?;
// Register the .buildinfo in debian/files, like dpkg-genbuildinfo does,
// so the .changes distributes it.
@@ -257,17 +244,11 @@ pub fn generate_binary_metadata(
control.section(),
control.priority(),
));
ctx.write_file(
&package_dir.join("debian/files"),
&files_list.render(),
)?;
ctx.write_file(&package_dir.join("debian/files"), &files_list.render())?;
// Hash the freshly written .buildinfo inside the context.
let buildinfo_hashes = hashes_in_context(
ctx,
upload_dir,
std::slice::from_ref(&buildinfo_name),
)?;
let buildinfo_hashes =
hashes_in_context(ctx, upload_dir, std::slice::from_ref(&buildinfo_name))?;
if let Some(h) = buildinfo_hashes.get(&buildinfo_name) {
checksums.insert_entry(
&buildinfo_name,
@@ -303,7 +284,10 @@ pub fn generate_binary_metadata(
files_list,
});
let changes_path = upload_dir.join(&changes_name);
ctx.write_file(&changes_path, &crate::debian::control::write_paragraph(&changes_doc))?;
ctx.write_file(
&changes_path,
&crate::debian::control::write_paragraph(&changes_doc),
)?;
Ok((buildinfo_path, changes_path))
}
@@ -321,10 +305,7 @@ fn pipeline_environment(opts: &BinaryMetadataOptions) -> BTreeMap<String, String
format!("parallel={}", opts.parallel),
);
if !opts.profiles.is_empty() {
env.insert(
"DEB_BUILD_PROFILES".to_string(),
opts.profiles.join(","),
);
env.insert("DEB_BUILD_PROFILES".to_string(), opts.profiles.join(","));
}
env
}
@@ -453,7 +434,8 @@ fn include_dsc_artifacts(
// The .dsc itself is hashed fresh (it may be signed/rewritten); the
// tarballs reuse the .dsc-recorded digests, like dpkg-genchanges does.
let dsc_hashes = hashes_in_context(ctx, upload_dir, std::slice::from_ref(&dsc_name.to_string()))?;
let dsc_hashes =
hashes_in_context(ctx, upload_dir, std::slice::from_ref(&dsc_name.to_string()))?;
if let Some(h) = dsc_hashes.get(dsc_name) {
checksums.insert_entry(
dsc_name,