On Sun, 2014-12-28 at 14:51 +0200, Niko Tyni wrote:
> A more robust solution is using dpkg-divert in maintainer scripts to move
> the core version out of the way and then back later if necessary. See
> for instance the libmodule-corelist-perl package for an example
> implementation.

Okay, attached is a revised patch that does exactly that.

It works (and it's taken me all day), but I admit that it's pretty
messy, so would welcome any feedback as to how to make this a little
tidier.

I figured that the dpkg-divert lines have to be generated during build,
otherwise it's not easily known which files will be installed.

Comments welcome!

>From 1037863029557e6f03252c0d0f7256c9d8f0e45e Mon Sep 17 00:00:00 2001
From: Andy Beverley <a...@andybev.com>
Date: Sun, 28 Dec 2014 23:57:06 +0000
Subject: [PATCH] Fix install fails with "trying to overwrite foo which is
 also in bar"

This patch installs dpkg-divert lines into preinst and postrm
to preserve files that are also installed by core packages. If
a module is built that is also part of core, these lines will
allow the 2 packages to coexist on the same system.
---
 debian/rules.dh.core                |   30 ++++++++++++++++++++++++++++++
 lib/Debian/Rules.pm                 |   13 +++++++++++++
 lib/DhMakePerl/Command/Packaging.pm |    7 +++++--
 lib/DhMakePerl/Command/make.pm      |    6 ++++--
 4 files changed, 52 insertions(+), 4 deletions(-)
 create mode 100755 debian/rules.dh.core

diff --git a/debian/rules.dh.core b/debian/rules.dh.core
new file mode 100755
index 0000000..6a8f24b
--- /dev/null
+++ b/debian/rules.dh.core
@@ -0,0 +1,30 @@
+#!/usr/bin/make -f
+
+# Rules file for core modules. This adds dpkg-divert commands to the
+# package to save existing copies of files that will be overwritten
+
+%:
+	dh $@
+
+override_dh_auto_configure:
+	dh_auto_configure -- NO_PERLLOCAL=1
+
+override_dh_md5sums:
+	# md5sums will contain all the files to be installed. Once it's been
+	# created, see whether any of the files to be installed already exist
+	# as part of another package
+	dh_md5sums
+	# The initial part of the shell script
+	echo '#!/bin/sh\n\nset -e\n\nif [ "$$1" = install ] || [ "$$1" = upgrade ]\nthen' > debian/PACKAGENAME/DEBIAN/preinst
+	# For each file in md5sums, see if it exists in another package on the
+	# system, and if it does, add the dpkg-divert commands
+	cut -d ' ' -f 3 debian/PACKAGENAME/DEBIAN/md5sums|xargs dpkg -S / 2> /dev/null|awk '/^perl/ {print "dpkg-divert --add --package PACKAGENAME --rename --divert " $$2 ".bundled " $$2 }' >> debian/PACKAGENAME/DEBIAN/preinst
+	# The end of the script
+	echo 'fi\nexit 0' >> debian/PACKAGENAME/DEBIAN/preinst
+	# Make the preinst file executable
+	chmod +x debian/PACKAGENAME/DEBIAN/preinst
+	# Same again for the package removal (postrm)
+	echo '#!/bin/sh\n\nset -e\n\nif [ "$$1" = remove ]\nthen' > debian/PACKAGENAME/DEBIAN/postrm
+	cut -d ' ' -f 3 debian/PACKAGENAME/DEBIAN/md5sums|xargs dpkg -S / 2> /dev/null|awk '/^perl/ {print "dpkg-divert --remove --package PACKAGENAME --rename --divert " $$2 ".bundled " $$2 }' >> debian/PACKAGENAME/DEBIAN/postrm
+	echo 'fi\nexit 0' >> debian/PACKAGENAME/DEBIAN/postrm
+	chmod +x debian/PACKAGENAME/DEBIAN/postrm
diff --git a/lib/Debian/Rules.pm b/lib/Debian/Rules.pm
index 9adc5e2..259d6af 100644
--- a/lib/Debian/Rules.pm
+++ b/lib/Debian/Rules.pm
@@ -369,6 +369,19 @@ sub write {
     }
 }
 
+=item transform $sub
+
+Transforms each line of the file using the subroutine $sub
+
+=cut
+
+sub transform {
+    my $self = shift;
+    my $sub = shift or die "Please pass a regular expression with which to transform";
+
+    $self->lines( [ map { $sub->($_) } @{ $self->lines } ] );
+}
+
 sub DESTROY {
     my $self = shift;
 
diff --git a/lib/DhMakePerl/Command/Packaging.pm b/lib/DhMakePerl/Command/Packaging.pm
index 6c0b158..e615c38 100644
--- a/lib/DhMakePerl/Command/Packaging.pm
+++ b/lib/DhMakePerl/Command/Packaging.pm
@@ -20,7 +20,7 @@ __PACKAGE__->mk_accessors(
         mod_cpan_version
         meta perlname author
         version rules docs examples copyright
-        control
+        control core_module
     )
 );
 
@@ -867,7 +867,7 @@ sub create_rules {
 
     $self->backup_file($file);
 
-    my $rulesname = 'rules.dh.tiny';
+    my $rulesname = $self->core_module ? 'rules.dh.core' : 'rules.dh.tiny';
 
     for my $source (
         catfile( $self->cfg->home_dir, $rulesname ),
@@ -876,6 +876,9 @@ sub create_rules {
         if ( -e $source ) {
             print "Using rules: $source\n" if $self->cfg->verbose;
             $self->rules->read($source);
+            my $pkgname = $self->pkgname;
+            # Substitute any variables in the rules file
+            $self->rules->transform( sub{ s/PACKAGENAME/$pkgname/g; $_ } );
             last;
         };
     }
diff --git a/lib/DhMakePerl/Command/make.pm b/lib/DhMakePerl/Command/make.pm
index 64a067f..1449737 100644
--- a/lib/DhMakePerl/Command/make.pm
+++ b/lib/DhMakePerl/Command/make.pm
@@ -14,7 +14,7 @@ __PACKAGE__->mk_accessors(
         perlname version pkgversion
         copyright author
         extrasfields  extrapfields
-        docs examples
+        docs examples core_module
         )
 );
 
@@ -76,6 +76,8 @@ sub execute {
 
     $self->check_deprecated_overrides;
 
+    $self->core_module(1) if is_core_module($self->cfg->cpan);
+
     my $tarball = $self->setup_dir();
     $self->process_meta;
     $self->findbin_fix();
@@ -301,7 +303,7 @@ sub setup_dir {
         $orig_pwd = $ENV{'PWD'};
 
         # Is the module a core module?
-       if ( is_core_module( $self->cfg->cpan ) ) {
+       if ( $self->core_module ) {
             die $self->cfg->cpan
             . " is a standard module. Will not build without --core-ok.\n"
                 unless $self->cfg->core_ok;
-- 
1.7.10.4

Reply via email to