From dd2438a72cd582451b481198bf3652ce8786889a Mon Sep 17 00:00:00 2001 From: Valentin Haudiquet Date: Sat, 19 Sep 2026 20:58:44 +0200 Subject: [PATCH] chlog: number regular uploads after the target series' vendor A flagless entry (no --backport/--nmu/--rebuild) targeting an Ubuntu series was numbered the Debian way: 1.0-1 became 1.0-2 with distribution noble, and getting the conventional 1.0-1ubuntu1 required hand-editing the version. The bump now derives from the vendor of the target series (distro-info): Ubuntu series get the ubuntu suffix convention (1.0-1 becomes 1.0-1ubuntu1, and re-bumping an already-Ubuntu changelog increments the counter instead of the revision), Debian series keep the plain revision bump, and series that cannot be resolved to a vendor (UNRELEASED, unknown) fall back to it too. There is no reverse sync, so the Ubuntu-to-Debian direction needs no special casing. Runs with an explicit --series now consult distro-info once, where they previously queried it not at all; the interactive flow already did for the series selector. EntryKind::Ubuntu remains the library-level way to force the numbering regardless of the series. --- src/changelog.rs | 75 ++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 70 insertions(+), 5 deletions(-) diff --git a/src/changelog.rs b/src/changelog.rs index aa36da3..4afd58d 100644 --- a/src/changelog.rs +++ b/src/changelog.rs @@ -27,8 +27,12 @@ pub struct GeneratedEntry { /// explicit version is given. #[derive(Debug, Clone, Copy, Default, PartialEq, Eq)] pub enum EntryKind { - /// A regular upload: the Debian revision is bumped (or the trailing - /// upstream number for native packages) + /// A regular upload: the version numbering follows the vendor of the + /// target series — the Debian convention (`1.0-1` becomes `1.0-2`) for + /// Debian series, the Ubuntu one for Ubuntu series (`1.0-1` becomes + /// `1.0-1ubuntu1`, an already-Ubuntu `1.0-1ubuntu1` becomes + /// `1.0-1ubuntu2`). Unresolvable series (UNRELEASED, unknown) number + /// the Debian way. #[default] Normal, /// A non-maintainer upload: `1.0-1` becomes `1.0-1.1` (native `1.0` @@ -36,8 +40,9 @@ pub enum EntryKind { Nmu, /// A no-change rebuild: `1.0-1` becomes `1.0-1build1` Rebuild, - /// An Ubuntu upload: `1.0-1` becomes `1.0-1ubuntu1`. Library-only for - /// now: the pkh CLI has no flag selecting it. + /// An Ubuntu upload regardless of the target series: `1.0-1` becomes + /// `1.0-1ubuntu1`. Library-only: the CLI has no flag selecting it, + /// and targeting an Ubuntu series already picks this numbering. Ubuntu, /// A backport: `1.0-1` becomes `1.0-1~bpo12+1`, where 12 is the Debian /// release number of the target series (derived from it: the series @@ -84,7 +89,10 @@ pub async fn generate_entry( version.to_string() } else { match kind { - EntryKind::Normal => compute_new_version(&old_version, Bump::Normal)?, + EntryKind::Normal => { + let bump = normal_bump_for_series(&series).await; + compute_new_version(&old_version, bump)? + } EntryKind::Nmu => compute_new_version(&old_version, Bump::Nmu)?, EntryKind::Rebuild => compute_new_version(&old_version, Bump::Rebuild)?, EntryKind::Ubuntu => compute_new_version(&old_version, Bump::Ubuntu)?, @@ -160,6 +168,18 @@ fn compute_new_version( } } +/// The version bump a regular ([`EntryKind::Normal`]) upload gets, derived +/// from the vendor of the target series: Ubuntu series number their uploads +/// the Ubuntu way (`1.0-1` becomes `1.0-1ubuntu1`), everything else — +/// Debian series, but also UNRELEASED and series no distro-info data knows — +/// numbers the Debian way (`1.0-1` becomes `1.0-2`). +async fn normal_bump_for_series(series: &str) -> Bump { + match crate::distro_info::get_dist_from_series(series).await { + Ok(dist) if dist == "ubuntu" => Bump::Ubuntu, + _ => Bump::Normal, + } +} + /// The Debian release number (e.g. `"12"` for bookworm) that backport /// versions are numbered after (`~bpo12+1`), derived from the target series; /// a backport suite name (`bookworm-backports`) is accepted too. Errors when @@ -828,6 +848,51 @@ mod tests { assert!(content.starts_with("mypackage (1.0-1) unstable")); } + /// A regular upload is numbered after the vendor of its target series: + /// a Debian-style version uploaded to an Ubuntu series gains the + /// ubuntu1 suffix, and re-bumping the now-Ubuntu changelog increments + /// that counter instead of the revision. Relies on the host distro-info + /// data listing noble (see the distro_info tests). The git repo + /// provides the maintainer identity: DEBFULLNAME/DEBEMAIL are + /// process-global and other tests mutate them in parallel. + #[tokio::test] + async fn test_generate_entry_ubuntu_series_numbering() { + let temp_dir = TempDir::new().unwrap(); + let repo_dir = temp_dir.path(); + setup_repo(repo_dir); + let changelog_path = repo_dir.join("debian/changelog"); + std::fs::create_dir_all(repo_dir.join("debian")).unwrap(); + std::fs::write( + &changelog_path, + "mypackage (1.0-1) unstable; urgency=medium\n\n * Initial release\n\n -- Maintainer Wed, 01 Jan 2020 00:00:00 +0000\n", + ) + .unwrap(); + + let entry = generate_entry( + "debian/changelog", + Some(repo_dir), + None, + Some("noble"), + EntryKind::Normal, + ) + .await + .unwrap(); + assert_eq!(entry.new_version, "1.0-1ubuntu1"); + assert_eq!(entry.series, "noble"); + + // Re-bumping the now-Ubuntu changelog increments the counter + let entry = generate_entry( + "debian/changelog", + Some(repo_dir), + None, + Some("noble"), + EntryKind::Normal, + ) + .await + .unwrap(); + assert_eq!(entry.new_version, "1.0-1ubuntu2"); + } + #[test] fn test_get_maintainer_info() { // Test with env vars