From bba85093e149888b8c15f2c8109507abfd467cf9 Mon Sep 17 00:00:00 2001 From: Jieyou Xu Date: Sun, 22 Dec 2024 23:41:03 +0800 Subject: [PATCH] run-make-support: re-export `recursive_remove` This facade is like other `run_make_support::fs` APIs that panic-on-failure but includes the path that the operation was called on in the panic message. --- src/tools/run-make-support/src/fs.rs | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/src/tools/run-make-support/src/fs.rs b/src/tools/run-make-support/src/fs.rs index 9345364e228b..95c0cc50dcf7 100644 --- a/src/tools/run-make-support/src/fs.rs +++ b/src/tools/run-make-support/src/fs.rs @@ -1,3 +1,4 @@ +use std::fs::FileType; use std::io; use std::path::{Path, PathBuf}; @@ -6,12 +7,13 @@ use std::path::{Path, PathBuf}; pub fn copy_symlink(src: impl AsRef, dst: impl AsRef) { let src = src.as_ref(); let dst = dst.as_ref(); - if let Err(e) = copy_symlink_raw(src, dst) { + let metadata = symlink_metadata(src); + if let Err(e) = copy_symlink_raw(metadata.file_type(), src, dst) { panic!("failed to copy symlink from `{}` to `{}`: {e}", src.display(), dst.display(),); } } -fn copy_symlink_raw(src: impl AsRef, dst: impl AsRef) -> io::Result<()> { +fn copy_symlink_raw(ty: FileType, src: impl AsRef, dst: impl AsRef) -> io::Result<()> { // Traverse symlink once to find path of target entity. let target_path = std::fs::read_link(src)?; @@ -54,7 +56,7 @@ pub fn copy_dir_all(src: impl AsRef, dst: impl AsRef) { if ty.is_dir() { copy_dir_all_inner(entry.path(), dst.join(entry.file_name()))?; } else if ty.is_symlink() { - copy_symlink_raw(entry.path(), dst.join(entry.file_name()))?; + copy_symlink_raw(ty, entry.path(), dst.join(entry.file_name()))?; } else { std::fs::copy(entry.path(), dst.join(entry.file_name()))?; } @@ -80,6 +82,21 @@ pub fn read_dir_entries, F: FnMut(&Path)>(dir: P, mut callback: F } } +/// A wrapper around [`build_helper::fs::recursive_remove`] which includes the file path in the +/// panic message. +/// +/// This handles removing symlinks on Windows (e.g. symlink-to-file will be removed via +/// [`std::fs::remove_file`] while symlink-to-dir will be removed via [`std::fs::remove_dir`]). +#[track_caller] +pub fn recursive_remove>(path: P) { + if let Err(e) = build_helper::fs::recursive_remove(path.as_ref()) { + panic!( + "failed to recursive remove filesystem entities at `{}`: {e}", + path.as_ref().display() + ); + } +} + /// A wrapper around [`std::fs::remove_file`] which includes the file path in the panic message. #[track_caller] pub fn remove_file>(path: P) {