fix: symlinks
This commit is contained in:
parent
54980fa73a
commit
5d8db4abf7
1 changed files with 47 additions and 2 deletions
|
|
@ -620,6 +620,10 @@ pub async fn symlink_metadata(path: impl AsRef<std::path::Path>) -> PolyIOResult
|
|||
})
|
||||
}
|
||||
|
||||
fn resolved_target(original: &std::path::Path) -> PathBuf {
|
||||
crate::canonicalize(original).unwrap_or_else(|_| original.to_path_buf())
|
||||
}
|
||||
|
||||
/// Symlink on Unix hard link on Windows so both paths must be on one volume
|
||||
#[tracing::instrument(
|
||||
level = "debug",
|
||||
|
|
@ -633,7 +637,8 @@ pub async fn symlink_file(
|
|||
original: impl AsRef<std::path::Path>,
|
||||
link: impl AsRef<std::path::Path>,
|
||||
) -> PolyIOResult<()> {
|
||||
let original = original.as_ref();
|
||||
let original = resolved_target(original.as_ref());
|
||||
let original = original.as_path();
|
||||
let link = link.as_ref();
|
||||
|
||||
#[cfg(windows)]
|
||||
|
|
@ -723,7 +728,8 @@ pub async fn symlink_dir(
|
|||
original: impl AsRef<std::path::Path>,
|
||||
link: impl AsRef<std::path::Path>,
|
||||
) -> PolyIOResult<()> {
|
||||
let original = original.as_ref();
|
||||
let original = resolved_target(original.as_ref());
|
||||
let original = original.as_path();
|
||||
let link = link.as_ref();
|
||||
|
||||
#[cfg(windows)]
|
||||
|
|
@ -846,6 +852,45 @@ mod tests {
|
|||
assert_eq!(write_buffer_size(Some(0)), DEFAULT_WRITE_BUFFER);
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
#[tokio::test]
|
||||
async fn a_link_target_is_stored_resolved() {
|
||||
let root = scratch("resolved-target");
|
||||
let real = root.join("var").join("home");
|
||||
std::fs::create_dir_all(&real).unwrap();
|
||||
std::os::unix::fs::symlink(&real, root.join("home")).unwrap();
|
||||
|
||||
let pack = real.join("pack.zip");
|
||||
std::fs::write(&pack, b"pack").unwrap();
|
||||
|
||||
let through_link = root.join("home").join("pack.zip");
|
||||
let link = root.join("resourcepacks.zip");
|
||||
|
||||
symlink_file(&through_link, &link).await.unwrap();
|
||||
|
||||
assert_eq!(
|
||||
read_link(&link).await.unwrap(),
|
||||
crate::canonicalize(&pack).unwrap(),
|
||||
"the stored target must be the resolved path, not the spelling we were given"
|
||||
);
|
||||
|
||||
std::fs::remove_dir_all(&root).ok();
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
#[tokio::test]
|
||||
async fn a_missing_target_is_stored_as_given() {
|
||||
let root = scratch("unresolved-target");
|
||||
let missing = root.join("not-here.zip");
|
||||
let link = root.join("link.zip");
|
||||
|
||||
symlink_file(&missing, &link).await.unwrap();
|
||||
|
||||
assert_eq!(read_link(&link).await.unwrap(), missing);
|
||||
|
||||
std::fs::remove_dir_all(&root).ok();
|
||||
}
|
||||
|
||||
fn scratch(tag: &str) -> PathBuf {
|
||||
static N: AtomicU64 = AtomicU64::new(0);
|
||||
let dir = std::env::temp_dir().join(format!(
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue