build: only redistribute the orig tarball on new upstream (-si)

dpkg-genchanges includes the upstream tarballs in the .changes only when
the upload brings a new upstream: no previous changelog entry, a changed
upstream version or a renamed source. On a plain revision bump the
tarball already sits in the archive, and dpkg strips it (and its .asc)
from the distribution set.

pkh's native source pipeline listed every .dsc-referenced tarball
unconditionally, making every upload re-ship the orig. Implement the
dpkg source styles as --orig auto|always|never (auto being the -si
default; always/never are -sa/-sd), stripping the tarballs out of the
changes, buildinfo-free checksum set and artifact list like dpkg, with
the explicit 'never' ignored for native packages. Comparison uses the
epoch-less upstream version, exactly like dpkg's version().

Differential tests against real dpkg cover revision bumps, new upstream
versions and both forced styles.
This commit is contained in:
2026-09-17 23:45:15 +02:00
parent c18f1fe9c2
commit 4ab41e691a
4 changed files with 308 additions and 36 deletions
+18 -2
View File
@@ -184,7 +184,10 @@ fn main() {
.subcommand(
Command::new("build")
.about("Build the source package (into a .dsc)")
.arg(arg!(--verbose "Show raw tool output instead of the live build view").required(false)),
.arg(arg!(--verbose "Show raw tool output instead of the live build view").required(false))
.arg(arg!(--orig <when> "Original source tarball in the upload [auto, always, never] (default: auto)").required(false)
.long_help("Whether the upload distributes the original source tarball(s), like dpkg-genchanges' -sa/-si/-sd source styles.\nauto: include them only when the upstream version changed since the previous changelog entry (the default);\nalways: force inclusion, even for a revision bump of the same upstream version;\nnever: never include them, even for a new upstream version.\nAn explicit value is ignored with a warning for native packages (they have no separate orig tarball).")
.value_parser(["auto", "always", "never"])),
)
.subcommand(
Command::new("put")
@@ -495,7 +498,20 @@ fn main() {
Some(std::sync::Arc::new(pkh::ui::deb::DebUi::new(&multi)))
};
if let Err(e) = pkh::build::build_source_package(Some(&cwd), ui) {
let orig_source = match sub_matches.get_one::<String>("orig").map(String::as_str) {
Some("always") => pkh::build::OrigSourceMode::Always,
Some("never") => pkh::build::OrigSourceMode::Never,
_ => pkh::build::OrigSourceMode::Auto,
};
if let Err(e) = pkh::build::build_source_package(
Some(&cwd),
pkh::build::SourceBuildOptions {
orig_source,
..Default::default()
},
ui,
) {
error!("{}", e);
// Unmet build dependencies/conflicts exit with status 3,
// like dpkg-buildpackage does.