1+ use std:: fs:: FileType ;
12use std:: io;
23use std:: path:: { Path , PathBuf } ;
34
@@ -6,12 +7,13 @@ use std::path::{Path, PathBuf};
67pub fn copy_symlink ( src : impl AsRef < Path > , dst : impl AsRef < Path > ) {
78 let src = src. as_ref ( ) ;
89 let dst = dst. as_ref ( ) ;
9- if let Err ( e) = copy_symlink_raw ( src, dst) {
10+ let metadata = symlink_metadata ( src) ;
11+ if let Err ( e) = copy_symlink_raw ( metadata. file_type ( ) , src, dst) {
1012 panic ! ( "failed to copy symlink from `{}` to `{}`: {e}" , src. display( ) , dst. display( ) , ) ;
1113 }
1214}
1315
14- fn copy_symlink_raw ( src : impl AsRef < Path > , dst : impl AsRef < Path > ) -> io:: Result < ( ) > {
16+ fn copy_symlink_raw ( ty : FileType , src : impl AsRef < Path > , dst : impl AsRef < Path > ) -> io:: Result < ( ) > {
1517 // Traverse symlink once to find path of target entity.
1618 let target_path = std:: fs:: read_link ( src) ?;
1719
@@ -54,7 +56,7 @@ pub fn copy_dir_all(src: impl AsRef<Path>, dst: impl AsRef<Path>) {
5456 if ty. is_dir ( ) {
5557 copy_dir_all_inner ( entry. path ( ) , dst. join ( entry. file_name ( ) ) ) ?;
5658 } else if ty. is_symlink ( ) {
57- copy_symlink_raw ( entry. path ( ) , dst. join ( entry. file_name ( ) ) ) ?;
59+ copy_symlink_raw ( ty , entry. path ( ) , dst. join ( entry. file_name ( ) ) ) ?;
5860 } else {
5961 std:: fs:: copy ( entry. path ( ) , dst. join ( entry. file_name ( ) ) ) ?;
6062 }
@@ -80,6 +82,21 @@ pub fn read_dir_entries<P: AsRef<Path>, F: FnMut(&Path)>(dir: P, mut callback: F
8082 }
8183}
8284
85+ /// A wrapper around [`build_helper::fs::recursive_remove`] which includes the file path in the
86+ /// panic message.
87+ ///
88+ /// This handles removing symlinks on Windows (e.g. symlink-to-file will be removed via
89+ /// [`std::fs::remove_file`] while symlink-to-dir will be removed via [`std::fs::remove_dir`]).
90+ #[ track_caller]
91+ pub fn recursive_remove < P : AsRef < Path > > ( path : P ) {
92+ if let Err ( e) = build_helper:: fs:: recursive_remove ( path. as_ref ( ) ) {
93+ panic ! (
94+ "failed to recursive remove filesystem entities at `{}`: {e}" ,
95+ path. as_ref( ) . display( )
96+ ) ;
97+ }
98+ }
99+
83100/// A wrapper around [`std::fs::remove_file`] which includes the file path in the panic message.
84101#[ track_caller]
85102pub fn remove_file < P : AsRef < Path > > ( path : P ) {
0 commit comments