@@ -731,30 +731,34 @@ 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 
737-     unless  target_directory 
738-       destdirs  =  fu_split_path ( File . realdirpath ( dest ) ) 
739-     end 
734+     cmd  =  "ln -s#{ force  ? 'f'  : '' } #{ target_directory  ? ''  : 'T' }  "  if  verbose 
740735    fu_each_src_dest0 ( src ,  dest ,  target_directory )  do  |s , d |
741736      if  target_directory 
742-         destdirs  =  fu_split_path ( File . realdirpath ( File . dirname ( d ) ) ) 
743-       # 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 ) ) 
744743      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 ) 
744+       srcdirs  =  fu_split_path ( s ) 
745+       i  =  fu_common_components ( srcdirs ,  destdirs ) 
746+       n  =  destdirs . size  - i 
747+       n  -= 1  unless  target_directory 
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 
749752      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 ) 
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 
757758      end 
759+       s  =  File . join ( link1 ) 
760+       fu_output_message  [ cmd ,  s ,  d ] . flatten . join ( ' ' )  if  verbose 
761+       next  if  noop 
758762      remove_file  d ,  true  if  force 
759763      File . symlink  s ,  d 
760764    end 
@@ -2504,22 +2508,26 @@ def fu_split_path(path) #:nodoc:
25042508    path  =  File . path ( path ) 
25052509    list  =  [ ] 
25062510    until  ( parent ,  base  =  File . split ( path ) ;  parent  == path  or  parent  == "." ) 
2507-       list  << base 
2511+       if  base  != '..'  and  list . last  == '..'  and  !( fu_have_symlink?  && File . symlink? ( path ) ) 
2512+         list . pop 
2513+       else 
2514+         list  << base 
2515+       end 
25082516      path  =  parent 
25092517    end 
25102518    list  << path 
25112519    list . reverse! 
25122520  end 
25132521  private_module_function  :fu_split_path 
25142522
2515-   def  fu_relative_components_from ( target ,  base )  #:nodoc: 
2523+   def  fu_common_components ( target ,  base )  #:nodoc: 
25162524    i  =  0 
25172525    while  target [ i ] &.== base [ i ] 
25182526      i  += 1 
25192527    end 
2520-     Array . new ( base . size - i ,   '..' ) . concat ( target [ i ..- 1 ] ) 
2528+     i 
25212529  end 
2522-   private_module_function  :fu_relative_components_from  
2530+   private_module_function  :fu_common_components  
25232531
25242532  def  fu_clean_components ( *comp )  #:nodoc: 
25252533    comp . shift  while  comp . first  == "." 
@@ -2529,7 +2537,7 @@ def fu_clean_components(*comp) #:nodoc:
25292537    while  c  =  comp . shift 
25302538      if  c  == ".."  and  clean . last  != ".."  and  !( fu_have_symlink?  && File . symlink? ( path ) ) 
25312539        clean . pop 
2532-         path . chomp !( %r((?<=\A |/)[^/]+/\z ) ,  "" ) 
2540+         path . sub !( %r((?<=\A |/)[^/]+/\z ) ,  "" ) 
25332541      else 
25342542        clean  << c 
25352543        path  << c  << "/" 
0 commit comments