chiark / gitweb /
Detect and bomb out on vendor-specific `3.0 (quilt)' patch series.
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Mon, 29 Jun 2015 01:46:24 +0000 (02:46 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Mon, 29 Jun 2015 01:46:24 +0000 (02:46 +0100)
debian/changelog
dgit
tests/tests/distropatches-reject [new file with mode: 0755]

index 901925b..a6353e1 100644 (file)
@@ -73,6 +73,8 @@ dgit (0.23~) unstable; urgency=low
   * Quilt linearisation with .pc removal passes -f to git-rm.  (Otherwise
     we may find that .pc/applied_patches prevents the commit.)
 
+  * Detect and bomb out on vendor-specific `3.0 (quilt)' patch series.
+
  --
 
 dgit (0.22.1) unstable; urgency=high
diff --git a/dgit b/dgit
index 8d3addb..19c0657 100755 (executable)
--- a/dgit
+++ b/dgit
@@ -1145,6 +1145,69 @@ sub clogp_authline ($) {
     return $authline;
 }
 
+sub vendor_patches_distro ($$) {
+    my ($checkdistro, $what) = @_;
+    return unless defined $checkdistro;
+
+    my $series = "debian/patches/\L$checkdistro\E.series";
+    printdebug "checking for vendor-specific $series ($what)\n";
+
+    if (!open SERIES, "<", $series) {
+       die "$series $!" unless $!==ENOENT;
+       return;
+    }
+    while (<SERIES>) {
+       next unless m/\S/;
+       next if m/^\s+\#/;
+
+       print STDERR <<END;
+
+Unfortunately, this source package uses a feature of dpkg-source where
+the same source package unpacks to different source code on different
+distros.  dgit cannot safely operate on such packages on affected
+distros, because the meaning of source packages is not stable.
+
+Please ask the distro/maintainer to remove the distro-specific series
+files and use a different technique (if necessary, uploading actually
+different packages, if different distros are supposed to have
+different code).
+
+END
+       fail "Found active distro-specific series file for".
+           " $checkdistro ($what): $series, cannot continue";
+    }
+    die "$series $!" if SERIES->error;
+    close SERIES;
+}
+
+sub check_for_vendor_patches () {
+    # This dpkg-source feature doesn't seem to be documented anywhere!
+    # But it can be found in the changelog (reformatted):
+
+    #   commit  4fa01b70df1dc4458daee306cfa1f987b69da58c
+    #   Author: Raphael Hertzog <hertzog@debian.org>
+    #   Date: Sun  Oct  3  09:36:48  2010 +0200
+
+    #   dpkg-source: correctly create .pc/.quilt_series with alternate
+    #   series files
+    #   
+    #   If you have debian/patches/ubuntu.series and you were
+    #   unpacking the source package on ubuntu, quilt was still
+    #   directed to debian/patches/series instead of
+    #   debian/patches/ubuntu.series.
+    #   
+    #   debian/changelog                        |    3 +++
+    #   scripts/Dpkg/Source/Package/V3/quilt.pm |    4 +++-
+    #   2 files changed, 6 insertions(+), 1 deletion(-)
+
+    use Dpkg::Vendor;
+    vendor_patches_distro($ENV{DEB_VENDOR}, "DEB_VENDOR");
+    vendor_patches_distro(Dpkg::Vendor::get_current_vendor(),
+                        "Dpkg::Vendor \`current vendor'");
+    vendor_patches_distro(access_basedistro(),
+                         "distro being accessed");
+}
+
 sub generate_commit_from_dsc () {
     prep_ud();
     changedir $ud;
@@ -1177,6 +1240,7 @@ sub generate_commit_from_dsc () {
     runcmd @cmd;
 
     my ($tree,$dir) = mktree_in_ud_from_only_subdir();
+    check_for_vendor_patches() if madformat($dsc->{format});
     runcmd qw(sh -ec), 'dpkg-parsechangelog >../changelog.tmp';
     my $clogp = parsecontrol('../changelog.tmp',"commit's changelog");
     my $authline = clogp_authline $clogp;
@@ -1632,6 +1696,7 @@ sub dopush ($) {
     runcmd qw(dpkg-source -x --),
         $dscpath =~ m#^/# ? $dscpath : "../../../$dscpath";
     my ($tree,$dir) = mktree_in_ud_from_only_subdir();
+    check_for_vendor_patches() if madformat($dsc->{format});
     changedir '../../../..';
     my $diffopt = $debuglevel>0 ? '--exit-code' : '--quiet';
     my @diffcmd = (@git, qw(diff), $diffopt, $tree);
@@ -2354,6 +2419,8 @@ sub build_maybe_quilt_fixup () {
     return unless madformat $format;
     # sigh
 
+    check_for_vendor_patches();
+
     # Our objective is:
     #  - honour any existing .pc in case it has any strangeness
     #  - determine the git commit corresponding to the tip of
diff --git a/tests/tests/distropatches-reject b/tests/tests/distropatches-reject
new file mode 100755 (executable)
index 0000000..c702c37
--- /dev/null
@@ -0,0 +1,83 @@
+#!/bin/bash
+set -e
+. tests/lib
+
+p=ruby-rails-3.2
+
+t-archive ruby-rails-3.2 3.2.6-1
+t-git-none
+
+cp $troot/pkg-srcs/${p}_3.2.6.orig.tar.gz .
+t-worktree test
+cd $p
+
+t-dgit --quilt=smash quilt-fixup
+
+build () {
+       t-dgit -wg --dpkg-buildpackage:-d build
+}
+
+expect-fail-distro-series () {
+       local why=$1; shift
+       t-expect-fail \
+       E:"Found active distro-specific series file.*(.*$why.*)" \
+       "$@"
+}
+
+mkdir -p debian/patches
+
+cat >debian/patches/boo <<'END'
+Description: add boo
+Author: Ian Jackson <ijackson@chiark.greenend.org.uk>
+
+---
+
+--- a/boo
++++ b/boo
+@@ -0,0 +1 @@
++content
+END
+
+echo boo >debian/patches/test-dummy.series
+
+git add debian/patches/boo
+git add debian/patches/test-dummy.series
+t-commit 'Add boo (on test-dummy)' 3.2.6-2
+
+expect-fail-distro-series 'distro being accessed' \
+build
+
+defaultvendor=$(perl -we '
+       use Dpkg::Vendor;
+       print lc Dpkg::Vendor::get_current_vendor
+')
+git mv debian/patches/test-dummy.series \
+       debian/patches/$defaultvendor.series
+t-commit 'Move boo (to default vendor)' 3.2.6-3
+
+expect-fail-distro-series 'current vendor' \
+build
+
+git mv debian/patches/$defaultvendor.series \
+       debian/patches/test-dummy-aside.series
+t-commit 'Move boo (to test-dummy-aside)' 3.2.6-4
+
+build
+
+DEB_VENDOR=test-dummy-aside \
+expect-fail-distro-series DEB_VENDOR \
+t-dgit push
+
+t-dgit push
+
+cd ..
+perl -i~ -pe 's/^Dgit:.*\n//' incoming/${p}_${v}.dsc
+t-archive-process-incoming sid
+
+rm -rf $p
+
+DEB_VENDOR=test-dummy-aside \
+expect-fail-distro-series DEB_VENDOR \
+t-dgit clone $p
+
+echo done.