run_make_support: extract copy_symlink
helper
This commit is contained in:
parent
b22856d192
commit
3b388eb9b6
1 changed files with 44 additions and 26 deletions
|
@ -1,7 +1,49 @@
|
|||
use std::io;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
/// Copy a directory into another.
|
||||
/// Given a symlink at `src`, read its target, then create a new symlink at `dst` also pointing to
|
||||
/// target.
|
||||
pub fn copy_symlink(src: impl AsRef<Path>, dst: impl AsRef<Path>) {
|
||||
let src = src.as_ref();
|
||||
let dst = dst.as_ref();
|
||||
if let Err(e) = copy_symlink_raw(src, dst) {
|
||||
panic!("failed to copy symlink from `{}` to `{}`: {e}", src.display(), dst.display(),);
|
||||
}
|
||||
}
|
||||
|
||||
fn copy_symlink_raw(ty: FileType, src: impl AsRef<Path>, dst: impl AsRef<Path>) -> io::Result<()> {
|
||||
// Traverse symlink once to find path of target entity.
|
||||
let target_path = std::fs::read_link(src)?;
|
||||
|
||||
let new_symlink_path = dst.as_ref();
|
||||
#[cfg(windows)]
|
||||
{
|
||||
use std::os::windows::fs::FileTypeExt;
|
||||
if ty.is_symlink_dir() {
|
||||
std::os::windows::fs::symlink_dir(&target_path, new_symlink_path)?;
|
||||
} else {
|
||||
// Target may be a file or another symlink, in any case we can use
|
||||
// `symlink_file` here.
|
||||
std::os::windows::fs::symlink_file(&target_path, new_symlink_path)?;
|
||||
}
|
||||
}
|
||||
#[cfg(unix)]
|
||||
{
|
||||
let _ = ty;
|
||||
std::os::unix::fs::symlink(target_path, new_symlink_path)?;
|
||||
}
|
||||
#[cfg(not(any(windows, unix)))]
|
||||
{
|
||||
let _ = ty;
|
||||
// Technically there's also wasi, but I have no clue about wasi symlink
|
||||
// semantics and which wasi targets / environment support symlinks.
|
||||
unimplemented!("unsupported target");
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Copy a directory into another. This will not traverse symlinks; instead, it will create new
|
||||
/// symlinks pointing at target paths that symlinks in the original directory points to.
|
||||
pub fn copy_dir_all(src: impl AsRef<Path>, dst: impl AsRef<Path>) {
|
||||
fn copy_dir_all_inner(src: impl AsRef<Path>, dst: impl AsRef<Path>) -> io::Result<()> {
|
||||
let dst = dst.as_ref();
|
||||
|
@ -14,31 +56,7 @@ pub fn copy_dir_all(src: impl AsRef<Path>, dst: impl AsRef<Path>) {
|
|||
if ty.is_dir() {
|
||||
copy_dir_all_inner(entry.path(), dst.join(entry.file_name()))?;
|
||||
} else if ty.is_symlink() {
|
||||
// Traverse symlink once to find path of target entity.
|
||||
let target_path = std::fs::read_link(entry.path())?;
|
||||
|
||||
let new_symlink_path = dst.join(entry.file_name());
|
||||
#[cfg(windows)]
|
||||
{
|
||||
use std::os::windows::fs::FileTypeExt;
|
||||
if ty.is_symlink_dir() {
|
||||
std::os::windows::fs::symlink_dir(&target_path, new_symlink_path)?;
|
||||
} else {
|
||||
// Target may be a file or another symlink, in any case we can use
|
||||
// `symlink_file` here.
|
||||
std::os::windows::fs::symlink_file(&target_path, new_symlink_path)?;
|
||||
}
|
||||
}
|
||||
#[cfg(unix)]
|
||||
{
|
||||
std::os::unix::fs::symlink(target_path, new_symlink_path)?;
|
||||
}
|
||||
#[cfg(not(any(windows, unix)))]
|
||||
{
|
||||
// Technically there's also wasi, but I have no clue about wasi symlink
|
||||
// semantics and which wasi targets / environment support symlinks.
|
||||
unimplemented!("unsupported target");
|
||||
}
|
||||
copy_symlink_raw(entry.path(), dst.join(entry.file_name()))?;
|
||||
} else {
|
||||
std::fs::copy(entry.path(), dst.join(entry.file_name()))?;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue