Skip to content

Commit 277f7f2

Browse files
committed
Use shorter symlink by real paths
1 parent 2836a16 commit 277f7f2

File tree

2 files changed

+21
-7
lines changed

2 files changed

+21
-7
lines changed

lib/fileutils.rb

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -732,19 +732,31 @@ def ln_sf(src, dest, noop: nil, verbose: nil)
732732
#
733733
def ln_sr(src, dest, target_directory: true, force: nil, noop: nil, verbose: nil)
734734
cmd = "ln -s#{force ? 'f' : ''}#{target_directory ? '' : 'T'}" if verbose
735-
unless target_directory
736-
destdirs = fu_split_path(dest)
737-
end
738735
fu_each_src_dest0(src, dest, target_directory) do |s,d|
739736
if target_directory
740-
destdirs = fu_split_path(File.dirname(d))
741-
# else d == dest
737+
parent = File.dirname(d)
738+
destdirs = fu_split_path(parent)
739+
real_ddirs = fu_split_path(File.realpath(parent))
740+
else
741+
destdirs ||= fu_split_path(dest)
742+
real_ddirs ||= fu_split_path(File.realpath(dest))
742743
end
743744
srcdirs = fu_split_path(s)
744745
i = fu_common_components(srcdirs, destdirs)
745746
n = destdirs.size - i
746747
n -= 1 unless target_directory
747-
s = File.join(fu_clean_components(*Array.new(n, '..'), *srcdirs[i..-1]))
748+
link1 = fu_clean_components(*Array.new([n, 0].max, '..'), *srcdirs[i..-1])
749+
begin
750+
real_sdirs = fu_split_path(File.realdirpath(s)) rescue nil
751+
rescue
752+
else
753+
i = fu_common_components(real_sdirs, real_ddirs)
754+
n = real_ddirs.size - i
755+
n -= 1 unless target_directory
756+
link2 = fu_clean_components(*Array.new([n, 0].max, '..'), *real_sdirs[i..-1])
757+
link1 = link2 if link1.size > link2.size
758+
end
759+
s = File.join(link1)
748760
fu_output_message [cmd, s, d].flatten.join(' ') if verbose
749761
next if noop
750762
remove_file d, true if force

test/fileutils/test_fileutils.rb

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1031,7 +1031,8 @@ def test_ln_sr
10311031
assert_all_assertions_foreach(nil, *TARGETS) do |fname|
10321032
lnfname = 'tmp/lnsdest'
10331033
ln_sr fname, lnfname
1034-
assert FileTest.symlink?(lnfname), 'not symlink'
1034+
assert_file.symlink?(lnfname)
1035+
assert_file.identical?(lnfname, fname)
10351036
assert_equal "../#{fname}", File.readlink(lnfname)
10361037
ensure
10371038
rm_f lnfname
@@ -1060,6 +1061,7 @@ def test_ln_sr
10601061
ln_sr 'tmp/src/xxx', 'data'
10611062
assert_file.symlink?('data/xxx')
10621063
assert_equal 'ok', File.read('data/xxx')
1064+
assert_equal 'src/xxx', File.readlink('data/xxx')
10631065
end
10641066

10651067
def test_ln_sr_not_target_directory

0 commit comments

Comments
 (0)