Skip to content

Commit 279dd4e

Browse files
committed
Use custom implementation of canonicalize for wasi
1 parent 85575a4 commit 279dd4e

File tree

3 files changed

+43
-6
lines changed

3 files changed

+43
-6
lines changed

crates/oxide/src/scanner/fsops.rs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
use std::io;
2+
use std::path::{Path, PathBuf};
3+
4+
/// https://github.com/oxc-project/oxc-resolver/blob/42a1e3eb50e9a1365c422c41d51f287fe5fb8244/src/file_system.rs#L93-L122
5+
pub fn canonicalize<P: AsRef<Path>>(path: P) -> io::Result<PathBuf> {
6+
#[cfg(not(target_os = "wasi"))]
7+
{
8+
dunce::canonicalize(path)
9+
}
10+
#[cfg(target_os = "wasi")]
11+
{
12+
use std::fs;
13+
let path = path.as_ref();
14+
let meta = fs::symlink_metadata(path)?;
15+
if meta.file_type().is_symlink() {
16+
let link = fs::read_link(path)?;
17+
let mut path_buf = path.to_path_buf();
18+
path_buf.pop();
19+
for segment in link.iter() {
20+
match segment.to_str() {
21+
Some("..") => {
22+
path_buf.pop();
23+
}
24+
Some(".") | None => {}
25+
Some(seg) => {
26+
// Need to trim the extra \0 introduces by rust std rust-lang/rust#123727
27+
path_buf.push(seg.trim_end_matches('\0'));
28+
}
29+
}
30+
}
31+
Ok(path_buf)
32+
} else {
33+
Ok(path.to_path_buf())
34+
}
35+
}
36+
}

crates/oxide/src/scanner/mod.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
pub mod auto_source_detection;
22
pub mod detect_sources;
33
pub mod sources;
4+
mod fsops;
45

56
use crate::extractor::{Extracted, Extractor};
67
use crate::glob::optimize_patterns;
@@ -63,7 +64,7 @@ fn init_tracing() {
6364
.unwrap_or_else(|_| panic!("Failed to open {file_path}"));
6465

6566
let file_path = Path::new(&file_path);
66-
let absolute_file_path = dunce::canonicalize(file_path)
67+
let absolute_file_path = fsops::canonicalize(file_path)
6768
.unwrap_or_else(|_| panic!("Failed to canonicalize {file_path:?}"));
6869
eprintln!(
6970
"{} Writing debug info to: {}\n",
@@ -215,7 +216,7 @@ impl Scanner {
215216
.into_iter()
216217
.filter_map(|changed_content| match changed_content {
217218
ChangedContent::File(file, extension) => {
218-
let Ok(file) = dunce::canonicalize(file) else {
219+
let Ok(file) = fsops::canonicalize(file) else {
219220
return None;
220221
};
221222
Some(ChangedContent::File(file, extension))

crates/oxide/src/scanner/sources.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::glob::split_pattern;
1+
use crate::{glob::split_pattern, scanner::fsops};
22
use crate::GlobEntry;
33
use bexpand::Expression;
44
use std::path::PathBuf;
@@ -102,7 +102,7 @@ impl PublicSourceEntry {
102102
/// resolved path.
103103
pub fn optimize(&mut self) {
104104
// Resolve base path immediately
105-
let Ok(base) = dunce::canonicalize(&self.base) else {
105+
let Ok(base) = fsops::canonicalize(&self.base) else {
106106
event!(Level::ERROR, "Failed to resolve base: {:?}", self.base);
107107
return;
108108
};
@@ -116,7 +116,7 @@ impl PublicSourceEntry {
116116
PathBuf::from(&self.base).join(&self.pattern)
117117
};
118118

119-
match dunce::canonicalize(combined_path) {
119+
match fsops::canonicalize(combined_path) {
120120
Ok(resolved_path) if resolved_path.is_dir() => {
121121
self.base = resolved_path.to_string_lossy().to_string();
122122
self.pattern = "**/*".to_owned();
@@ -144,7 +144,7 @@ impl PublicSourceEntry {
144144
Some(static_part) => {
145145
// TODO: If the base does not exist on disk, try removing the last slash and try
146146
// again.
147-
match dunce::canonicalize(base.join(static_part)) {
147+
match fsops::canonicalize(base.join(static_part)) {
148148
Ok(base) => base,
149149
Err(err) => {
150150
event!(tracing::Level::ERROR, "Failed to resolve glob: {:?}", err);

0 commit comments

Comments
 (0)