Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 11 additions & 0 deletions crates/fsops/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[package]
name = "fsops"
version = "0.1.0"
edition = "2021"

[lib]
name = "fsops"
bench = false

[dependencies]
dunce = "1.0.5"
41 changes: 41 additions & 0 deletions crates/fsops/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
use std::io;
use std::path::{Path, PathBuf};

/// https://github.com/oxc-project/oxc-resolver/blob/42a1e3eb50e9a1365c422c41d51f287fe5fb8244/src/file_system.rs#L93-L122
pub fn canonicalize<P: AsRef<Path>>(path: P) -> io::Result<PathBuf> {
#[cfg(not(target_os = "wasi"))]
{
dunce::canonicalize(path)
}
#[cfg(target_os = "wasi")]
{
canonicalize_wasi(path)
}
}

#[cfg(target_os = "wasi")]
fn canonicalize_wasi<P: AsRef<Path>>(path: P) -> io::Result<PathBuf> {
use std::fs;
let path = path.as_ref();
let meta = fs::symlink_metadata(path)?;
if meta.file_type().is_symlink() {
let link = fs::read_link(path)?;
let mut path_buf = path.to_path_buf();
path_buf.pop();
for segment in link.iter() {
match segment.to_str() {
Some("..") => {
path_buf.pop();
}
Some(".") | None => {}
Some(seg) => {
// Need to trim the extra \0 introduces by rust std rust-lang/rust#123727
path_buf.push(seg.trim_end_matches('\0'));
}
}
}
Ok(path_buf)
} else {
Ok(path.to_path_buf())
}
}
1 change: 1 addition & 0 deletions crates/ignore/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ memchr = "2.6.3"
same-file = "1.0.6"
walkdir = "2.4.0"
dunce = "1.0.5"
fsops = { path = "../fsops" }

[dependencies.regex-automata]
version = "0.4.0"
Expand Down
4 changes: 2 additions & 2 deletions crates/ignore/src/dir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,8 +176,8 @@ impl Ignore {
if !self.is_root() {
panic!("Ignore::add_parents called on non-root matcher");
}
// CHANGED: Use `dunce::canonicalize` as we use it everywhere else.
let absolute_base = match dunce::canonicalize(path.as_ref()) {
// CHANGED: Use `fsops::canonicalize` as we use it everywhere else.
let absolute_base = match fsops::canonicalize(path.as_ref()) {
Ok(path) => Arc::new(path),
Err(_) => {
// There's not much we can do here, so just return our
Expand Down
1 change: 1 addition & 0 deletions crates/oxide/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ fast-glob = "0.4.3"
classification-macros = { path = "../classification-macros" }
ignore = { path = "../ignore" }
regex = "1.11.1"
fsops = { path = "../fsops" }

[dev-dependencies]
tempfile = "3.13.0"
Expand Down
4 changes: 2 additions & 2 deletions crates/oxide/src/glob.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ pub fn hoist_static_glob_parts(entries: &Vec<GlobEntry>, emit_parent_glob: bool)
None => base,
};

let base = match dunce::canonicalize(&base) {
let base = match fsops::canonicalize(&base) {
Ok(base) => base,
Err(err) => {
event!(tracing::Level::ERROR, "Failed to resolve glob: {:?}", err);
Expand Down Expand Up @@ -253,7 +253,7 @@ mod tests {
let optimized_sources = optimize_patterns(&sources);

let parent_dir =
format!("{}{}", dunce::canonicalize(base).unwrap().display(), "/").replace('\\', "/");
format!("{}{}", fsops::canonicalize(base).unwrap().display(), "/").replace('\\', "/");

// Remove the temporary directory from the base
optimized_sources
Expand Down
2 changes: 1 addition & 1 deletion crates/oxide/src/paths.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,6 @@ impl Path {
}

pub fn canonicalize(&self) -> io::Result<Self> {
Ok(dunce::canonicalize(&self.inner)?.into())
Ok(fsops::canonicalize(&self.inner)?.into())
}
}
4 changes: 2 additions & 2 deletions crates/oxide/src/scanner/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ fn init_tracing() {
.unwrap_or_else(|_| panic!("Failed to open {file_path}"));

let file_path = Path::new(&file_path);
let absolute_file_path = dunce::canonicalize(file_path)
let absolute_file_path = fsops::canonicalize(file_path)
.unwrap_or_else(|_| panic!("Failed to canonicalize {file_path:?}"));
eprintln!(
"{} Writing debug info to: {}\n",
Expand Down Expand Up @@ -215,7 +215,7 @@ impl Scanner {
.into_iter()
.filter_map(|changed_content| match changed_content {
ChangedContent::File(file, extension) => {
let Ok(file) = dunce::canonicalize(file) else {
let Ok(file) = fsops::canonicalize(file) else {
return None;
};
Some(ChangedContent::File(file, extension))
Expand Down
6 changes: 3 additions & 3 deletions crates/oxide/src/scanner/sources.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ impl PublicSourceEntry {
/// resolved path.
pub fn optimize(&mut self) {
// Resolve base path immediately
let Ok(base) = dunce::canonicalize(&self.base) else {
let Ok(base) = fsops::canonicalize(&self.base) else {
event!(Level::ERROR, "Failed to resolve base: {:?}", self.base);
return;
};
Expand All @@ -116,7 +116,7 @@ impl PublicSourceEntry {
PathBuf::from(&self.base).join(&self.pattern)
};

match dunce::canonicalize(combined_path) {
match fsops::canonicalize(combined_path) {
Ok(resolved_path) if resolved_path.is_dir() => {
self.base = resolved_path.to_string_lossy().to_string();
self.pattern = "**/*".to_owned();
Expand Down Expand Up @@ -144,7 +144,7 @@ impl PublicSourceEntry {
Some(static_part) => {
// TODO: If the base does not exist on disk, try removing the last slash and try
// again.
match dunce::canonicalize(base.join(static_part)) {
match fsops::canonicalize(base.join(static_part)) {
Ok(base) => base,
Err(err) => {
event!(tracing::Level::ERROR, "Failed to resolve glob: {:?}", err);
Expand Down
2 changes: 1 addition & 1 deletion crates/oxide/tests/scanner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ mod scanner {
let candidates = scanner.scan();

let base_dir =
format!("{}{}", dunce::canonicalize(&base).unwrap().display(), "/").replace('\\', "/");
format!("{}{}", fsops::canonicalize(&base).unwrap().display(), "/").replace('\\', "/");

// Get all scanned files as strings relative to the base directory
let mut files = scanner
Expand Down