Kaynağa Gözat

Add support for binary-only key-value option in changelogs

This allows to mark changelog entries as being for a binary-only upload,
which implies there cannot be any source produced, and the binary
version is going to be different to the source version.

As such the version substvars will get different values, w/o needing to
hardcode a specific syntax. Although we fallback to the old syntax just
in case, for example to handle possible multiple consecutive binary-only
entries w/o needing to complicate the code too much.

Closes: #440094, #672723
Guillem Jover 14 yıl önce
ebeveyn
işleme
094d3a7e61

+ 3 - 0
debian/changelog

@@ -18,6 +18,9 @@ dpkg (1.16.5) UNRELEASED; urgency=low
   [ Guillem Jover ]
   * Add a dpkg-buildflags --status action to describe the flag settings.
     Thanks to Bernhard R. Link <brlink@debian.org>. Closes: #664058
+  * Add support for “binary-only” key-value option in changelogs, to allow
+    marking changelog entries as part of a binary only upload, having a
+    different version from the source package. Closes: #440094, #672723
 
   [ Updated dpkg translations ]
   * Swedish (Peter Krefting).

+ 3 - 0
scripts/Dpkg/Changelog/Entry/Debian.pm

@@ -131,6 +131,9 @@ sub check_header {
 	    if ($k eq 'Urgency') {
 		push @errors, sprintf(_g("badly formatted urgency value: %s"), $v)
 		    unless ($v =~ m/^([-0-9a-z]+)((\s+.*)?)$/i);
+	    } elsif ($k eq 'Binary-Only') {
+		push @errors, sprintf(_g("bad binary-only value: %s"), $v)
+		    unless ($v eq "yes");
 	    } elsif ($k =~ m/^X[BCS]+-/i) {
 	    } else {
 		push @errors, sprintf(_g("unknown key-value %s"), $k);

+ 8 - 4
scripts/Dpkg/Control/Fields.pm

@@ -50,6 +50,9 @@ our %FIELDS = (
     'Binary' => {
         allowed => CTRL_PKG_SRC | CTRL_FILE_CHANGES,
     },
+    'Binary-Only' => {
+        allowed => ALL_CHANGES,
+    },
     'Breaks' => {
         allowed => ALL_PKG,
         dependency => 'union',
@@ -305,13 +308,14 @@ our %FIELD_ORDER = (
         @checksum_fields, qw(Files)
     ],
     CTRL_FILE_CHANGES() => [
-        qw(Format Date Source Binary Architecture Version Distribution
-        Urgency Maintainer Changed-By Description Closes Changes),
+        qw(Format Date Source Binary Binary-Only Architecture Version
+        Distribution Urgency Maintainer Changed-By Description
+        Closes Changes),
         @checksum_fields, qw(Files)
     ],
     CTRL_CHANGELOG() => [
-        qw(Source Version Distribution Urgency Maintainer Date Closes
-        Changes)
+        qw(Source Binary-Only Version Distribution Urgency Maintainer
+        Date Closes Changes)
     ],
     CTRL_FILE_STATUS() => [ # Same as fieldinfos in lib/dpkg/parse.c
         qw(Package Essential Status Priority Section Installed-Size Origin

+ 15 - 9
scripts/Dpkg/Substvars.pm

@@ -1,3 +1,4 @@
+# Copyright © 2006-2009,2012 Guillem Jover <guillem@debian.org>
 # Copyright © 2007-2010 Raphaël Hertzog <hertzog@debian.org>
 #
 # This program is free software; you can redistribute it and/or modify
@@ -18,7 +19,7 @@ package Dpkg::Substvars;
 use strict;
 use warnings;
 
-our $VERSION = "1.01";
+our $VERSION = "1.02";
 
 use Dpkg qw($version);
 use Dpkg::Arch qw(get_host_arch);
@@ -179,26 +180,31 @@ sub parse {
     }
 }
 
-=item $s->set_version_substvars($version)
+=item $s->set_version_substvars($sourceversion, $binaryversion)
 
 Defines ${binary:Version}, ${source:Version} and
-${source:Upstream-Version} based on the given version string.
+${source:Upstream-Version} based on the given version strings.
 
 These will never be warned about when unused.
 
 =cut
 
 sub set_version_substvars {
-    my ($self, $version) = @_;
+    my ($self, $sourceversion, $binaryversion) = @_;
 
-    $self->{'vars'}{'binary:Version'} = $version;
-    $self->{'vars'}{'source:Version'} = $version;
-    $self->{'vars'}{'source:Version'} =~ s/\+b[0-9]+$//;
-    $self->{'vars'}{'source:Upstream-Version'} = $version;
+    # Handle old function signature taking only one argument.
+    $binaryversion ||= $sourceversion;
+
+    # Fallback to manually compute the binary version if they are the same.
+    $sourceversion =~ s/\+b[0-9]+$// if $sourceversion eq $binaryversion;
+
+    $self->{'vars'}{'binary:Version'} = $binaryversion;
+    $self->{'vars'}{'source:Version'} = $sourceversion;
+    $self->{'vars'}{'source:Upstream-Version'} = $sourceversion;
     $self->{'vars'}{'source:Upstream-Version'} =~ s/-[^-]*$//;
 
     # XXX: Source-Version is now deprecated, remove in the future.
-    $self->{'vars'}{'Source-Version'} = $version;
+    $self->{'vars'}{'Source-Version'} = $binaryversion;
 
     $self->mark_as_used($_) foreach qw/binary:Version source:Version source:Upstream-Version Source-Version/;
 }

+ 6 - 1
scripts/dpkg-genchanges.pl

@@ -207,7 +207,12 @@ my $prev_changelog = changelog_parse(%options);
 # Other initializations
 my $control = Dpkg::Control::Info->new($controlfile);
 my $fields = Dpkg::Control->new(type => CTRL_FILE_CHANGES);
-$substvars->set_version_substvars($changelog->{"Version"});
+
+my $sourceversion = $changelog->{"Binary-Only"} ?
+                    $prev_changelog->{"Version"} : $changelog->{"Version"};
+my $binaryversion = $changelog->{"Version"};
+
+$substvars->set_version_substvars($sourceversion, $binaryversion);
 $substvars->set_arch_substvars();
 $substvars->load("debian/substvars") if -e "debian/substvars" and not $substvars_loaded;
 

+ 21 - 8
scripts/dpkg-gencontrol.pl

@@ -48,6 +48,7 @@ my $fileslistfile = 'debian/files';
 my $packagebuilddir = 'debian/tmp';
 
 my $sourceversion;
+my $binaryversion;
 my $forceversion;
 my $forcefilename;
 my $stdout;
@@ -139,10 +140,24 @@ umask 0022; # ensure sane default permissions for created files
 my %options = (file => $changelogfile);
 $options{"changelogformat"} = $changelogformat if $changelogformat;
 my $changelog = changelog_parse(%options);
-$substvars->set_version_substvars($changelog->{"Version"});
+if ($changelog->{"Binary-Only"}) {
+    $options{"count"} = 1;
+    $options{"offset"} = 1;
+    my $prev_changelog = changelog_parse(%options);
+    $sourceversion = $prev_changelog->{"Version"};
+} else {
+    $sourceversion = $changelog->{"Version"};
+}
+
+if (defined $forceversion) {
+    $binaryversion = $forceversion;
+} else {
+    $binaryversion = $changelog->{"Version"};
+}
+
+$substvars->set_version_substvars($sourceversion, $binaryversion);
 $substvars->set_arch_substvars();
 $substvars->load("debian/substvars") if -e "debian/substvars" and not $substvars_loaded;
-$substvars->set("binary:Version", $forceversion) if defined $forceversion;
 my $control = Dpkg::Control::Info->new($controlfile);
 my $fields = Dpkg::Control->new(type => CTRL_PKG_DEB);
 
@@ -209,8 +224,7 @@ foreach $_ (keys %{$changelog}) {
     if (m/^Source$/) {
 	set_source_package($v);
     } elsif (m/^Version$/) {
-	$sourceversion = $v;
-	$fields->{$_} = $v unless defined($forceversion);
+        # Already handled previously.
     } elsif (m/^Maintainer$/) {
         # That field must not be copied from changelog even if it's
         # allowed in the binary package control information
@@ -219,7 +233,7 @@ foreach $_ (keys %{$changelog}) {
     }
 }
 
-$fields->{'Version'} = $forceversion if defined($forceversion);
+$fields->{'Version'} = $binaryversion;
 
 # Process dependency fields in a second pass, now that substvars have been
 # initialized.
@@ -294,11 +308,10 @@ if ($pkg_type eq 'udeb') {
     }
 }
 
-my $verdiff = $fields->{'Version'} ne $substvars->get('source:Version') ||
-              $fields->{'Version'} ne $sourceversion;
+my $verdiff = $binaryversion ne $sourceversion;
 if ($oppackage ne $sourcepackage || $verdiff) {
     $fields->{'Source'} = $sourcepackage;
-    $fields->{'Source'} .= " (" . $substvars->get('source:Version') . ")" if $verdiff;
+    $fields->{'Source'} .= " (" . $sourceversion . ")" if $verdiff;
 }
 
 if (!defined($substvars->get('Installed-Size'))) {

+ 3 - 0
scripts/dpkg-source.pl

@@ -323,6 +323,9 @@ if ($options{'opmode'} =~ /^(-b|--print-format|--(before|after)-build|--commit)$
 	    my ($ok, $error) = version_check($v);
             error($error) unless $ok;
 	    $fields->{$_} = $v;
+	} elsif (m/^Binary-Only$/) {
+	    error(_g("building source for a binary-only release"))
+	        if $v eq "yes" and $options{'opmode'} eq "-b";
 	} elsif (m/^Maintainer$/i) {
             # Do not replace the field coming from the source entry
 	} else {

+ 5 - 1
scripts/t/750_Dpkg_Substvars.t

@@ -13,7 +13,7 @@
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-use Test::More tests => 26;
+use Test::More tests => 29;
 
 use strict;
 use warnings;
@@ -56,6 +56,10 @@ $s->set_arch_substvars();
 is($s->get('Arch'), get_host_arch(),'arch');
 
 is($s->get($_), undef, 'no ' . $_) for qw/binary:Version source:Version source:Upstream-Version/;
+$s->set_version_substvars("1:2.3.4~5-6.7.8~nmu9", "1:2.3.4~5-6.7.8~nmu9+bin0");
+is($s->get("binary:Version"), "1:2.3.4~5-6.7.8~nmu9+bin0", "binary:Version");
+is($s->get("source:Version"), "1:2.3.4~5-6.7.8~nmu9", "source:Version");
+is($s->get("source:Upstream-Version"), "1:2.3.4~5", "source:Upstream-Version");
 $s->set_version_substvars("1:2.3.4~5-6.7.8~nmu9+b0");
 is($s->get("binary:Version"), "1:2.3.4~5-6.7.8~nmu9+b0", "binary:Version");
 is($s->get("source:Version"), "1:2.3.4~5-6.7.8~nmu9", "source:Version");