Skip to content

Commit 582e910

Browse files
committed
run_make_support: extract copy_symlink helper
1 parent b22856d commit 582e910

File tree

1 file changed

+42
-26
lines changed
  • src/tools/run-make-support/src

1 file changed

+42
-26
lines changed

src/tools/run-make-support/src/fs.rs

+42-26
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,47 @@
11
use std::io;
22
use std::path::{Path, PathBuf};
33

4-
/// Copy a directory into another.
4+
/// Given a symlink at `src`, read its target, then create a new symlink at `dst` also pointing to
5+
/// target.
6+
pub fn copy_symlink(src: impl AsRef<Path>, dst: impl AsRef<Path>) {
7+
let src = src.as_ref();
8+
let dst = dst.as_ref();
9+
if let Err(e) = copy_symlink_raw(src, dst) {
10+
panic!("failed to copy symlink from `{}` to `{}`: {e}", src.display(), dst.display(),);
11+
}
12+
}
13+
14+
fn copy_symlink_raw(src: impl AsRef<Path>, dst: impl AsRef<Path>) -> io::Result<()> {
15+
// Traverse symlink once to find path of target entity.
16+
let target_path = std::fs::read_link(src)?;
17+
18+
let new_symlink_path = dst.as_ref();
19+
#[cfg(windows)]
20+
{
21+
use std::os::windows::fs::FileTypeExt;
22+
if ty.is_symlink_dir() {
23+
std::os::windows::fs::symlink_dir(&target_path, new_symlink_path)?;
24+
} else {
25+
// Target may be a file or another symlink, in any case we can use
26+
// `symlink_file` here.
27+
std::os::windows::fs::symlink_file(&target_path, new_symlink_path)?;
28+
}
29+
}
30+
#[cfg(unix)]
31+
{
32+
std::os::unix::fs::symlink(target_path, new_symlink_path)?;
33+
}
34+
#[cfg(not(any(windows, unix)))]
35+
{
36+
// Technically there's also wasi, but I have no clue about wasi symlink
37+
// semantics and which wasi targets / environment support symlinks.
38+
unimplemented!("unsupported target");
39+
}
40+
Ok(())
41+
}
42+
43+
/// Copy a directory into another. This will not traverse symlinks; instead, it will create new
44+
/// symlinks pointing at target paths that symlinks in the original directory points to.
545
pub fn copy_dir_all(src: impl AsRef<Path>, dst: impl AsRef<Path>) {
646
fn copy_dir_all_inner(src: impl AsRef<Path>, dst: impl AsRef<Path>) -> io::Result<()> {
747
let dst = dst.as_ref();
@@ -14,31 +54,7 @@ pub fn copy_dir_all(src: impl AsRef<Path>, dst: impl AsRef<Path>) {
1454
if ty.is_dir() {
1555
copy_dir_all_inner(entry.path(), dst.join(entry.file_name()))?;
1656
} else if ty.is_symlink() {
17-
// Traverse symlink once to find path of target entity.
18-
let target_path = std::fs::read_link(entry.path())?;
19-
20-
let new_symlink_path = dst.join(entry.file_name());
21-
#[cfg(windows)]
22-
{
23-
use std::os::windows::fs::FileTypeExt;
24-
if ty.is_symlink_dir() {
25-
std::os::windows::fs::symlink_dir(&target_path, new_symlink_path)?;
26-
} else {
27-
// Target may be a file or another symlink, in any case we can use
28-
// `symlink_file` here.
29-
std::os::windows::fs::symlink_file(&target_path, new_symlink_path)?;
30-
}
31-
}
32-
#[cfg(unix)]
33-
{
34-
std::os::unix::fs::symlink(target_path, new_symlink_path)?;
35-
}
36-
#[cfg(not(any(windows, unix)))]
37-
{
38-
// Technically there's also wasi, but I have no clue about wasi symlink
39-
// semantics and which wasi targets / environment support symlinks.
40-
unimplemented!("unsupported target");
41-
}
57+
copy_symlink_raw(entry.path(), dst.join(entry.file_name()))?;
4258
} else {
4359
std::fs::copy(entry.path(), dst.join(entry.file_name()))?;
4460
}

0 commit comments

Comments
 (0)