@@ -731,30 +731,22 @@ def ln_sf(src, dest, noop: nil, verbose: nil)
731731 # Like FileUtils.ln_s, but create links relative to +dest+.
732732 #
733733 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
737735 unless target_directory
738- destdirs = fu_split_path ( File . realdirpath ( dest ) )
736+ destdirs = fu_split_path ( dest )
739737 end
740738 fu_each_src_dest0 ( src , dest , target_directory ) do |s , d |
741739 if target_directory
742- destdirs = fu_split_path ( File . realdirpath ( File . dirname ( d ) ) )
740+ destdirs = fu_split_path ( File . dirname ( d ) )
743741 # else d == dest
744742 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
758750 remove_file d , true if force
759751 File . symlink s , d
760752 end
@@ -2504,22 +2496,26 @@ def fu_split_path(path) #:nodoc:
25042496 path = File . path ( path )
25052497 list = [ ]
25062498 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
25082504 path = parent
25092505 end
25102506 list << path
25112507 list . reverse!
25122508 end
25132509 private_module_function :fu_split_path
25142510
2515- def fu_relative_components_from ( target , base ) #:nodoc:
2511+ def fu_common_components ( target , base ) #:nodoc:
25162512 i = 0
25172513 while target [ i ] &.== base [ i ]
25182514 i += 1
25192515 end
2520- Array . new ( base . size - i , '..' ) . concat ( target [ i ..- 1 ] )
2516+ i
25212517 end
2522- private_module_function :fu_relative_components_from
2518+ private_module_function :fu_common_components
25232519
25242520 def fu_clean_components ( *comp ) #:nodoc:
25252521 comp . shift while comp . first == "."
@@ -2529,7 +2525,7 @@ def fu_clean_components(*comp) #:nodoc:
25292525 while c = comp . shift
25302526 if c == ".." and clean . last != ".." and !( fu_have_symlink? && File . symlink? ( path ) )
25312527 clean . pop
2532- path . chomp !( %r((?<=\A |/)[^/]+/\z ) , "" )
2528+ path . sub !( %r((?<=\A |/)[^/]+/\z ) , "" )
25332529 else
25342530 clean << c
25352531 path << c << "/"
0 commit comments