From 71c059d03358cd040a4187df516aa410f5ba3c2a Mon Sep 17 00:00:00 2001 From: Orestis Floros Date: Sun, 18 Oct 2020 20:02:37 +0200 Subject: [PATCH] i3-dmenu-desktop: Manually search for topdir (#4033) Since 3a672bc, using follow or follow_fast, does not set $File::Find::topdir, breaking our deduplication. Fixes #4031 --- i3-dmenu-desktop | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/i3-dmenu-desktop b/i3-dmenu-desktop index 5c34b2bb6..07fe83360 100755 --- a/i3-dmenu-desktop +++ b/i3-dmenu-desktop @@ -13,6 +13,7 @@ use POSIX qw(locale_h); use File::Find; use File::Basename qw(basename); use File::Temp qw(tempfile); +use List::Util 'first'; use Getopt::Long; use Pod::Usage; use v5.10; @@ -123,6 +124,8 @@ for my $dir (split(':', $xdg_data_dirs)) { # Cleanup the paths, maybe some application does not cope with double slashes # (the field code %k is replaced with the .desktop file location). @searchdirs = map { s,//,/,g; $_ } @searchdirs; +# Also remove any trailing slashes. +@searchdirs = map { s,/*$,,g; $_ } @searchdirs; # To avoid errors by File::Find’s find(), only pass existing directories. @searchdirs = grep { -d $_ } @searchdirs; @@ -133,8 +136,15 @@ find( return unless substr($_, -1 * length('.desktop')) eq '.desktop'; my $relative = $File::Find::name; - # + 1 for the trailing /, which is missing in ::topdir. - substr($relative, 0, length($File::Find::topdir) + 1) = ''; + # Find and then replace the directory in @searchdirs in which the + # current file is located. We used to do this with + # $File::Find::topdir but it is not supported when using the + # 'follow' or 'follow_fast' options. + # See #3973, #4031. + my $topdir = first { substr($relative, 0, length($_)) eq $_ } @searchdirs; + + # + 1 for the trailing /, which is missing in $topdir. + substr($relative, 0, length($topdir) + 1) = ''; # Don’t overwrite files with the same relative path, we search in # descending order of importance.