summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRaphaël Hertzog <hertzog@debian.org>2010-06-10 16:20:41 +0200
committerRaphaël Hertzog <hertzog@debian.org>2010-06-10 17:10:00 +0200
commit2b204533b8a2a95ca0d3796978368f9fd3d82b9c (patch)
tree5bd3de801792a703af514cf4adca93856e90c813
parent9278ba135233d63d7f0869cbd6ea8df0800987f3 (diff)
downloaddpkg-2b204533b8a2a95ca0d3796978368f9fd3d82b9c.tar.gz
dpkg-source: new --unapply-patches option
This option is used by source formats 2.0 and 3.0 (quilt) to unapply patches after a successful build. It's useful for people who manage their packages in a VCS repository and prefer to have patches unapplied, even after a package build. Given that this option is a matter of personal taste, do not allow it in debian/source/options so that the resulting source package cannot have this behaviour by default and so that all source packages behave in a consistent way: patches applied by default is a major feature of the new formats.
-rw-r--r--debian/changelog4
-rw-r--r--man/dpkg-source.19
-rw-r--r--scripts/Dpkg/Source/Package/V2.pm27
-rw-r--r--scripts/Dpkg/Source/Package/V3/quilt.pm23
-rwxr-xr-xscripts/dpkg-source.pl14
5 files changed, 73 insertions, 4 deletions
diff --git a/debian/changelog b/debian/changelog
index b7734cc1b..811b87cd7 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -31,6 +31,10 @@ dpkg (1.15.8) UNRELEASED; urgency=low
* update-alternatives has been rewritten in C, the only feature change
should be that it uses its own logfile /var/log/alternatives.log (rotated
like dpkg.log).
+ * Implement new --unapply-patches option for dpkg-source with source formats
+ 2.0 and 3.0 (quilt) that unapplies the patches after a successful build.
+ This option can be put in debian/source/local-options in the package VCS
+ repository for instance.
[ Guillem Jover ]
* Require gettext 0.18:
diff --git a/man/dpkg-source.1 b/man/dpkg-source.1
index 5e4d30b7c..6e19a64e4 100644
--- a/man/dpkg-source.1
+++ b/man/dpkg-source.1
@@ -506,6 +506,15 @@ Automatically create the main original tarball as empty if it's missing
and if there are supplementary original tarballs. This option is meant to
be used when the source package is just a bundle of multiple upstream
software and where there's no "main" software.
+.TP
+.B \-\-unapply\-patches
+Unapply the patches in the \fB\-\-after\-build\fP hook. This is mainly
+useful when you build your package directly in a VCS that contains
+unpatched upstream source and where you want to keep the tree unpatched
+even after a package build. This option is usually put in
+\fBdebian/source/local\-options\fP (it's not allowed in
+\fBdebian/source/options\fP so that all generated source packages have the
+same behaviour by default).
.PP
.B Extract options
diff --git a/scripts/Dpkg/Source/Package/V2.pm b/scripts/Dpkg/Source/Package/V2.pm
index 787d6acd6..3c7082121 100644
--- a/scripts/Dpkg/Source/Package/V2.pm
+++ b/scripts/Dpkg/Source/Package/V2.pm
@@ -53,6 +53,8 @@ sub init_options {
unless exists $self->{'options'}{'preparation'};
$self->{'options'}{'skip_patches'} = 0
unless exists $self->{'options'}{'skip_patches'};
+ $self->{'options'}{'unapply_patches'} = 0
+ unless exists $self->{'options'}{'unapply_patches'};
$self->{'options'}{'skip_debianization'} = 0
unless exists $self->{'options'}{'skip_debianization'};
$self->{'options'}{'create_empty_orig'} = 0
@@ -76,6 +78,9 @@ sub parse_cmdline_option {
} elsif ($opt =~ /^--skip-patches$/) {
$self->{'options'}{'skip_patches'} = 1;
return 1;
+ } elsif ($opt =~ /^--unapply-patches$/) {
+ $self->{'options'}{'unapply_patches'} = 1;
+ return 1;
} elsif ($opt =~ /^--skip-debianization$/) {
$self->{'options'}{'skip_debianization'} = 1;
return 1;
@@ -206,6 +211,23 @@ sub apply_patches {
close(APPLIED);
}
+sub unapply_patches {
+ my ($self, $dir, %opts) = @_;
+ my @patches = reverse($self->get_patches($dir, %opts));
+ return unless scalar(@patches);
+ my $timestamp = time();
+ my $applied = File::Spec->catfile($dir, "debian", "patches", ".dpkg-source-applied");
+ foreach my $patch (@patches) {
+ my $path = File::Spec->catfile($dir, "debian", "patches", $patch);
+ info(_g("unapplying %s"), $patch) unless $opts{"quiet"};
+ my $patch_obj = Dpkg::Source::Patch->new(filename => $path);
+ $patch_obj->apply($dir, force_timestamp => 1,
+ timestamp => $timestamp,
+ add_options => [ '-E', '-R' ]);
+ }
+ unlink($applied);
+}
+
sub can_build {
my ($self, $dir) = @_;
return 1 if $self->find_original_tarballs(include_supplementary => 0);
@@ -219,6 +241,11 @@ sub before_build {
$self->check_patches_applied($dir) if $self->{'options'}{'preparation'};
}
+sub after_build {
+ my ($self, $dir) = @_;
+ $self->unapply_patches($dir) if $self->{'options'}{'unapply_patches'};
+}
+
sub prepare_build {
my ($self, $dir) = @_;
$self->{'diff_options'} = {
diff --git a/scripts/Dpkg/Source/Package/V3/quilt.pm b/scripts/Dpkg/Source/Package/V3/quilt.pm
index bb9030005..ad352d32e 100644
--- a/scripts/Dpkg/Source/Package/V3/quilt.pm
+++ b/scripts/Dpkg/Source/Package/V3/quilt.pm
@@ -227,6 +227,29 @@ sub apply_patches {
close(APPLIED);
}
+sub unapply_patches {
+ my ($self, $dir, %opts) = @_;
+
+ $opts{'verbose'} = 1 unless defined $opts{'verbose'};
+
+ my $pc_applied = File::Spec->catfile($dir, ".pc", "applied-patches");
+ my @applied = $self->read_patch_list($pc_applied);
+ $opts{"timestamp"} = time();
+ foreach my $patch (reverse @applied) {
+ my $path = File::Spec->catfile($dir, "debian", "patches", $patch);
+ my $obj = Dpkg::Source::Patch->new(filename => $path);
+
+ info(_g("unapplying %s"), $patch) if $opts{"verbose"};
+ $obj->apply($dir, timestamp => $opts{"timestamp"},
+ force_timestamp => 1, remove_backup => 0,
+ options => [ '-R', '-s', '-t', '-N', '-p1',
+ '-u', '-V', 'never', '-g0', '-E',
+ '--no-backup-if-mismatch' ]);
+ erasedir(File::Spec->catdir($dir, ".pc", $patch));
+ }
+ unlink($pc_applied);
+}
+
sub prepare_build {
my ($self, $dir) = @_;
$self->SUPER::prepare_build($dir);
diff --git a/scripts/dpkg-source.pl b/scripts/dpkg-source.pl
index 403f0fc4e..04bb4a755 100755
--- a/scripts/dpkg-source.pl
+++ b/scripts/dpkg-source.pl
@@ -104,15 +104,21 @@ if (defined($options{'opmode'}) &&
if (not -d $dir) {
error(_g("directory argument %s is not a directory"), $dir);
}
+ # --format options are not allowed, they would take precedence
+ # over real command line options, debian/source/format should be used
+ # instead
+ # --unapply-patches is only allowed in local-options as it's a matter
+ # of personal taste and the default should be to keep patches applied
+ my $forbidden_opts_re = {
+ "options" => qr/^--(?:format=|unapply-patches$)/,
+ "local-options" => qr/^--format=/,
+ };
foreach my $filename ("local-options", "options") {
my $conf = Dpkg::Conf->new();
my $optfile = File::Spec->catfile($dir, "debian", "source", $filename);
next unless -f $optfile;
$conf->load($optfile);
- # --format options are not allowed, they would take precedence
- # over real command line options, debian/source/format should be used
- # instead
- @$conf = grep { ! /^--format=/ } @$conf;
+ $conf->filter(remove => sub { $_[0] =~ $forbidden_opts_re->{$filename} });
if (@$conf) {
info(_g("using options from %s: %s"), $optfile, join(" ", @$conf))
unless $options{'opmode'} eq "--print-format";