File tree Expand file tree Collapse file tree 2 files changed +56
-1
lines changed
Expand file tree Collapse file tree 2 files changed +56
-1
lines changed Original file line number Diff line number Diff line change @@ -567,3 +567,53 @@ fn copy_dir_preserves_symlinks() {
567567 "Dir symlink target should be preserved"
568568 ) ;
569569}
570+
571+ #[ test]
572+ #[ cfg( unix) ]
573+ fn copy_file_preserves_symlinks ( ) {
574+ // copy_file must preserve symlink targets, not create new symlinks to source
575+ use std:: os:: unix:: fs:: symlink;
576+
577+ let cx = DistContext :: new ( None ) . unwrap ( ) ;
578+ let mut tx = cx. transaction ( ) ;
579+
580+ let src_dir = cx. pkg_dir . path ( ) ;
581+ let real_file = src_dir. join ( "real_file.txt" ) ;
582+ utils:: write_file ( "" , & real_file, "content" ) . unwrap ( ) ;
583+
584+ let link_file = src_dir. join ( "link.txt" ) ;
585+ symlink ( "real_file.txt" , & link_file) . unwrap ( ) ;
586+
587+ assert ! (
588+ fs:: symlink_metadata( & link_file)
589+ . unwrap( )
590+ . file_type( )
591+ . is_symlink( )
592+ ) ;
593+ assert_eq ! (
594+ fs:: read_link( & link_file) . unwrap( ) . to_str( ) . unwrap( ) ,
595+ "real_file.txt"
596+ ) ;
597+
598+ tx. copy_file (
599+ "test-component" ,
600+ PathBuf :: from ( "copied_link.txt" ) ,
601+ & link_file,
602+ )
603+ . unwrap ( ) ;
604+ tx. commit ( ) ;
605+
606+ let dest_link = cx. prefix . path ( ) . join ( "copied_link.txt" ) ;
607+ assert ! (
608+ fs:: symlink_metadata( & dest_link)
609+ . unwrap( )
610+ . file_type( )
611+ . is_symlink( ) ,
612+ "Copied file should be a symlink"
613+ ) ;
614+ assert_eq ! (
615+ fs:: read_link( & dest_link) . unwrap( ) . to_str( ) . unwrap( ) ,
616+ "real_file.txt" ,
617+ "Symlink target should be preserved, not point to original source"
618+ ) ;
619+ }
Original file line number Diff line number Diff line change @@ -232,7 +232,12 @@ pub(crate) fn copy_file(src: &Path, dest: &Path) -> Result<()> {
232232 path : PathBuf :: from ( src) ,
233233 } ) ?;
234234 if metadata. file_type ( ) . is_symlink ( ) {
235- symlink_file ( src, dest) . map ( |_| ( ) )
235+ // Read the symlink target and create a new symlink with the same target
236+ let link_target = fs:: read_link ( src) . with_context ( || RustupError :: ReadingFile {
237+ name : "symlink target for" ,
238+ path : PathBuf :: from ( src) ,
239+ } ) ?;
240+ symlink_file ( & link_target, dest) . map ( |_| ( ) )
236241 } else {
237242 fs:: copy ( src, dest)
238243 . with_context ( || {
You can’t perform that action at this time.
0 commit comments