build: fail binary-only metadata when the previous version is unparseable
The binNMU path swallowed parse errors with a let-chain: a changelog that could not yield the previous version silently produced a .changes with plain 'Source: pkg', no Binary-Only-Changes and no redistributed previous .dsc. Propagate the parse error like the source-build path does (a single-entry changelog stays tolerated), and reuse the changelog already read instead of reading the file a second time.
This commit is contained in:
+75
-5
@@ -130,12 +130,20 @@ pub fn generate_binary_metadata(
|
|||||||
let mut source_display = entry.source.clone();
|
let mut source_display = entry.source.clone();
|
||||||
let mut binary_only_changes = None;
|
let mut binary_only_changes = None;
|
||||||
|
|
||||||
if entry.binary_only
|
if entry.binary_only {
|
||||||
&& let Ok(prev_entry) = crate::debian::changelog::parse_previous_version_from_str(
|
// A binary-only upload must reference the previous source version;
|
||||||
&ctx.read_file(&package_dir.join("debian/changelog"))?,
|
// a changelog that cannot yield it is a hard error, like in the
|
||||||
|
// source-build path. Reuse the changelog read above instead of
|
||||||
|
// reading the file a second time.
|
||||||
|
let changelog_path = package_dir.join("debian/changelog");
|
||||||
|
let prev = crate::debian::changelog::parse_previous_version_from_str(&changelog_content)
|
||||||
|
.map_err(|e| {
|
||||||
|
format!(
|
||||||
|
"cannot parse the previous version from '{}': {e}",
|
||||||
|
changelog_path.display()
|
||||||
)
|
)
|
||||||
&& let Some(prev) = prev_entry
|
})?;
|
||||||
{
|
if let Some(prev) = prev {
|
||||||
source_display = format!("{} ({})", entry.source, prev);
|
source_display = format!("{} ({})", entry.source, prev);
|
||||||
binary_only_changes = Some(format!(
|
binary_only_changes = Some(format!(
|
||||||
"{}\n\n -- {} <{}> {}",
|
"{}\n\n -- {} <{}> {}",
|
||||||
@@ -148,6 +156,7 @@ pub fn generate_binary_metadata(
|
|||||||
include_dsc_artifacts(ctx, upload_dir, &dsc_name, &mut checksums)?;
|
include_dsc_artifacts(ctx, upload_dir, &dsc_name, &mut checksums)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------
|
// ------------------------------------------------------------------
|
||||||
// Binary package names and descriptions
|
// Binary package names and descriptions
|
||||||
@@ -580,4 +589,65 @@ Files:
|
|||||||
assert_eq!(tar_entry.sha1, "aaa111");
|
assert_eq!(tar_entry.sha1, "aaa111");
|
||||||
assert_eq!(tar_entry.sha256, "bbb222");
|
assert_eq!(tar_entry.sha256, "bbb222");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A binary-only (binNMU) build whose changelog cannot yield the
|
||||||
|
/// previous version (malformed second header, unbalanced parenthesis)
|
||||||
|
/// must fail the metadata generation with a diagnostic naming the
|
||||||
|
/// changelog, instead of silently emitting a plain `Source:` `.changes`
|
||||||
|
/// with no `Binary-Only-Changes` and no redistributed previous `.dsc`.
|
||||||
|
#[test]
|
||||||
|
fn binary_only_prev_version_parse_failure_errors_instead_of_wrong_metadata() {
|
||||||
|
let changelog = "\
|
||||||
|
hello (1.0-1+b1) unstable; urgency=medium, binary-only=yes
|
||||||
|
|
||||||
|
* Binary-only rebuild.
|
||||||
|
|
||||||
|
-- A B <a@b.c> Mon, 01 Jan 2024 00:00:00 +0000
|
||||||
|
|
||||||
|
hello (1.0-1 unstable; urgency=medium
|
||||||
|
|
||||||
|
* Previous entry with an unbalanced parenthesis.
|
||||||
|
|
||||||
|
-- A B <a@b.c> Sun, 31 Dec 2023 00:00:00 +0000
|
||||||
|
";
|
||||||
|
let control = "\
|
||||||
|
Source: hello
|
||||||
|
Section: devel
|
||||||
|
Priority: optional
|
||||||
|
Maintainer: A B <a@b.c>
|
||||||
|
|
||||||
|
Package: hello
|
||||||
|
Architecture: all
|
||||||
|
Description: test package
|
||||||
|
";
|
||||||
|
let base = tempfile::tempdir().expect("tempdir");
|
||||||
|
let tree = base.path().join("hello-1.0");
|
||||||
|
std::fs::create_dir_all(tree.join("debian")).expect("mkdir tree");
|
||||||
|
std::fs::write(tree.join("debian/changelog"), changelog).expect("write changelog");
|
||||||
|
std::fs::write(tree.join("debian/control"), control).expect("write control");
|
||||||
|
std::fs::write(
|
||||||
|
tree.join("debian/files"),
|
||||||
|
"hello_1.0-1+b1_all.deb devel optional\n",
|
||||||
|
)
|
||||||
|
.expect("write files");
|
||||||
|
std::fs::write(base.path().join("hello_1.0-1+b1_all.deb"), "deb payload")
|
||||||
|
.expect("write deb");
|
||||||
|
|
||||||
|
let ctx = Arc::new(
|
||||||
|
crate::context::Context::new(crate::context::ContextConfig::Local).expect("context"),
|
||||||
|
);
|
||||||
|
let opts = BinaryMetadataOptions {
|
||||||
|
profiles: Vec::new(),
|
||||||
|
vendor: "debian".to_string(),
|
||||||
|
exported_env: BTreeMap::new(),
|
||||||
|
build_arch: "amd64".to_string(),
|
||||||
|
host_arch: "amd64".to_string(),
|
||||||
|
};
|
||||||
|
let err = generate_binary_metadata(&ctx, &tree, base.path(), &opts)
|
||||||
|
.expect_err("binary-only build with an unparseable changelog must fail");
|
||||||
|
let err = err.to_string();
|
||||||
|
assert!(err.contains("debian/changelog"), "{err}");
|
||||||
|
assert!(err.contains("previous version"), "{err}");
|
||||||
|
assert!(err.contains("unbalanced parenthesis"), "{err}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user