Control: tags -1 + patch

Hi Colin,

On Thu, Nov 23, 2023 at 03:45:56PM +0000, Colin Watson wrote:
> Talking to Helmut at the mini-Debconf in Cambridge, we went back and
> forth a bit but his gut feeling appeared to be that it would make sense
> to at least experiment with having dh_movetousr update symlink targets,
> so I'm filing this bug as a reminder.

I've come up with a solution to this and appreciate reviews (not
necessarily by Colin).

A couple of words regarding the implementation:
 * It converts symlinks in /usr before merging as the merged symlinks
   are being recreated anyway and we don't want to duplicate that.
 * File::Find is happy with scanning a directory that does not exist.
 * Are there sufficient test cases?

Helmut
diff -Nru debhelper-13.11.8/debian/changelog debhelper-13.11.9/debian/changelog
--- debhelper-13.11.8/debian/changelog  2023-11-15 09:10:26.000000000 +0100
+++ debhelper-13.11.9/debian/changelog  2023-11-24 06:48:33.000000000 +0100
@@ -1,3 +1,10 @@
+debhelper (13.11.9) UNRELEASED; urgency=medium
+
+  * dh_movetousr also updates links from canonical into aliased. (Closes:
+    #1056590)
+
+ -- Helmut Grohne <hel...@subdivi.de>  Fri, 24 Nov 2023 06:48:33 +0100
+
 debhelper (13.11.8) unstable; urgency=medium
 
   * Team upload.
diff -Nru debhelper-13.11.8/dh_movetousr debhelper-13.11.9/dh_movetousr
--- debhelper-13.11.8/dh_movetousr      2023-11-15 07:21:59.000000000 +0100
+++ debhelper-13.11.9/dh_movetousr      2023-11-24 00:08:11.000000000 +0100
@@ -9,6 +9,7 @@
 use strict;
 use warnings;
 use Config;
+use File::Find;
 use File::Spec;
 use Debian::Debhelper::Dh_Lib;
 
@@ -76,6 +77,7 @@
 my @merged_directories = (
        qw{bin lib lib64 libo32 libx32 sbin},
 );
+my $merged_dir_pattern = join('|', @merged_directories);
 
 sub merge_entry {
        my ($package, $rootdir, $location) = @_;
@@ -159,6 +161,22 @@
 
                next if ! -d $tmp;
 
+               # Reconstruct absolute symlinks pointing from /usr into an
+               # aliased directory.
+               find (
+                       {
+                               wanted => sub {
+                                       return unless -l;
+                                       my $target = readlink($_);
+                                       return unless ($target =~ 
m,^/($merged_dir_pattern)(/|$),);
+                                       s|^\Q$tmp\E||;
+                                       make_symlink("$_", "usr/$target", $tmp);
+                               },
+                               no_chdir => 1
+                       },
+                       "$tmp/usr"
+               );
+
                foreach my $dir (@merged_directories) {
                        if (-d "$tmp/$dir" && ! -l "$tmp/$dir") {
                                merge_entry($package, $tmp, $dir);
diff -Nru debhelper-13.11.8/t/dh_movetousr/dh_movetousr.t 
debhelper-13.11.9/t/dh_movetousr/dh_movetousr.t
--- debhelper-13.11.8/t/dh_movetousr/dh_movetousr.t     2023-11-15 
07:21:59.000000000 +0100
+++ debhelper-13.11.9/t/dh_movetousr/dh_movetousr.t     2023-11-24 
06:48:33.000000000 +0100
@@ -13,6 +13,9 @@
 
 each_compat_subtest {
        my ($compat) = @_;
+       make_path('debian/debhelper');
+       # Don't fail on an empty package.
+       ok(run_dh_tool('dh_movetousr'));
        make_path('debian/debhelper/lib/foo');
        make_path('debian/debhelper/lib/bar');
        make_path('debian/debhelper/usr/lib/bar');
@@ -27,6 +30,9 @@
        make_symlink_raw_target('../../bar', 'debian/debhelper/lib/foo/rel3');
        make_symlink_raw_target('../../../bar', 
'debian/debhelper/lib/foo/rel4');
        make_symlink_raw_target('/usr/bin/bar', 'debian/debhelper/sbin/foo');
+       make_symlink_raw_target('dead', 'debian/debhelper/usr/lib/rel');
+       make_symlink_raw_target('/etc', 'debian/debhelper/usr/lib/abs1');
+       make_symlink_raw_target('/sbin/foo', 'debian/debhelper/usr/lib/abs2');
        ok(run_dh_tool('dh_movetousr', '--fail-noop'));
        # Files get moved.
        ok(! -e 'debian/debhelper/lib');
@@ -60,6 +66,15 @@
        # policy 10.5.
        ok(-l 'debian/debhelper/usr/sbin/foo');
        ok(readlink('debian/debhelper/usr/sbin/foo') eq '../bin/bar');
+       # Relative link within /usr is left alone.
+       ok(-l 'debian/debhelper/usr/lib/rel');
+       ok(readlink('debian/debhelper/usr/lib/rel') eq 'dead');
+       # Absolute link not pointing into aliased is left alone.
+       ok(-l 'debian/debhelper/usr/lib/abs1');
+       ok(readlink('debian/debhelper/usr/lib/abs1') eq '/etc');
+       # Absolute link pointing into aliased becomes relative.
+       ok(-l 'debian/debhelper/usr/lib/abs2');
+       ok(readlink('debian/debhelper/usr/lib/abs2') eq '../sbin/foo');
        ok(!run_dh_tool({ quiet => 1 }, 'dh_movetousr', '--fail-noop'));
        ok(run_dh_tool('dh_movetousr'));
        remove_tree('debian/debhelper');

Reply via email to