@@ -731,30 +731,22 @@ def ln_sf(src, dest, noop: nil, verbose: nil)
731
731
# Like FileUtils.ln_s, but create links relative to +dest+.
732
732
#
733
733
def ln_sr ( src , dest , target_directory : true , force : nil , noop : nil , verbose : nil )
734
- fu_output_message "ln -sr#{ force ? 'f' : '' } #{
735
- target_directory ? '' : 'T' } #{ [ src , dest ] . flatten . join ' ' } " if verbose
736
- return if noop
734
+ cmd = "ln -s#{ force ? 'f' : '' } #{ target_directory ? '' : 'T' } " if verbose
737
735
unless target_directory
738
- destdirs = fu_split_path ( File . realdirpath ( dest ) )
736
+ destdirs = fu_split_path ( dest )
739
737
end
740
738
fu_each_src_dest0 ( src , dest , target_directory ) do |s , d |
741
739
if target_directory
742
- destdirs = fu_split_path ( File . realdirpath ( File . dirname ( d ) ) )
740
+ destdirs = fu_split_path ( File . dirname ( d ) )
743
741
# else d == dest
744
742
end
745
- if fu_starting_path? ( s )
746
- srcdirs = fu_split_path ( ( File . realdirpath ( s ) rescue File . expand_path ( s ) ) )
747
- base = fu_relative_components_from ( srcdirs , destdirs )
748
- s = File . join ( *base )
749
- else
750
- srcdirs = fu_clean_components ( *fu_split_path ( s ) )
751
- base = fu_relative_components_from ( fu_split_path ( Dir . pwd ) , destdirs )
752
- while srcdirs . first &. == ".." and base . last &.!=( ".." ) and !fu_starting_path? ( base . last )
753
- srcdirs . shift
754
- base . pop
755
- end
756
- s = File . join ( *base , *srcdirs )
757
- end
743
+ srcdirs = fu_split_path ( s )
744
+ i = fu_common_components ( srcdirs , destdirs )
745
+ n = destdirs . size - i
746
+ n -= 1 unless target_directory
747
+ s = File . join ( fu_clean_components ( *Array . new ( n , '..' ) , *srcdirs [ i ..-1 ] ) )
748
+ fu_output_message [ cmd , s , d ] . flatten . join ( ' ' ) if verbose
749
+ next if noop
758
750
remove_file d , true if force
759
751
File . symlink s , d
760
752
end
@@ -2504,22 +2496,26 @@ def fu_split_path(path) #:nodoc:
2504
2496
path = File . path ( path )
2505
2497
list = [ ]
2506
2498
until ( parent , base = File . split ( path ) ; parent == path or parent == "." )
2507
- list << base
2499
+ if base != '..' and list . last == '..' and !( fu_have_symlink? && File . symlink? ( path ) )
2500
+ list . pop
2501
+ else
2502
+ list << base
2503
+ end
2508
2504
path = parent
2509
2505
end
2510
2506
list << path
2511
2507
list . reverse!
2512
2508
end
2513
2509
private_module_function :fu_split_path
2514
2510
2515
- def fu_relative_components_from ( target , base ) #:nodoc:
2511
+ def fu_common_components ( target , base ) #:nodoc:
2516
2512
i = 0
2517
2513
while target [ i ] &.== base [ i ]
2518
2514
i += 1
2519
2515
end
2520
- Array . new ( base . size - i , '..' ) . concat ( target [ i ..- 1 ] )
2516
+ i
2521
2517
end
2522
- private_module_function :fu_relative_components_from
2518
+ private_module_function :fu_common_components
2523
2519
2524
2520
def fu_clean_components ( *comp ) #:nodoc:
2525
2521
comp . shift while comp . first == "."
@@ -2529,7 +2525,7 @@ def fu_clean_components(*comp) #:nodoc:
2529
2525
while c = comp . shift
2530
2526
if c == ".." and clean . last != ".." and !( fu_have_symlink? && File . symlink? ( path ) )
2531
2527
clean . pop
2532
- path . chomp !( %r((?<=\A |/)[^/]+/\z ) , "" )
2528
+ path . sub !( %r((?<=\A |/)[^/]+/\z ) , "" )
2533
2529
else
2534
2530
clean << c
2535
2531
path << c << "/"
0 commit comments