From 0bed4d3e5153aaf2e06fb6579ac6f24acf63567f Mon Sep 17 00:00:00 2001 From: Divy Srivastava Date: Sat, 9 Mar 2024 09:07:29 +0530 Subject: [PATCH] fix(ext/node): support junction symlinks on Windows (#22762) Fixes https://github.com/denoland/deno/issues/20609 Vitepress support! `vitepress dev` and `vitepress build` via BYONM --- Cargo.lock | 1 + Cargo.toml | 1 + cli/Cargo.toml | 2 +- ext/fs/Cargo.toml | 1 + ext/fs/interface.rs | 2 ++ ext/fs/std_fs.rs | 3 +++ ext/node/polyfills/_fs/_fs_symlink.ts | 2 +- tests/unit_node/_fs/_fs_symlink_test.ts | 17 +++++++++++++++++ 8 files changed, 27 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7a68504db2..14916df054 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1425,6 +1425,7 @@ dependencies = [ "deno_io", "filetime", "fs3", + "junction", "libc", "log", "nix 0.26.2", diff --git a/Cargo.toml b/Cargo.toml index ed863abdd0..dc7bda38bc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -194,6 +194,7 @@ nix = "=0.26.2" # windows deps fwdansi = "=1.1.0" +junction = "=0.2.0" winapi = "=0.3.9" windows-sys = { version = "0.48.0", features = ["Win32_Media"] } winres = "=0.1.12" diff --git a/cli/Cargo.toml b/cli/Cargo.toml index cb1255d7f3..9a6a8ee57c 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -154,7 +154,7 @@ zstd.workspace = true [target.'cfg(windows)'.dependencies] fwdansi.workspace = true -junction = "=0.2.0" +junction.workspace = true winapi = { workspace = true, features = ["knownfolders", "mswsock", "objbase", "shlobj", "tlhelp32", "winbase", "winerror", "winsock2"] } [target.'cfg(unix)'.dependencies] diff --git a/ext/fs/Cargo.toml b/ext/fs/Cargo.toml index f6f64010ed..b8cccde286 100644 --- a/ext/fs/Cargo.toml +++ b/ext/fs/Cargo.toml @@ -35,3 +35,4 @@ nix.workspace = true [target.'cfg(windows)'.dependencies] winapi = { workspace = true, features = ["winbase"] } +junction.workspace = true diff --git a/ext/fs/interface.rs b/ext/fs/interface.rs index 8ffa614815..c5a348eb11 100644 --- a/ext/fs/interface.rs +++ b/ext/fs/interface.rs @@ -64,6 +64,8 @@ pub enum FsFileType { File, #[serde(rename = "dir")] Directory, + #[serde(rename = "junction")] + Junction, } #[derive(Serialize)] diff --git a/ext/fs/std_fs.rs b/ext/fs/std_fs.rs index c1c9200cb5..332866e457 100644 --- a/ext/fs/std_fs.rs +++ b/ext/fs/std_fs.rs @@ -810,6 +810,9 @@ fn symlink( FsFileType::Directory => { std::os::windows::fs::symlink_dir(oldpath, newpath)?; } + FsFileType::Junction => { + junction::create(oldpath, newpath)?; + } }; Ok(()) diff --git a/ext/node/polyfills/_fs/_fs_symlink.ts b/ext/node/polyfills/_fs/_fs_symlink.ts index 5cb1217557..350263423a 100644 --- a/ext/node/polyfills/_fs/_fs_symlink.ts +++ b/ext/node/polyfills/_fs/_fs_symlink.ts @@ -7,7 +7,7 @@ import { CallbackWithError } from "ext:deno_node/_fs/_fs_common.ts"; import { pathFromURL } from "ext:deno_web/00_infra.js"; import { promisify } from "ext:deno_node/internal/util.mjs"; -type SymlinkType = "file" | "dir"; +type SymlinkType = "file" | "dir" | "junction"; export function symlink( target: string | URL, diff --git a/tests/unit_node/_fs/_fs_symlink_test.ts b/tests/unit_node/_fs/_fs_symlink_test.ts index 68ed1014ac..98cf514608 100644 --- a/tests/unit_node/_fs/_fs_symlink_test.ts +++ b/tests/unit_node/_fs/_fs_symlink_test.ts @@ -105,3 +105,20 @@ Deno.test({ } }, }); + +Deno.test({ + name: "SYNC: symlink junction", + fn() { + const dir: string = Deno.makeTempDirSync(); + const linkedDir: string = dir + "-junction"; + + try { + symlinkSync(dir, linkedDir, "junction"); + const stat = Deno.lstatSync(linkedDir); + assert(stat.isSymlink); + } finally { + Deno.removeSync(dir); + Deno.removeSync(linkedDir); + } + }, +});