Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 3b388eb

Browse files
committed
run_make_support: extract copy_symlink helper
1 parent b22856d commit 3b388eb

File tree

1 file changed

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

1 file changed

+44
-26
lines changed

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

Lines changed: 44 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,49 @@
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(ty: FileType, 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+
let _ = ty;
33+
std::os::unix::fs::symlink(target_path, new_symlink_path)?;
34+
}
35+
#[cfg(not(any(windows, unix)))]
36+
{
37+
let _ = ty;
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+
}
42+
Ok(())
43+
}
44+
45+
/// Copy a directory into another. This will not traverse symlinks; instead, it will create new
46+
/// symlinks pointing at target paths that symlinks in the original directory points to.
547
pub fn copy_dir_all(src: impl AsRef<Path>, dst: impl AsRef<Path>) {
648
fn copy_dir_all_inner(src: impl AsRef<Path>, dst: impl AsRef<Path>) -> io::Result<()> {
749
let dst = dst.as_ref();
@@ -14,31 +56,7 @@ pub fn copy_dir_all(src: impl AsRef<Path>, dst: impl AsRef<Path>) {
1456
if ty.is_dir() {
1557
copy_dir_all_inner(entry.path(), dst.join(entry.file_name()))?;
1658
} 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-
}
59+
copy_symlink_raw(entry.path(), dst.join(entry.file_name()))?;
4260
} else {
4361
std::fs::copy(entry.path(), dst.join(entry.file_name()))?;
4462
}

0 commit comments

Comments
 (0)