1
+ use std::fs::FileType;
1
2
use std::io;
2
3
use std::path::{Path, PathBuf};
3
4
@@ -6,12 +7,13 @@ use std::path::{Path, PathBuf};
6
7
pub fn copy_symlink(src: impl AsRef<Path>, dst: impl AsRef<Path>) {
7
8
let src = src.as_ref();
8
9
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) {
10
12
panic!("failed to copy symlink from `{}` to `{}`: {e}", src.display(), dst.display(),);
11
13
}
12
14
}
13
15
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<()> {
15
17
// Traverse symlink once to find path of target entity.
16
18
let target_path = std::fs::read_link(src)?;
17
19
@@ -54,7 +56,7 @@ pub fn copy_dir_all(src: impl AsRef<Path>, dst: impl AsRef<Path>) {
54
56
if ty.is_dir() {
55
57
copy_dir_all_inner(entry.path(), dst.join(entry.file_name()))?;
56
58
} 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()))?;
58
60
} else {
59
61
std::fs::copy(entry.path(), dst.join(entry.file_name()))?;
60
62
}
@@ -80,6 +82,21 @@ pub fn read_dir_entries<P: AsRef<Path>, F: FnMut(&Path)>(dir: P, mut callback: F
80
82
}
81
83
}
82
84
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
+
83
100
/// A wrapper around [`std::fs::remove_file`] which includes the file path in the panic message.
84
101
#[track_caller]
85
102
pub fn remove_file<P: AsRef<Path>>(path: P) {
0 commit comments