Skip to content

Commit 16b0403

Browse files
fix(Mountain): Strip file:// scheme from paths in FileSystem effect handlers
Cocoon sends full URIs like `file:///Users/nikola/.land/extensions/...` through FileSystem.ReadFile/WriteFile/ReadDirectory RPC calls. Creating a PathBuf from such strings treats the scheme literally, causing every file operation to 404. Add `StripFileUriScheme()` helper to strip `file://` or `file:///` prefixes before constructing PathBuf. Apply to all 8 FileSystem operations: ReadFile, WriteFile, ReadDirectory, StatFile, CreateDirectory, Delete, Rename, and Copy. This fixes the redhat.java extension activation failure (and any other extension that reads its own package.json via the gRPC fs.readFile path) with "Resource not found: file:///...".
1 parent 66283f9 commit 16b0403

1 file changed

Lines changed: 32 additions & 10 deletions

File tree

Source/Track/Effect/CreateEffectForRequest/FileSystem.rs

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,28 @@ use tauri::Runtime;
1212

1313
use crate::{RunTime::ApplicationRunTime::ApplicationRunTime, Track::Effect::MappedEffectType::MappedEffect};
1414

15+
/// Strip a leading `file://` (or `file:///`) scheme from the incoming path.
16+
/// Cocoon sends full URIs like `file:///Users/nikola/.land/extensions/...`
17+
/// through `FileSystem.ReadFile`/`WriteFile`/`ReadDirectory`; `PathBuf` from
18+
/// such a string treats the scheme literally and every read 404s. Without
19+
/// this the redhat.java activation (and any other extension that uses the
20+
/// gRPC fs.readFile path for its own package.json) fails with "Resource not
21+
/// found: file:///...".
22+
fn StripFileUriScheme(Input:&str) -> &str {
23+
if let Some(Rest) = Input.strip_prefix("file://") {
24+
// `file:///Users/...` - the third slash is part of the path, keep it.
25+
if Rest.starts_with('/') {
26+
return Rest;
27+
}
28+
// `file://localhost/Users/...` - rarely used, but normalise by
29+
// stripping host-up-to-first-slash. Fall through on failure.
30+
if let Some(Idx) = Rest.find('/') {
31+
return &Rest[Idx..];
32+
}
33+
}
34+
Input
35+
}
36+
1537
pub fn CreateEffect<R:Runtime>(
1638
MethodName:&str,
1739
Parameters:Value,
@@ -28,7 +50,7 @@ pub fn CreateEffect<R:Runtime>(
2850
return Ok(json!(payload));
2951
}
3052
let fs_reader:Arc<dyn FileSystemReader> = run_time.Environment.Require();
31-
let path = std::path::PathBuf::from(path_str);
53+
let path = std::path::PathBuf::from(StripFileUriScheme(path_str));
3254
fs_reader
3355
.ReadFile(&path)
3456
.await
@@ -45,7 +67,7 @@ pub fn CreateEffect<R:Runtime>(
4567
Box::pin(async move {
4668
let fs_writer:Arc<dyn FileSystemWriter> = run_time.Environment.Require();
4769
let path_str = Parameters.get(0).and_then(Value::as_str).unwrap_or("");
48-
let path = std::path::PathBuf::from(path_str);
70+
let path = std::path::PathBuf::from(StripFileUriScheme(path_str));
4971
let content = Parameters.get(1).cloned();
5072
let content_bytes = match content {
5173
Some(Value::Array(arr)) => {
@@ -70,7 +92,7 @@ pub fn CreateEffect<R:Runtime>(
7092
Box::pin(async move {
7193
let fs_reader:Arc<dyn FileSystemReader> = run_time.Environment.Require();
7294
let path_str = Parameters.get(0).and_then(Value::as_str).unwrap_or("");
73-
let path = std::path::PathBuf::from(path_str);
95+
let path = std::path::PathBuf::from(StripFileUriScheme(path_str));
7496
fs_reader
7597
.ReadDirectory(&path)
7698
.await
@@ -87,7 +109,7 @@ pub fn CreateEffect<R:Runtime>(
87109
Box::pin(async move {
88110
let fs_reader:Arc<dyn FileSystemReader> = run_time.Environment.Require();
89111
let path_str = Parameters.get(0).and_then(Value::as_str).unwrap_or("");
90-
let path = std::path::PathBuf::from(path_str);
112+
let path = std::path::PathBuf::from(StripFileUriScheme(path_str));
91113
fs_reader
92114
.StatFile(&path)
93115
.await
@@ -104,7 +126,7 @@ pub fn CreateEffect<R:Runtime>(
104126
Box::pin(async move {
105127
let fs_writer:Arc<dyn FileSystemWriter> = run_time.Environment.Require();
106128
let path_str = Parameters.get(0).and_then(Value::as_str).unwrap_or("");
107-
let path = std::path::PathBuf::from(path_str);
129+
let path = std::path::PathBuf::from(StripFileUriScheme(path_str));
108130
fs_writer
109131
.CreateDirectory(&path, true)
110132
.await
@@ -121,7 +143,7 @@ pub fn CreateEffect<R:Runtime>(
121143
Box::pin(async move {
122144
let fs_writer:Arc<dyn FileSystemWriter> = run_time.Environment.Require();
123145
let path_str = Parameters.get(0).and_then(Value::as_str).unwrap_or("");
124-
let path = std::path::PathBuf::from(path_str);
146+
let path = std::path::PathBuf::from(StripFileUriScheme(path_str));
125147
let recursive = Parameters.get(1).and_then(Value::as_bool).unwrap_or(false);
126148
fs_writer
127149
.Delete(&path, recursive, false)
@@ -142,8 +164,8 @@ pub fn CreateEffect<R:Runtime>(
142164
let target = Parameters.get(1).and_then(Value::as_str).unwrap_or("");
143165
fs_writer
144166
.Rename(
145-
&std::path::PathBuf::from(source),
146-
&std::path::PathBuf::from(target),
167+
&std::path::PathBuf::from(StripFileUriScheme(source)),
168+
&std::path::PathBuf::from(StripFileUriScheme(target)),
147169
true,
148170
)
149171
.await
@@ -163,8 +185,8 @@ pub fn CreateEffect<R:Runtime>(
163185
let target = Parameters.get(1).and_then(Value::as_str).unwrap_or("");
164186
fs_writer
165187
.Copy(
166-
&std::path::PathBuf::from(source),
167-
&std::path::PathBuf::from(target),
188+
&std::path::PathBuf::from(StripFileUriScheme(source)),
189+
&std::path::PathBuf::from(StripFileUriScheme(target)),
168190
true,
169191
)
170192
.await

0 commit comments

Comments
 (0)