From 7147925bedab3b5078f4b05a08bf47573443257e Mon Sep 17 00:00:00 2001 From: sapphi-red <49056869+sapphi-red@users.noreply.github.com> Date: Tue, 12 Nov 2024 10:39:51 +0900 Subject: [PATCH 1/8] fix: use same UNC path normalization logic with libuv --- Cargo.lock | 7 ---- Cargo.toml | 1 - fixtures/pnpm/longfilename/index.js | 3 ++ fixtures/pnpm/longfilename/package.json | 7 ++++ fixtures/pnpm/package.json | 1 + pnpm-lock.yaml | 8 +++++ src/file_system.rs | 43 ++++++++++++++++++++++--- tests/resolve_test.rs | 10 ++++++ 8 files changed, 67 insertions(+), 13 deletions(-) create mode 100644 fixtures/pnpm/longfilename/index.js create mode 100644 fixtures/pnpm/longfilename/package.json diff --git a/Cargo.lock b/Cargo.lock index cc9ac699..41419914 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -340,12 +340,6 @@ dependencies = [ "litrs", ] -[[package]] -name = "dunce" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" - [[package]] name = "either" version = "1.13.0" @@ -688,7 +682,6 @@ dependencies = [ "criterion2", "dashmap", "document-features", - "dunce", "indexmap 2.6.0", "json-strip-comments", "normalize-path", diff --git a/Cargo.toml b/Cargo.toml index 182640a1..56984336 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -70,7 +70,6 @@ serde_json = { version = "1", features = [ "preserve_order", ] } # preserve_order: package_json.exports requires order such as `["require", "import", "default"]` rustc-hash = { version = "2" } -dunce = "1" # Normalize Windows paths to the most compatible format, avoiding UNC where possible once_cell = "1" # Use `std::sync::OnceLock::get_or_try_init` when it is stable. thiserror = "1" json-strip-comments = "1" diff --git a/fixtures/pnpm/longfilename/index.js b/fixtures/pnpm/longfilename/index.js new file mode 100644 index 00000000..7f0f7ce6 --- /dev/null +++ b/fixtures/pnpm/longfilename/index.js @@ -0,0 +1,3 @@ +const test = 'hello world' + +export default test diff --git a/fixtures/pnpm/longfilename/package.json b/fixtures/pnpm/longfilename/package.json new file mode 100644 index 00000000..21b5e76f --- /dev/null +++ b/fixtures/pnpm/longfilename/package.json @@ -0,0 +1,7 @@ +{ + "name": "@oxc-resolver/test-longfilename-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "private": true, + "version": "0.0.0", + "main": "index.js", + "type": "module" +} diff --git a/fixtures/pnpm/package.json b/fixtures/pnpm/package.json index 12fd900b..577d8a3c 100644 --- a/fixtures/pnpm/package.json +++ b/fixtures/pnpm/package.json @@ -3,6 +3,7 @@ "version": "1.0.0", "private": true, "devDependencies": { + "@oxc-resolver/test-longfilename-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa": "file:./longfilename", "axios": "1.6.2", "ipaddr.js": "2.2.0", "postcss": "8.4.33", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e6f5501b..30d0e6f6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -29,6 +29,9 @@ importers: fixtures/pnpm: devDependencies: + '@oxc-resolver/test-longfilename-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa': + specifier: file:./longfilename + version: file:fixtures/pnpm/longfilename axios: specifier: 1.6.2 version: 1.6.2 @@ -546,6 +549,9 @@ packages: '@octokit/types@13.6.1': resolution: {integrity: sha512-PHZE9Z+kWXb23Ndik8MKPirBPziOc0D2/3KH1P+6jK5nGWe96kadZuE4jev2/Jq7FvIfTlT2Ltg8Fv2x1v0a5g==} + '@oxc-resolver/test-longfilename-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa@file:fixtures/pnpm/longfilename': + resolution: {directory: fixtures/pnpm/longfilename, type: directory} + '@rollup/pluginutils@4.2.1': resolution: {integrity: sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==} engines: {node: '>= 8.0.0'} @@ -1907,6 +1913,8 @@ snapshots: dependencies: '@octokit/openapi-types': 22.2.0 + '@oxc-resolver/test-longfilename-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa@file:fixtures/pnpm/longfilename': {} + '@rollup/pluginutils@4.2.1': dependencies: estree-walker: 2.0.2 diff --git a/src/file_system.rs b/src/file_system.rs index 0ba7da73..0f7f2911 100644 --- a/src/file_system.rs +++ b/src/file_system.rs @@ -1,12 +1,17 @@ use std::{ fs, io, - path::{Path, PathBuf}, + path::{Component, Path, PathBuf, Prefix}, }; use cfg_if::cfg_if; #[cfg(feature = "yarn_pnp")] use pnp::fs::{LruZipCache, VPath, VPathInfo, ZipCache}; +#[cfg(windows)] +const UNC_PATH_PREFIX: &str = "\\\\?\\UNC\\"; +#[cfg(windows)] +const LONG_PATH_PREFIX: &str = "\\\\?\\"; + /// File System abstraction used for `ResolverGeneric` pub trait FileSystem: Send + Sync { /// See [std::fs::read_to_string] @@ -165,13 +170,13 @@ impl FileSystem for FileSystemOs { if #[cfg(feature = "yarn_pnp")] { match VPath::from(path)? { VPath::Zip(info) => { - dunce::canonicalize(info.physical_base_path().join(info.zip_path)) + node_compatible_raw_canonicalize(info.physical_base_path().join(info.zip_path)) } - VPath::Virtual(info) => dunce::canonicalize(info.physical_base_path()), - VPath::Native(path) => dunce::canonicalize(path), + VPath::Virtual(info) => node_compatible_raw_canonicalize(info.physical_base_path()), + VPath::Native(path) => node_compatible_raw_canonicalize(path), } } else if #[cfg(windows)] { - dunce::canonicalize(path) + node_compatible_raw_canonicalize(path) } else { use std::path::Component; let mut path_buf = path.to_path_buf(); @@ -227,3 +232,31 @@ fn metadata() { ); let _ = meta; } + +fn node_compatible_raw_canonicalize>(path: P) -> io::Result { + cfg_if! { + if #[cfg(windows)] { + // same logic with https://github.com/libuv/libuv/blob/d4ab6fbba4669935a6bc23645372dfe4ac29ab39/src/win/fs.c#L2774-L2784 + let canonicalized = fs::canonicalize(path)?; + let first_component = canonicalized.components().next(); + match first_component { + Some(Component::Prefix(prefix)) => { + match prefix.kind() { + Prefix::VerbatimUNC(_, _) => { + Ok(canonicalized.to_str().and_then(|s| s.get(UNC_PATH_PREFIX.len()..)).map(PathBuf::from).unwrap_or(canonicalized)) + } + Prefix::VerbatimDisk(_) => { + Ok(canonicalized.to_str().and_then(|s| s.get(LONG_PATH_PREFIX.len()..)).map(PathBuf::from).unwrap_or(canonicalized)) + } + _ => { + Ok(canonicalized) + } + } + } + _ => Ok(canonicalized), + } + } else { + fs::canonicalize(path) + } + } +} diff --git a/tests/resolve_test.rs b/tests/resolve_test.rs index 3c250569..8b4341d1 100644 --- a/tests/resolve_test.rs +++ b/tests/resolve_test.rs @@ -205,3 +205,13 @@ fn nested_symlinks() { Ok(dir.join("nm/index.js")) ); } + +#[test] +fn windows_symlinked_longfilename() { + let dir = dir(); + let path = dir.join("fixtures/pnpm"); + let module_path = dir.join("node_modules/.pnpm/@oxc-resolver+test-longfilename-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_m464apeldykmdsyzlfhtrggk24/node_modules/@oxc-resolver/test-longfilename-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/index.js"); + + let resolution = Resolver::new(ResolveOptions::default()).resolve(&path, "@oxc-resolver/test-longfilename-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa").map(|r| r.full_path()); + assert_eq!(resolution, Ok(module_path)); +} From babda968deea9675db068d2924d12567caa6f9b3 Mon Sep 17 00:00:00 2001 From: sapphi-red <49056869+sapphi-red@users.noreply.github.com> Date: Tue, 12 Nov 2024 11:43:45 +0900 Subject: [PATCH 2/8] chore: fix clippy --- src/file_system.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/file_system.rs b/src/file_system.rs index 0f7f2911..eda3bcad 100644 --- a/src/file_system.rs +++ b/src/file_system.rs @@ -1,6 +1,6 @@ use std::{ fs, io, - path::{Component, Path, PathBuf, Prefix}, + path::{Path, PathBuf}, }; use cfg_if::cfg_if; @@ -236,6 +236,7 @@ fn metadata() { fn node_compatible_raw_canonicalize>(path: P) -> io::Result { cfg_if! { if #[cfg(windows)] { + use std::path::{Component, Prefix}; // same logic with https://github.com/libuv/libuv/blob/d4ab6fbba4669935a6bc23645372dfe4ac29ab39/src/win/fs.c#L2774-L2784 let canonicalized = fs::canonicalize(path)?; let first_component = canonicalized.components().next(); From ec3ccec0928345c866c47e6fddec23d098426772 Mon Sep 17 00:00:00 2001 From: LongYinan Date: Tue, 12 Nov 2024 15:48:52 -0800 Subject: [PATCH 3/8] perf: reduce the number of syscalls on Windows --- Cargo.toml | 2 +- src/file_system.rs | 149 ++++++++++++++++++++++++--------------------- 2 files changed, 79 insertions(+), 72 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 56984336..c1b1ec07 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,7 +14,7 @@ keywords = ["node", "resolve", "cjs", "esm", "enhanced-resolve"] license = "MIT" readme = "README.md" repository = "https://github.com/oxc-project/oxc-resolver" -rust-version = "1.70" +rust-version = "1.74" include = ["/src", "/examples", "/benches"] [lib] diff --git a/src/file_system.rs b/src/file_system.rs index eda3bcad..bdf09f62 100644 --- a/src/file_system.rs +++ b/src/file_system.rs @@ -8,9 +8,9 @@ use cfg_if::cfg_if; use pnp::fs::{LruZipCache, VPath, VPathInfo, ZipCache}; #[cfg(windows)] -const UNC_PATH_PREFIX: &str = "\\\\?\\UNC\\"; +const UNC_PATH_PREFIX: &[u8] = b"\\\\?\\UNC\\"; #[cfg(windows)] -const LONG_PATH_PREFIX: &str = "\\\\?\\"; +const LONG_PATH_PREFIX: &[u8] = b"\\\\?\\"; /// File System abstraction used for `ResolverGeneric` pub trait FileSystem: Send + Sync { @@ -169,55 +169,12 @@ impl FileSystem for FileSystemOs { cfg_if! { if #[cfg(feature = "yarn_pnp")] { match VPath::from(path)? { - VPath::Zip(info) => { - node_compatible_raw_canonicalize(info.physical_base_path().join(info.zip_path)) - } - VPath::Virtual(info) => node_compatible_raw_canonicalize(info.physical_base_path()), - VPath::Native(path) => node_compatible_raw_canonicalize(path), + VPath::Zip(info) => fast_canonicalize(info.physical_base_path().join(info.zip_path)), + VPath::Virtual(info) => fast_canonicalize(info.physical_base_path()), + VPath::Native(path) => fast_canonicalize(path), } - } else if #[cfg(windows)] { - node_compatible_raw_canonicalize(path) } else { - use std::path::Component; - let mut path_buf = path.to_path_buf(); - loop { - let link = fs::read_link(&path_buf)?; - path_buf.pop(); - if fs::symlink_metadata(&path_buf)?.is_symlink() - { - path_buf = self.canonicalize(path_buf.as_path())?; - } - for component in link.components() { - match component { - Component::ParentDir => { - path_buf.pop(); - } - Component::Normal(seg) => { - #[cfg(target_family = "wasm")] - { - // Need to trim the extra \0 introduces by https://github.com/nodejs/uvwasi/issues/262 - path_buf.push(seg.to_string_lossy().trim_end_matches('\0')); - } - #[cfg(not(target_family = "wasm"))] - { - path_buf.push(seg); - } - } - Component::RootDir => { - path_buf = PathBuf::from("/"); - } - Component::CurDir | Component::Prefix(_) => {} - } - if fs::symlink_metadata(&path_buf)?.is_symlink() - { - path_buf = self.canonicalize(path_buf.as_path())?; - } - } - if !fs::symlink_metadata(&path_buf)?.is_symlink() { - break; - } - } - Ok(path_buf) + fast_canonicalize(path) } } } @@ -233,31 +190,81 @@ fn metadata() { let _ = meta; } -fn node_compatible_raw_canonicalize>(path: P) -> io::Result { - cfg_if! { - if #[cfg(windows)] { - use std::path::{Component, Prefix}; - // same logic with https://github.com/libuv/libuv/blob/d4ab6fbba4669935a6bc23645372dfe4ac29ab39/src/win/fs.c#L2774-L2784 - let canonicalized = fs::canonicalize(path)?; - let first_component = canonicalized.components().next(); - match first_component { - Some(Component::Prefix(prefix)) => { - match prefix.kind() { - Prefix::VerbatimUNC(_, _) => { - Ok(canonicalized.to_str().and_then(|s| s.get(UNC_PATH_PREFIX.len()..)).map(PathBuf::from).unwrap_or(canonicalized)) - } - Prefix::VerbatimDisk(_) => { - Ok(canonicalized.to_str().and_then(|s| s.get(LONG_PATH_PREFIX.len()..)).map(PathBuf::from).unwrap_or(canonicalized)) - } - _ => { - Ok(canonicalized) - } +#[inline] +// This is A faster fs::canonicalize implementation by reducing the number of syscalls +fn fast_canonicalize(path: &Path) -> io::Result { + use std::path::Component; + let mut path_buf = path.to_path_buf(); + + loop { + let link = { + #[cfg(windows)] + { + node_compatible_raw_canonicalize(fs::read_link(&path_buf)?) + } + #[cfg(not(windows))] + { + fs::read_link(&path_buf)? + } + }; + path_buf.pop(); + if fs::symlink_metadata(&path_buf)?.is_symlink() { + path_buf = fast_canonicalize(path_buf.as_path())?; + } + for component in link.components() { + match component { + Component::ParentDir => { + path_buf.pop(); + } + Component::Normal(seg) => { + #[cfg(target_family = "wasm")] + { + // Need to trim the extra \0 introduces by https://github.com/nodejs/uvwasi/issues/262 + path_buf.push(seg.to_string_lossy().trim_end_matches('\0')); + } + #[cfg(not(target_family = "wasm"))] + { + path_buf.push(seg); + } + } + Component::RootDir => { + #[cfg(not(windows))] + { + path_buf = PathBuf::from("/"); + } + #[cfg(windows)] + { + path_buf.push(""); } } - _ => Ok(canonicalized), + Component::Prefix(prefix) => { + path_buf = PathBuf::from(prefix.as_os_str()); + } + Component::CurDir => {} + } + + if fs::symlink_metadata(&path_buf)?.is_symlink() { + path_buf = fast_canonicalize(path_buf.as_path())?; } - } else { - fs::canonicalize(path) + } + if !fs::symlink_metadata(&path_buf)?.is_symlink() { + break; } } + Ok(path_buf) +} + +#[cfg(windows)] +fn node_compatible_raw_canonicalize>(path: P) -> PathBuf { + let path_bytes = path.as_ref().as_os_str().as_encoded_bytes(); + path_bytes + .strip_prefix(UNC_PATH_PREFIX) + .or_else(|| path_bytes.strip_prefix(LONG_PATH_PREFIX)) + .map_or_else( + || path.as_ref().to_path_buf(), + |p| { + // SAFETY: `as_encoded_bytes` ensures `p` is valid path bytes + unsafe { PathBuf::from(std::ffi::OsStr::from_encoded_bytes_unchecked(p)) } + }, + ) } From 049fa92864cf8457afc2729e6a1b26409dfea969 Mon Sep 17 00:00:00 2001 From: sapphi-red <49056869+sapphi-red@users.noreply.github.com> Date: Wed, 13 Nov 2024 10:33:28 +0900 Subject: [PATCH 4/8] fix: fix types --- src/file_system.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/file_system.rs b/src/file_system.rs index bdf09f62..a25e6635 100644 --- a/src/file_system.rs +++ b/src/file_system.rs @@ -171,10 +171,10 @@ impl FileSystem for FileSystemOs { match VPath::from(path)? { VPath::Zip(info) => fast_canonicalize(info.physical_base_path().join(info.zip_path)), VPath::Virtual(info) => fast_canonicalize(info.physical_base_path()), - VPath::Native(path) => fast_canonicalize(path), + VPath::Native(path) => fast_canonicalize(path.to_path_buf()), } } else { - fast_canonicalize(path) + fast_canonicalize(path.to_path_buf()) } } } @@ -192,9 +192,9 @@ fn metadata() { #[inline] // This is A faster fs::canonicalize implementation by reducing the number of syscalls -fn fast_canonicalize(path: &Path) -> io::Result { +fn fast_canonicalize(path: PathBuf) -> io::Result { use std::path::Component; - let mut path_buf = path.to_path_buf(); + let mut path_buf = path; loop { let link = { @@ -209,7 +209,7 @@ fn fast_canonicalize(path: &Path) -> io::Result { }; path_buf.pop(); if fs::symlink_metadata(&path_buf)?.is_symlink() { - path_buf = fast_canonicalize(path_buf.as_path())?; + path_buf = fast_canonicalize(path_buf)?; } for component in link.components() { match component { @@ -244,7 +244,7 @@ fn fast_canonicalize(path: &Path) -> io::Result { } if fs::symlink_metadata(&path_buf)?.is_symlink() { - path_buf = fast_canonicalize(path_buf.as_path())?; + path_buf = fast_canonicalize(path_buf)?; } } if !fs::symlink_metadata(&path_buf)?.is_symlink() { From 50871028c48e9eed300d44a359b4fe63d9b5bc04 Mon Sep 17 00:00:00 2001 From: sapphi-red <49056869+sapphi-red@users.noreply.github.com> Date: Wed, 13 Nov 2024 10:36:48 +0900 Subject: [PATCH 5/8] fix: fix clippy --- src/file_system.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/file_system.rs b/src/file_system.rs index a25e6635..175a73cc 100644 --- a/src/file_system.rs +++ b/src/file_system.rs @@ -171,7 +171,7 @@ impl FileSystem for FileSystemOs { match VPath::from(path)? { VPath::Zip(info) => fast_canonicalize(info.physical_base_path().join(info.zip_path)), VPath::Virtual(info) => fast_canonicalize(info.physical_base_path()), - VPath::Native(path) => fast_canonicalize(path.to_path_buf()), + VPath::Native(path) => fast_canonicalize(path), } } else { fast_canonicalize(path.to_path_buf()) From e18ff561d13c83e738d670d4707f564b919bd4d8 Mon Sep 17 00:00:00 2001 From: LongYinan Date: Wed, 13 Nov 2024 09:40:17 +0800 Subject: [PATCH 6/8] Update src/file_system.rs --- src/file_system.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/file_system.rs b/src/file_system.rs index 175a73cc..ccf6a433 100644 --- a/src/file_system.rs +++ b/src/file_system.rs @@ -234,7 +234,7 @@ fn fast_canonicalize(path: PathBuf) -> io::Result { } #[cfg(windows)] { - path_buf.push(""); + path_buf.push("\\"); } } Component::Prefix(prefix) => { From 4f225380c888111798a550d831c5e6a1afb61f6f Mon Sep 17 00:00:00 2001 From: sapphi-red <49056869+sapphi-red@users.noreply.github.com> Date: Wed, 13 Nov 2024 13:57:53 +0900 Subject: [PATCH 7/8] perf: use `fs::canonicalize` for Windows --- src/file_system.rs | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/file_system.rs b/src/file_system.rs index ccf6a433..b0317ca1 100644 --- a/src/file_system.rs +++ b/src/file_system.rs @@ -174,7 +174,7 @@ impl FileSystem for FileSystemOs { VPath::Native(path) => fast_canonicalize(path), } } else { - fast_canonicalize(path.to_path_buf()) + fast_canonicalize(path) } } } @@ -191,8 +191,22 @@ fn metadata() { } #[inline] +fn fast_canonicalize>(path: P) -> io::Result { + #[cfg(windows)] + { + // fs::canonicalize was faster on Windows (https://github.com/oxc-project/oxc-resolver/pull/306) + Ok(node_compatible_raw_canonicalize(fs::canonicalize(path)?)) + } + #[cfg(not(windows))] + { + fast_canonicalize_non_windows(path.as_ref().to_path_buf()) + } +} + +#[inline] +#[cfg(not(windows))] // This is A faster fs::canonicalize implementation by reducing the number of syscalls -fn fast_canonicalize(path: PathBuf) -> io::Result { +fn fast_canonicalize_non_windows(path: PathBuf) -> io::Result { use std::path::Component; let mut path_buf = path; From c8e2b090ccc717b613e0b36c17745eb383742fe6 Mon Sep 17 00:00:00 2001 From: sapphi-red <49056869+sapphi-red@users.noreply.github.com> Date: Wed, 13 Nov 2024 13:59:31 +0900 Subject: [PATCH 8/8] refactor: remove windows only logic from `fast_canonicalize_non_windows` --- src/file_system.rs | 25 +++---------------------- 1 file changed, 3 insertions(+), 22 deletions(-) diff --git a/src/file_system.rs b/src/file_system.rs index b0317ca1..cb1bfdf5 100644 --- a/src/file_system.rs +++ b/src/file_system.rs @@ -211,16 +211,7 @@ fn fast_canonicalize_non_windows(path: PathBuf) -> io::Result { let mut path_buf = path; loop { - let link = { - #[cfg(windows)] - { - node_compatible_raw_canonicalize(fs::read_link(&path_buf)?) - } - #[cfg(not(windows))] - { - fs::read_link(&path_buf)? - } - }; + let link = fs::read_link(&path_buf)?; path_buf.pop(); if fs::symlink_metadata(&path_buf)?.is_symlink() { path_buf = fast_canonicalize(path_buf)?; @@ -242,19 +233,9 @@ fn fast_canonicalize_non_windows(path: PathBuf) -> io::Result { } } Component::RootDir => { - #[cfg(not(windows))] - { - path_buf = PathBuf::from("/"); - } - #[cfg(windows)] - { - path_buf.push("\\"); - } - } - Component::Prefix(prefix) => { - path_buf = PathBuf::from(prefix.as_os_str()); + path_buf = PathBuf::from("/"); } - Component::CurDir => {} + Component::CurDir | Component::Prefix(_) => {} } if fs::symlink_metadata(&path_buf)?.is_symlink() {