diff options
author | David Sherret <dsherret@users.noreply.github.com> | 2024-09-28 19:17:48 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-09-28 19:17:48 -0400 |
commit | 5faf769ac61b627d14710cdf487de7cd4eb3f9d3 (patch) | |
tree | 2cc4ab975522b3c8845ab3040c010fd998a769a6 /ext/node_resolver/path.rs | |
parent | 3138478f66823348eb745c7f0c2d34eed378a3f0 (diff) |
refactor: extract out sloppy imports resolution from CLI crate (#25920)
This is slow progress towards creating a `deno_resolver` crate.
Waiting on:
* https://github.com/denoland/deno/pull/25918
* https://github.com/denoland/deno/pull/25916
Diffstat (limited to 'ext/node_resolver/path.rs')
-rw-r--r-- | ext/node_resolver/path.rs | 179 |
1 files changed, 0 insertions, 179 deletions
diff --git a/ext/node_resolver/path.rs b/ext/node_resolver/path.rs deleted file mode 100644 index ece270cd9..000000000 --- a/ext/node_resolver/path.rs +++ /dev/null @@ -1,179 +0,0 @@ -// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. - -use std::path::Component; -use std::path::Path; -use std::path::PathBuf; - -use url::Url; - -/// Extension to path_clean::PathClean -pub trait PathClean<T> { - fn clean(&self) -> T; -} - -impl PathClean<PathBuf> for PathBuf { - fn clean(&self) -> PathBuf { - fn is_clean_path(path: &Path) -> bool { - let path = path.to_string_lossy(); - let mut current_index = 0; - while let Some(index) = path[current_index..].find("\\.") { - let trailing_index = index + current_index + 2; - let mut trailing_chars = path[trailing_index..].chars(); - match trailing_chars.next() { - Some('.') => match trailing_chars.next() { - Some('/') | Some('\\') | None => { - return false; - } - _ => {} - }, - Some('/') | Some('\\') => { - return false; - } - _ => {} - } - current_index = trailing_index; - } - true - } - - let path = path_clean::PathClean::clean(self); - if cfg!(windows) && !is_clean_path(&path) { - // temporary workaround because path_clean::PathClean::clean is - // not good enough on windows - let mut components = Vec::new(); - - for component in path.components() { - match component { - Component::CurDir => { - // skip - } - Component::ParentDir => { - let maybe_last_component = components.pop(); - if !matches!(maybe_last_component, Some(Component::Normal(_))) { - panic!("Error normalizing: {}", path.display()); - } - } - Component::Normal(_) | Component::RootDir | Component::Prefix(_) => { - components.push(component); - } - } - } - components.into_iter().collect::<PathBuf>() - } else { - path - } - } -} - -pub(crate) fn to_file_specifier(path: &Path) -> Url { - match Url::from_file_path(path) { - Ok(url) => url, - Err(_) => panic!("Invalid path: {}", path.display()), - } -} - -// todo(dsherret): we have the below code also in deno_core and it -// would be good to somehow re-use it in both places (we don't want -// to create a dependency on deno_core here) - -#[cfg(not(windows))] -#[inline] -pub fn strip_unc_prefix(path: PathBuf) -> PathBuf { - path -} - -/// Strips the unc prefix (ex. \\?\) from Windows paths. -#[cfg(windows)] -pub fn strip_unc_prefix(path: PathBuf) -> PathBuf { - use std::path::Component; - use std::path::Prefix; - - let mut components = path.components(); - match components.next() { - Some(Component::Prefix(prefix)) => { - match prefix.kind() { - // \\?\device - Prefix::Verbatim(device) => { - let mut path = PathBuf::new(); - path.push(format!(r"\\{}\", device.to_string_lossy())); - path.extend(components.filter(|c| !matches!(c, Component::RootDir))); - path - } - // \\?\c:\path - Prefix::VerbatimDisk(_) => { - let mut path = PathBuf::new(); - path.push(prefix.as_os_str().to_string_lossy().replace(r"\\?\", "")); - path.extend(components); - path - } - // \\?\UNC\hostname\share_name\path - Prefix::VerbatimUNC(hostname, share_name) => { - let mut path = PathBuf::new(); - path.push(format!( - r"\\{}\{}\", - hostname.to_string_lossy(), - share_name.to_string_lossy() - )); - path.extend(components.filter(|c| !matches!(c, Component::RootDir))); - path - } - _ => path, - } - } - _ => path, - } -} - -#[cfg(test)] -mod test { - #[cfg(windows)] - #[test] - fn test_path_clean() { - use super::*; - - run_test("C:\\test\\./file.txt", "C:\\test\\file.txt"); - run_test("C:\\test\\../other/file.txt", "C:\\other\\file.txt"); - run_test("C:\\test\\../other\\file.txt", "C:\\other\\file.txt"); - - fn run_test(input: &str, expected: &str) { - assert_eq!(PathBuf::from(input).clean(), PathBuf::from(expected)); - } - } - - #[cfg(windows)] - #[test] - fn test_strip_unc_prefix() { - use std::path::PathBuf; - - run_test(r"C:\", r"C:\"); - run_test(r"C:\test\file.txt", r"C:\test\file.txt"); - - run_test(r"\\?\C:\", r"C:\"); - run_test(r"\\?\C:\test\file.txt", r"C:\test\file.txt"); - - run_test(r"\\.\C:\", r"\\.\C:\"); - run_test(r"\\.\C:\Test\file.txt", r"\\.\C:\Test\file.txt"); - - run_test(r"\\?\UNC\localhost\", r"\\localhost"); - run_test(r"\\?\UNC\localhost\c$\", r"\\localhost\c$"); - run_test( - r"\\?\UNC\localhost\c$\Windows\file.txt", - r"\\localhost\c$\Windows\file.txt", - ); - run_test(r"\\?\UNC\wsl$\deno.json", r"\\wsl$\deno.json"); - - run_test(r"\\?\server1", r"\\server1"); - run_test(r"\\?\server1\e$\", r"\\server1\e$\"); - run_test( - r"\\?\server1\e$\test\file.txt", - r"\\server1\e$\test\file.txt", - ); - - fn run_test(input: &str, expected: &str) { - assert_eq!( - super::strip_unc_prefix(PathBuf::from(input)), - PathBuf::from(expected) - ); - } - } -} |