mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
path-uri: clarify host-native path conversion (#29501)
## Why Downstream refactors are producing confusing code with this functionality having a very generic name. Encoding the specific conversion approach in the method name makes it clearer. ## What Rename `PathUri::from_path` to `PathUri::from_host_native_path` and update its Rust call sites.
This commit is contained in:
committed by
GitHub
Unverified
parent
c53b1dae09
commit
11fab432be
@@ -500,7 +500,7 @@ mod tests {
|
||||
assert_matches!(
|
||||
maybe_parse_apply_patch_verified(
|
||||
&args,
|
||||
&PathUri::from_path(dir.path()).expect("absolute test path"),
|
||||
&PathUri::from_host_native_path(dir.path()).expect("absolute test path"),
|
||||
LOCAL_FS.as_ref(),
|
||||
/*sandbox*/ None,
|
||||
)
|
||||
@@ -517,7 +517,7 @@ mod tests {
|
||||
assert_matches!(
|
||||
maybe_parse_apply_patch_verified(
|
||||
&args,
|
||||
&PathUri::from_path(dir.path()).expect("absolute test path"),
|
||||
&PathUri::from_host_native_path(dir.path()).expect("absolute test path"),
|
||||
LOCAL_FS.as_ref(),
|
||||
/*sandbox*/ None,
|
||||
)
|
||||
@@ -752,7 +752,7 @@ PATCH"#,
|
||||
_ => panic!("Expected a single UpdateFile hunk"),
|
||||
};
|
||||
|
||||
let path_uri = PathUri::from_path(&path).expect("absolute test path");
|
||||
let path_uri = PathUri::from_host_native_path(&path).expect("absolute test path");
|
||||
let diff =
|
||||
unified_diff_from_chunks(&path_uri, chunks, LOCAL_FS.as_ref(), /*sandbox*/ None)
|
||||
.await
|
||||
@@ -792,7 +792,7 @@ PATCH"#,
|
||||
_ => panic!("Expected a single UpdateFile hunk"),
|
||||
};
|
||||
|
||||
let path_uri = PathUri::from_path(&path).expect("absolute test path");
|
||||
let path_uri = PathUri::from_host_native_path(&path).expect("absolute test path");
|
||||
let diff =
|
||||
unified_diff_from_chunks(&path_uri, chunks, LOCAL_FS.as_ref(), /*sandbox*/ None)
|
||||
.await
|
||||
@@ -832,7 +832,7 @@ PATCH"#,
|
||||
|
||||
let result = maybe_parse_apply_patch_verified(
|
||||
&argv,
|
||||
&PathUri::from_path(session_dir.path()).expect("absolute test path"),
|
||||
&PathUri::from_host_native_path(session_dir.path()).expect("absolute test path"),
|
||||
LOCAL_FS.as_ref(),
|
||||
/*sandbox*/ None,
|
||||
)
|
||||
@@ -844,7 +844,7 @@ PATCH"#,
|
||||
result,
|
||||
MaybeApplyPatchVerified::Body(ApplyPatchAction {
|
||||
changes: HashMap::from([(
|
||||
PathUri::from_path(session_dir.path().join(relative_path))
|
||||
PathUri::from_host_native_path(session_dir.path().join(relative_path))
|
||||
.expect("absolute test path"),
|
||||
ApplyPatchFileChange::Update {
|
||||
unified_diff: r#"@@ -1 +1 @@
|
||||
@@ -857,7 +857,8 @@ PATCH"#,
|
||||
},
|
||||
)]),
|
||||
patch: argv[1].clone(),
|
||||
cwd: PathUri::from_path(session_dir.path()).expect("absolute test path"),
|
||||
cwd: PathUri::from_host_native_path(session_dir.path())
|
||||
.expect("absolute test path"),
|
||||
})
|
||||
);
|
||||
}
|
||||
@@ -887,7 +888,7 @@ PATCH"#,
|
||||
|
||||
let result = maybe_parse_apply_patch_verified(
|
||||
&argv,
|
||||
&PathUri::from_path(session_dir.path()).expect("absolute test path"),
|
||||
&PathUri::from_host_native_path(session_dir.path()).expect("absolute test path"),
|
||||
LOCAL_FS.as_ref(),
|
||||
/*sandbox*/ None,
|
||||
)
|
||||
@@ -902,8 +903,8 @@ PATCH"#,
|
||||
worktree_dir.as_path()
|
||||
);
|
||||
|
||||
let source_path =
|
||||
PathUri::from_path(worktree_dir.join(source_name)).expect("absolute test path");
|
||||
let source_path = PathUri::from_host_native_path(worktree_dir.join(source_name))
|
||||
.expect("absolute test path");
|
||||
let change = action
|
||||
.changes()
|
||||
.get(&source_path)
|
||||
@@ -912,7 +913,8 @@ PATCH"#,
|
||||
match change {
|
||||
ApplyPatchFileChange::Update { move_path, .. } => {
|
||||
let expected_move_path =
|
||||
PathUri::from_path(worktree_dir.join(dest_name)).expect("absolute test path");
|
||||
PathUri::from_host_native_path(worktree_dir.join(dest_name))
|
||||
.expect("absolute test path");
|
||||
assert_eq!(move_path.as_ref(), Some(&expected_move_path));
|
||||
}
|
||||
other => panic!("expected update change, got {other:?}"),
|
||||
@@ -923,7 +925,7 @@ PATCH"#,
|
||||
async fn test_unreadable_destinations_still_verify() {
|
||||
let session_dir = tempdir().unwrap();
|
||||
fs::write(session_dir.path().join("binary.dat"), [0xff, 0xfe, 0xfd]).unwrap();
|
||||
let cwd = PathUri::from_path(session_dir.path()).expect("absolute test path");
|
||||
let cwd = PathUri::from_host_native_path(session_dir.path()).expect("absolute test path");
|
||||
let add_argv = vec![
|
||||
"apply_patch".to_string(),
|
||||
"*** Begin Patch\n*** Add File: binary.dat\n+text\n*** End Patch".to_string(),
|
||||
@@ -966,7 +968,7 @@ PATCH"#,
|
||||
|
||||
let result = maybe_parse_apply_patch_verified(
|
||||
&argv,
|
||||
&PathUri::from_path(session_dir.path()).expect("absolute test path"),
|
||||
&PathUri::from_host_native_path(session_dir.path()).expect("absolute test path"),
|
||||
LOCAL_FS.as_ref(),
|
||||
/*sandbox*/ None,
|
||||
)
|
||||
|
||||
@@ -913,7 +913,7 @@ mod tests {
|
||||
let mut stderr = Vec::new();
|
||||
apply_patch(
|
||||
&patch,
|
||||
&PathUri::from_path(dir.path()).expect("absolute test path"),
|
||||
&PathUri::from_host_native_path(dir.path()).expect("absolute test path"),
|
||||
&mut stdout,
|
||||
&mut stderr,
|
||||
LOCAL_FS.as_ref(),
|
||||
@@ -937,7 +937,7 @@ mod tests {
|
||||
#[tokio::test]
|
||||
async fn test_apply_patch_hunks_accept_relative_and_absolute_paths() {
|
||||
let dir = tempdir().unwrap();
|
||||
let cwd = PathUri::from_path(dir.path()).expect("absolute test path");
|
||||
let cwd = PathUri::from_host_native_path(dir.path()).expect("absolute test path");
|
||||
let relative_add = dir.path().join("relative-add.txt");
|
||||
let absolute_add = dir.path().join("absolute-add.txt");
|
||||
let relative_delete = dir.path().join("relative-delete.txt");
|
||||
@@ -1016,7 +1016,7 @@ mod tests {
|
||||
let mut stderr = Vec::new();
|
||||
apply_patch(
|
||||
&patch,
|
||||
&PathUri::from_path(dir.path()).expect("absolute test path"),
|
||||
&PathUri::from_host_native_path(dir.path()).expect("absolute test path"),
|
||||
&mut stdout,
|
||||
&mut stderr,
|
||||
LOCAL_FS.as_ref(),
|
||||
@@ -1052,7 +1052,7 @@ mod tests {
|
||||
let mut stderr = Vec::new();
|
||||
apply_patch(
|
||||
&patch,
|
||||
&PathUri::from_path(dir.path()).expect("absolute test path"),
|
||||
&PathUri::from_host_native_path(dir.path()).expect("absolute test path"),
|
||||
&mut stdout,
|
||||
&mut stderr,
|
||||
LOCAL_FS.as_ref(),
|
||||
@@ -1092,7 +1092,7 @@ mod tests {
|
||||
let mut stderr = Vec::new();
|
||||
apply_patch(
|
||||
&patch,
|
||||
&PathUri::from_path(dir.path()).expect("absolute test path"),
|
||||
&PathUri::from_host_native_path(dir.path()).expect("absolute test path"),
|
||||
&mut stdout,
|
||||
&mut stderr,
|
||||
LOCAL_FS.as_ref(),
|
||||
@@ -1136,7 +1136,7 @@ mod tests {
|
||||
let mut stderr = Vec::new();
|
||||
let failure = apply_patch(
|
||||
&patch,
|
||||
&PathUri::from_path(dir.path()).expect("absolute test path"),
|
||||
&PathUri::from_host_native_path(dir.path()).expect("absolute test path"),
|
||||
&mut stdout,
|
||||
&mut stderr,
|
||||
LOCAL_FS.as_ref(),
|
||||
@@ -1196,7 +1196,7 @@ mod tests {
|
||||
let mut stderr = Vec::new();
|
||||
apply_patch(
|
||||
&patch,
|
||||
&PathUri::from_path(dir.path()).expect("absolute test path"),
|
||||
&PathUri::from_host_native_path(dir.path()).expect("absolute test path"),
|
||||
&mut stdout,
|
||||
&mut stderr,
|
||||
LOCAL_FS.as_ref(),
|
||||
@@ -1254,7 +1254,7 @@ mod tests {
|
||||
let mut stderr = Vec::new();
|
||||
apply_patch(
|
||||
&patch,
|
||||
&PathUri::from_path(dir.path()).expect("absolute test path"),
|
||||
&PathUri::from_host_native_path(dir.path()).expect("absolute test path"),
|
||||
&mut stdout,
|
||||
&mut stderr,
|
||||
LOCAL_FS.as_ref(),
|
||||
@@ -1298,7 +1298,7 @@ mod tests {
|
||||
let mut stderr = Vec::new();
|
||||
apply_patch(
|
||||
&patch,
|
||||
&PathUri::from_path(dir.path()).expect("absolute test path"),
|
||||
&PathUri::from_host_native_path(dir.path()).expect("absolute test path"),
|
||||
&mut stdout,
|
||||
&mut stderr,
|
||||
LOCAL_FS.as_ref(),
|
||||
@@ -1341,7 +1341,7 @@ mod tests {
|
||||
let mut stderr = Vec::new();
|
||||
apply_patch(
|
||||
&patch,
|
||||
&PathUri::from_path(dir.path()).expect("absolute test path"),
|
||||
&PathUri::from_host_native_path(dir.path()).expect("absolute test path"),
|
||||
&mut stdout,
|
||||
&mut stderr,
|
||||
LOCAL_FS.as_ref(),
|
||||
@@ -1391,7 +1391,7 @@ mod tests {
|
||||
[Hunk::UpdateFile { chunks, .. }] => chunks,
|
||||
_ => panic!("Expected a single UpdateFile hunk"),
|
||||
};
|
||||
let path_uri = PathUri::from_path(&path).expect("absolute test path");
|
||||
let path_uri = PathUri::from_host_native_path(&path).expect("absolute test path");
|
||||
let diff = unified_diff_from_chunks(
|
||||
&path_uri,
|
||||
update_file_chunks,
|
||||
@@ -1439,7 +1439,7 @@ mod tests {
|
||||
_ => panic!("Expected a single UpdateFile hunk"),
|
||||
};
|
||||
|
||||
let resolved_path = PathUri::from_path(&path).expect("absolute test path");
|
||||
let resolved_path = PathUri::from_host_native_path(&path).expect("absolute test path");
|
||||
let diff = unified_diff_from_chunks(
|
||||
&resolved_path,
|
||||
chunks,
|
||||
@@ -1485,7 +1485,7 @@ mod tests {
|
||||
_ => panic!("Expected a single UpdateFile hunk"),
|
||||
};
|
||||
|
||||
let resolved_path = PathUri::from_path(&path).expect("absolute test path");
|
||||
let resolved_path = PathUri::from_host_native_path(&path).expect("absolute test path");
|
||||
let diff = unified_diff_from_chunks(
|
||||
&resolved_path,
|
||||
chunks,
|
||||
@@ -1529,7 +1529,7 @@ mod tests {
|
||||
_ => panic!("Expected a single UpdateFile hunk"),
|
||||
};
|
||||
|
||||
let path_uri = PathUri::from_path(&path).expect("absolute test path");
|
||||
let path_uri = PathUri::from_host_native_path(&path).expect("absolute test path");
|
||||
let diff =
|
||||
unified_diff_from_chunks(&path_uri, chunks, LOCAL_FS.as_ref(), /*sandbox*/ None)
|
||||
.await
|
||||
@@ -1580,7 +1580,7 @@ mod tests {
|
||||
_ => panic!("Expected a single UpdateFile hunk"),
|
||||
};
|
||||
|
||||
let path_uri = PathUri::from_path(&path).expect("absolute test path");
|
||||
let path_uri = PathUri::from_host_native_path(&path).expect("absolute test path");
|
||||
let diff =
|
||||
unified_diff_from_chunks(&path_uri, chunks, LOCAL_FS.as_ref(), /*sandbox*/ None)
|
||||
.await
|
||||
@@ -1610,7 +1610,7 @@ mod tests {
|
||||
let mut stderr = Vec::new();
|
||||
apply_patch(
|
||||
&patch,
|
||||
&PathUri::from_path(dir.path()).expect("absolute test path"),
|
||||
&PathUri::from_host_native_path(dir.path()).expect("absolute test path"),
|
||||
&mut stdout,
|
||||
&mut stderr,
|
||||
LOCAL_FS.as_ref(),
|
||||
@@ -1648,7 +1648,7 @@ g
|
||||
let mut stderr = Vec::new();
|
||||
let result = apply_patch(
|
||||
&patch,
|
||||
&PathUri::from_path(dir.path()).expect("absolute test path"),
|
||||
&PathUri::from_host_native_path(dir.path()).expect("absolute test path"),
|
||||
&mut stdout,
|
||||
&mut stderr,
|
||||
LOCAL_FS.as_ref(),
|
||||
@@ -1667,7 +1667,7 @@ g
|
||||
let dir = tempdir().unwrap();
|
||||
let path = dir.path().join("binary.dat");
|
||||
fs::write(dir.path().join("source.txt"), "before\n").unwrap();
|
||||
let cwd = PathUri::from_path(dir.path()).expect("absolute test path");
|
||||
let cwd = PathUri::from_host_native_path(dir.path()).expect("absolute test path");
|
||||
|
||||
for patch in [
|
||||
wrap_patch("*** Add File: binary.dat\n+text"),
|
||||
@@ -1705,7 +1705,7 @@ g
|
||||
let mut stderr = Vec::new();
|
||||
let delta = apply_patch(
|
||||
&patch,
|
||||
&PathUri::from_path(dir.path()).expect("absolute test path"),
|
||||
&PathUri::from_host_native_path(dir.path()).expect("absolute test path"),
|
||||
&mut stdout,
|
||||
&mut stderr,
|
||||
LOCAL_FS.as_ref(),
|
||||
|
||||
@@ -480,7 +480,7 @@ fn test_parse_patch_accepts_relative_and_absolute_hunk_paths() {
|
||||
#[test]
|
||||
fn test_hunk_resolve_path_accepts_relative_and_absolute_paths() {
|
||||
let cwd_dir = tempfile::tempdir().unwrap();
|
||||
let cwd = PathUri::from_path(cwd_dir.path()).unwrap();
|
||||
let cwd = PathUri::from_host_native_path(cwd_dir.path()).unwrap();
|
||||
let absolute_dir = tempfile::tempdir().unwrap();
|
||||
let absolute_add = absolute_dir.path().join("absolute-add.py").abs();
|
||||
let absolute_delete = absolute_dir.path().join("absolute-delete.py").abs();
|
||||
|
||||
@@ -8,7 +8,7 @@ use tempfile::tempdir;
|
||||
fn convert_apply_patch_maps_add_variant() {
|
||||
let tmp = tempdir().expect("tmp");
|
||||
let path = tmp.path().join("a.txt");
|
||||
let path_uri = PathUri::from_path(&path).expect("absolute test path");
|
||||
let path_uri = PathUri::from_host_native_path(&path).expect("absolute test path");
|
||||
let action = ApplyPatchAction::new_add_for_test(&path_uri, "hello".to_string());
|
||||
|
||||
let got = convert_apply_patch_to_protocol(&action);
|
||||
|
||||
@@ -645,7 +645,7 @@ mod tests {
|
||||
make_session_and_context_with_dynamic_tools_and_rx(Vec::new()).await;
|
||||
let tracker = Arc::new(Mutex::new(TurnDiffTracker::new()));
|
||||
let dir = tempdir().expect("tempdir");
|
||||
let cwd = PathUri::from_path(dir.path()).expect("absolute cwd");
|
||||
let cwd = PathUri::from_host_native_path(dir.path()).expect("absolute cwd");
|
||||
let mut stdout = Vec::new();
|
||||
let mut stderr = Vec::new();
|
||||
let delta = codex_apply_patch::apply_patch(
|
||||
@@ -729,7 +729,7 @@ mod tests {
|
||||
make_session_and_context_with_dynamic_tools_and_rx(Vec::new()).await;
|
||||
let tracker = Arc::new(Mutex::new(TurnDiffTracker::new()));
|
||||
let dir = tempdir().expect("tempdir");
|
||||
let cwd = PathUri::from_path(dir.path()).expect("absolute cwd");
|
||||
let cwd = PathUri::from_host_native_path(dir.path()).expect("absolute cwd");
|
||||
|
||||
for patch in [
|
||||
"*** Begin Patch\n*** Add File: a.txt\n+one\n*** End Patch",
|
||||
@@ -782,7 +782,7 @@ mod tests {
|
||||
make_session_and_context_with_dynamic_tools_and_rx(Vec::new()).await;
|
||||
let tracker = Arc::new(Mutex::new(TurnDiffTracker::new()));
|
||||
let dir = tempdir().expect("tempdir");
|
||||
let cwd = PathUri::from_path(dir.path()).expect("absolute cwd");
|
||||
let cwd = PathUri::from_host_native_path(dir.path()).expect("absolute cwd");
|
||||
let mut stdout = Vec::new();
|
||||
let mut stderr = Vec::new();
|
||||
let delta = codex_apply_patch::apply_patch(
|
||||
|
||||
@@ -18,7 +18,7 @@ fn git_blob_sha1_hex(data: &str) -> String {
|
||||
}
|
||||
|
||||
async fn apply_verified_patch(root: &Path, patch: &str) -> AppliedPatchDelta {
|
||||
let cwd = PathUri::from_path(root).expect("absolute tempdir path");
|
||||
let cwd = PathUri::from_host_native_path(root).expect("absolute tempdir path");
|
||||
let argv = vec!["apply_patch".to_string(), patch.to_string()];
|
||||
match codex_apply_patch::maybe_parse_apply_patch_verified(
|
||||
&argv,
|
||||
|
||||
@@ -998,7 +998,7 @@ impl TestCodexHarness {
|
||||
) -> Result<()> {
|
||||
let abs_path = self.path_abs(rel);
|
||||
if let Some(parent) = abs_path.parent() {
|
||||
let parent_uri = PathUri::from_path(&parent)?;
|
||||
let parent_uri = PathUri::from_host_native_path(&parent)?;
|
||||
self.test
|
||||
.fs()
|
||||
.create_directory(
|
||||
@@ -1008,7 +1008,7 @@ impl TestCodexHarness {
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
let abs_path_uri = PathUri::from_path(&abs_path)?;
|
||||
let abs_path_uri = PathUri::from_host_native_path(&abs_path)?;
|
||||
self.test
|
||||
.fs()
|
||||
.write_file(
|
||||
@@ -1022,7 +1022,7 @@ impl TestCodexHarness {
|
||||
|
||||
pub async fn read_file_text(&self, rel: impl AsRef<Path>) -> Result<String> {
|
||||
let path = self.path_abs(rel);
|
||||
let path_uri = PathUri::from_path(&path)?;
|
||||
let path_uri = PathUri::from_host_native_path(&path)?;
|
||||
Ok(self
|
||||
.test
|
||||
.fs()
|
||||
@@ -1032,7 +1032,7 @@ impl TestCodexHarness {
|
||||
|
||||
pub async fn create_dir_all(&self, rel: impl AsRef<Path>) -> Result<()> {
|
||||
let path = self.path_abs(rel);
|
||||
let path_uri = PathUri::from_path(&path)?;
|
||||
let path_uri = PathUri::from_host_native_path(&path)?;
|
||||
self.test
|
||||
.fs()
|
||||
.create_directory(
|
||||
|
||||
@@ -141,8 +141,8 @@ async fn agents_override_is_preferred_over_agents_md() -> Result<()> {
|
||||
agents_instructions(test_codex().with_workspace_setup(|cwd, fs| async move {
|
||||
let agents_md = cwd.join("AGENTS.md");
|
||||
let override_md = cwd.join("AGENTS.override.md");
|
||||
let agents_md_uri = PathUri::from_path(&agents_md)?;
|
||||
let override_md_uri = PathUri::from_path(&override_md)?;
|
||||
let agents_md_uri = PathUri::from_host_native_path(&agents_md)?;
|
||||
let override_md_uri = PathUri::from_host_native_path(&override_md)?;
|
||||
fs.write_file(&agents_md_uri, b"base doc".to_vec(), /*sandbox*/ None)
|
||||
.await?;
|
||||
fs.write_file(
|
||||
@@ -177,8 +177,8 @@ async fn configured_fallback_is_used_when_agents_candidate_is_directory() -> Res
|
||||
.with_workspace_setup(|cwd, fs| async move {
|
||||
let agents_dir = cwd.join("AGENTS.md");
|
||||
let fallback = cwd.join("WORKFLOW.md");
|
||||
let agents_dir_uri = PathUri::from_path(&agents_dir)?;
|
||||
let fallback_uri = PathUri::from_path(&fallback)?;
|
||||
let agents_dir_uri = PathUri::from_host_native_path(&agents_dir)?;
|
||||
let fallback_uri = PathUri::from_host_native_path(&fallback)?;
|
||||
fs.create_directory(
|
||||
&agents_dir_uri,
|
||||
CreateDirectoryOptions { recursive: true },
|
||||
@@ -220,10 +220,10 @@ async fn agents_docs_are_concatenated_from_project_root_to_cwd() -> Result<()> {
|
||||
let root_agents = root.join("AGENTS.md");
|
||||
let git_marker = root.join(".git");
|
||||
let nested_agents = nested.join("AGENTS.md");
|
||||
let nested_uri = PathUri::from_path(&nested)?;
|
||||
let root_agents_uri = PathUri::from_path(&root_agents)?;
|
||||
let git_marker_uri = PathUri::from_path(&git_marker)?;
|
||||
let nested_agents_uri = PathUri::from_path(&nested_agents)?;
|
||||
let nested_uri = PathUri::from_host_native_path(&nested)?;
|
||||
let root_agents_uri = PathUri::from_host_native_path(&root_agents)?;
|
||||
let git_marker_uri = PathUri::from_host_native_path(&git_marker)?;
|
||||
let nested_agents_uri = PathUri::from_host_native_path(&nested_agents)?;
|
||||
|
||||
fs.create_directory(
|
||||
&nested_uri,
|
||||
@@ -363,7 +363,7 @@ async fn selected_environment_sources_match_model_visible_instructions() -> Resu
|
||||
let mut builder = test_codex()
|
||||
.with_home(home)
|
||||
.with_workspace_setup(|cwd, fs| async move {
|
||||
let agents_md_uri = PathUri::from_path(cwd.join("AGENTS.md"))?;
|
||||
let agents_md_uri = PathUri::from_host_native_path(cwd.join("AGENTS.md"))?;
|
||||
fs.write_file(
|
||||
&agents_md_uri,
|
||||
b"project doc".to_vec(),
|
||||
@@ -420,7 +420,8 @@ async fn loads_user_instructions_without_a_primary_environment() -> Result<()> {
|
||||
.with_home(Arc::clone(&home))
|
||||
.with_user_instructions_provider(provider.clone())
|
||||
.with_workspace_setup(|cwd, fs| async move {
|
||||
let project_agents_uri = PathUri::from_path(cwd.join(GLOBAL_AGENTS_FILENAME))?;
|
||||
let project_agents_uri =
|
||||
PathUri::from_host_native_path(cwd.join(GLOBAL_AGENTS_FILENAME))?;
|
||||
fs.write_file(
|
||||
&project_agents_uri,
|
||||
PROJECT_INSTRUCTIONS.as_bytes().to_vec(),
|
||||
@@ -505,7 +506,7 @@ async fn fresh_thread_composes_global_before_project_and_reports_sources() -> Re
|
||||
let mut builder = test_codex()
|
||||
.with_home(Arc::clone(&home))
|
||||
.with_workspace_setup(|cwd, fs| async move {
|
||||
let agents_md_uri = PathUri::from_path(cwd.join("AGENTS.md"))?;
|
||||
let agents_md_uri = PathUri::from_host_native_path(cwd.join("AGENTS.md"))?;
|
||||
fs.write_file(
|
||||
&agents_md_uri,
|
||||
PROJECT_INSTRUCTIONS.as_bytes().to_vec(),
|
||||
@@ -534,7 +535,7 @@ async fn fresh_thread_composes_global_before_project_and_reports_sources() -> Re
|
||||
)?;
|
||||
test.fs()
|
||||
.write_file(
|
||||
&PathUri::from_path(&project_source)?,
|
||||
&PathUri::from_host_native_path(&project_source)?,
|
||||
NEW_PROJECT_INSTRUCTIONS.as_bytes().to_vec(),
|
||||
/*sandbox*/ None,
|
||||
)
|
||||
@@ -631,7 +632,7 @@ async fn multi_environment_thread_loads_every_project_and_keeps_creation_snapsho
|
||||
.with_user_instructions_provider(provider.clone())
|
||||
.with_workspace_setup(|cwd, fs| async move {
|
||||
fs.write_file(
|
||||
&PathUri::from_path(cwd.join(GLOBAL_AGENTS_FILENAME))?,
|
||||
&PathUri::from_host_native_path(cwd.join(GLOBAL_AGENTS_FILENAME))?,
|
||||
b"remote project instructions".to_vec(),
|
||||
/*sandbox*/ None,
|
||||
)
|
||||
@@ -658,7 +659,7 @@ async fn multi_environment_thread_loads_every_project_and_keeps_creation_snapsho
|
||||
},
|
||||
TurnEnvironmentSelection {
|
||||
environment_id: LOCAL_ENVIRONMENT_ID.to_string(),
|
||||
cwd: PathUri::from_path(local_root.path())?,
|
||||
cwd: PathUri::from_host_native_path(local_root.path())?,
|
||||
},
|
||||
],
|
||||
thread_extension_init: Default::default(),
|
||||
@@ -671,7 +672,7 @@ async fn multi_environment_thread_loads_every_project_and_keeps_creation_snapsho
|
||||
vec![
|
||||
PathUri::from_abs_path(&global_source),
|
||||
PathUri::from_abs_path(&remote_source),
|
||||
PathUri::from_path(&local_source)?,
|
||||
PathUri::from_host_native_path(&local_source)?,
|
||||
]
|
||||
);
|
||||
|
||||
@@ -684,7 +685,7 @@ async fn multi_environment_thread_loads_every_project_and_keeps_creation_snapsho
|
||||
)?;
|
||||
test.fs()
|
||||
.write_file(
|
||||
&PathUri::from_path(test.config.cwd.join(GLOBAL_AGENTS_OVERRIDE_FILENAME))?,
|
||||
&PathUri::from_host_native_path(test.config.cwd.join(GLOBAL_AGENTS_OVERRIDE_FILENAME))?,
|
||||
b"new remote project instructions".to_vec(),
|
||||
/*sandbox*/ None,
|
||||
)
|
||||
@@ -712,7 +713,7 @@ async fn multi_environment_thread_loads_every_project_and_keeps_creation_snapsho
|
||||
vec![
|
||||
PathUri::from_abs_path(&global_source),
|
||||
PathUri::from_abs_path(&remote_source),
|
||||
PathUri::from_path(&local_source)?,
|
||||
PathUri::from_host_native_path(&local_source)?,
|
||||
]
|
||||
);
|
||||
|
||||
|
||||
@@ -1329,7 +1329,7 @@ async fn apply_patch_turn_diff_paths_stay_repo_relative_when_session_cwd_is_nest
|
||||
config.cwd = config.cwd.join("subdir");
|
||||
})
|
||||
.with_workspace_setup(|cwd, fs| async move {
|
||||
let cwd_uri = PathUri::from_path(&cwd)?;
|
||||
let cwd_uri = PathUri::from_host_native_path(&cwd)?;
|
||||
fs.create_directory(
|
||||
&cwd_uri,
|
||||
CreateDirectoryOptions { recursive: true },
|
||||
@@ -1337,8 +1337,8 @@ async fn apply_patch_turn_diff_paths_stay_repo_relative_when_session_cwd_is_nest
|
||||
)
|
||||
.await?;
|
||||
let repo_root = cwd.parent().expect("nested cwd should have parent");
|
||||
let git_uri = PathUri::from_path(repo_root.join(".git"))?;
|
||||
let repo_file_uri = PathUri::from_path(repo_root.join("repo.txt"))?;
|
||||
let git_uri = PathUri::from_host_native_path(repo_root.join(".git"))?;
|
||||
let repo_file_uri = PathUri::from_host_native_path(repo_root.join("repo.txt"))?;
|
||||
fs.write_file(
|
||||
&git_uri,
|
||||
b"gitdir: /tmp/fake-worktree\n".to_vec(),
|
||||
@@ -1586,7 +1586,7 @@ async fn apply_patch_turn_diff_tracks_local_and_remote_environment_paths() -> Re
|
||||
SystemTime::now().duration_since(UNIX_EPOCH)?.as_millis()
|
||||
))
|
||||
.abs();
|
||||
let shared_cwd_uri = PathUri::from_path(&shared_cwd)?;
|
||||
let shared_cwd_uri = PathUri::from_host_native_path(&shared_cwd)?;
|
||||
let _ = fs::remove_dir_all(shared_cwd.as_path());
|
||||
test.fs()
|
||||
.remove(
|
||||
@@ -1689,7 +1689,7 @@ async fn apply_patch_turn_diff_tracks_local_and_remote_environment_paths() -> Re
|
||||
assert_eq!(
|
||||
test.fs()
|
||||
.read_file_text(
|
||||
&PathUri::from_path(shared_cwd.join(file_name))?,
|
||||
&PathUri::from_host_native_path(shared_cwd.join(file_name))?,
|
||||
/*sandbox*/ None,
|
||||
)
|
||||
.await?,
|
||||
@@ -1859,7 +1859,7 @@ async fn apply_patch_clears_aggregated_diff_after_inexact_delta() -> Result<()>
|
||||
|
||||
let harness = apply_patch_harness_with(|builder| {
|
||||
builder.with_workspace_setup(|cwd, fs| async move {
|
||||
let binary_path_uri = PathUri::from_path(cwd.join("binary.dat"))?;
|
||||
let binary_path_uri = PathUri::from_host_native_path(cwd.join("binary.dat"))?;
|
||||
fs.write_file(
|
||||
&binary_path_uri,
|
||||
vec![0xff, 0xfe, 0xfd],
|
||||
|
||||
@@ -74,7 +74,7 @@ async fn approved_network_host_for_one_environment_still_prompts_in_another() ->
|
||||
SystemTime::now().duration_since(UNIX_EPOCH)?.as_millis()
|
||||
))
|
||||
.abs();
|
||||
let remote_cwd_uri = PathUri::from_path(&remote_cwd)?;
|
||||
let remote_cwd_uri = PathUri::from_host_native_path(&remote_cwd)?;
|
||||
test.fs()
|
||||
.create_directory(
|
||||
&remote_cwd_uri,
|
||||
|
||||
@@ -173,7 +173,7 @@ async fn remote_test_env_can_connect_and_use_filesystem() -> Result<()> {
|
||||
let file_system = test_env.environment().get_filesystem();
|
||||
|
||||
let file_path_abs = test_env.cwd().join("remote-test-env-ok");
|
||||
let file_path_uri = PathUri::from_path(&file_path_abs)?;
|
||||
let file_path_uri = PathUri::from_host_native_path(&file_path_abs)?;
|
||||
let payload = b"remote-test-env-ok".to_vec();
|
||||
|
||||
file_system
|
||||
@@ -329,8 +329,8 @@ async fn remote_sandbox_denial_requests_approval_and_retries() -> Result<()> {
|
||||
let nonce = SystemTime::now().duration_since(UNIX_EPOCH)?.as_millis();
|
||||
let remote_cwd = PathBuf::from(format!("/tmp/codex-remote-denial-cwd-{nonce}")).abs();
|
||||
let target_path = PathBuf::from(format!("/tmp/codex-remote-denial-target-{nonce}")).abs();
|
||||
let remote_cwd_uri = PathUri::from_path(&remote_cwd)?;
|
||||
let target_uri = PathUri::from_path(&target_path)?;
|
||||
let remote_cwd_uri = PathUri::from_host_native_path(&remote_cwd)?;
|
||||
let target_uri = PathUri::from_host_native_path(&target_path)?;
|
||||
test.fs()
|
||||
.create_directory(
|
||||
&remote_cwd_uri,
|
||||
@@ -801,8 +801,8 @@ async fn exec_command_routes_to_selected_remote_environment() -> Result<()> {
|
||||
))
|
||||
.abs();
|
||||
let remote_marker_name = "marker.txt";
|
||||
let remote_cwd_uri = PathUri::from_path(&remote_cwd)?;
|
||||
let remote_marker_uri = PathUri::from_path(remote_cwd.join(remote_marker_name))?;
|
||||
let remote_cwd_uri = PathUri::from_host_native_path(&remote_cwd)?;
|
||||
let remote_marker_uri = PathUri::from_host_native_path(remote_cwd.join(remote_marker_name))?;
|
||||
test.fs()
|
||||
.create_directory(
|
||||
&remote_cwd_uri,
|
||||
@@ -900,7 +900,7 @@ async fn remote_request_permissions_grant_unblocks_later_remote_exec() -> Result
|
||||
let local_write_root = local_cwd.path().join(relative_write_root);
|
||||
let local_target_path = local_cwd.path().join(relative_target_path);
|
||||
fs::create_dir(&local_write_root)?;
|
||||
let remote_write_root_uri = PathUri::from_path(&remote_write_root)?;
|
||||
let remote_write_root_uri = PathUri::from_host_native_path(&remote_write_root)?;
|
||||
test.fs()
|
||||
.create_directory(
|
||||
&remote_write_root_uri,
|
||||
@@ -1040,7 +1040,7 @@ async fn remote_request_permissions_grant_unblocks_later_remote_exec() -> Result
|
||||
assert_eq!(
|
||||
test.fs()
|
||||
.read_file_text(
|
||||
&PathUri::from_path(&remote_target_path)?,
|
||||
&PathUri::from_host_native_path(&remote_target_path)?,
|
||||
/*sandbox*/ None,
|
||||
)
|
||||
.await?,
|
||||
@@ -1084,7 +1084,7 @@ async fn apply_patch_freeform_routes_to_selected_remote_environment() -> Result<
|
||||
SystemTime::now().duration_since(UNIX_EPOCH)?.as_millis()
|
||||
))
|
||||
.abs();
|
||||
let remote_cwd_uri = PathUri::from_path(&remote_cwd)?;
|
||||
let remote_cwd_uri = PathUri::from_host_native_path(&remote_cwd)?;
|
||||
test.fs()
|
||||
.create_directory(
|
||||
&remote_cwd_uri,
|
||||
@@ -1129,7 +1129,7 @@ async fn apply_patch_freeform_routes_to_selected_remote_environment() -> Result<
|
||||
let remote_contents = test
|
||||
.fs()
|
||||
.read_file_text(
|
||||
&PathUri::from_path(remote_cwd.join(file_name))?,
|
||||
&PathUri::from_host_native_path(remote_cwd.join(file_name))?,
|
||||
/*sandbox*/ None,
|
||||
)
|
||||
.await?;
|
||||
@@ -1174,7 +1174,7 @@ async fn apply_patch_approvals_are_remembered_per_environment() -> Result<()> {
|
||||
SystemTime::now().duration_since(UNIX_EPOCH)?.as_millis()
|
||||
))
|
||||
.abs();
|
||||
let remote_cwd_uri = PathUri::from_path(&remote_cwd)?;
|
||||
let remote_cwd_uri = PathUri::from_host_native_path(&remote_cwd)?;
|
||||
test.fs()
|
||||
.create_directory(
|
||||
&remote_cwd_uri,
|
||||
@@ -1188,7 +1188,7 @@ async fn apply_patch_approvals_are_remembered_per_environment() -> Result<()> {
|
||||
SystemTime::now().duration_since(UNIX_EPOCH)?.as_millis()
|
||||
))
|
||||
.abs();
|
||||
let target_path_uri = PathUri::from_path(&target_path)?;
|
||||
let target_path_uri = PathUri::from_host_native_path(&target_path)?;
|
||||
let _ = fs::remove_file(&target_path);
|
||||
test.fs()
|
||||
.remove(
|
||||
@@ -1362,7 +1362,7 @@ async fn apply_patch_intercepted_exec_command_routes_to_selected_remote_environm
|
||||
SystemTime::now().duration_since(UNIX_EPOCH)?.as_millis()
|
||||
))
|
||||
.abs();
|
||||
let remote_cwd_uri = PathUri::from_path(&remote_cwd)?;
|
||||
let remote_cwd_uri = PathUri::from_host_native_path(&remote_cwd)?;
|
||||
test.fs()
|
||||
.create_directory(
|
||||
&remote_cwd_uri,
|
||||
@@ -1417,7 +1417,7 @@ async fn apply_patch_intercepted_exec_command_routes_to_selected_remote_environm
|
||||
let remote_contents = test
|
||||
.fs()
|
||||
.read_file_text(
|
||||
&PathUri::from_path(remote_cwd.join(file_name))?,
|
||||
&PathUri::from_host_native_path(remote_cwd.join(file_name))?,
|
||||
/*sandbox*/ None,
|
||||
)
|
||||
.await?;
|
||||
@@ -1455,8 +1455,8 @@ async fn remote_test_env_sandboxed_read_allows_readable_root() -> Result<()> {
|
||||
|
||||
let allowed_dir = PathBuf::from(format!("/tmp/codex-remote-readable-{}", std::process::id()));
|
||||
let file_path = allowed_dir.join("note.txt");
|
||||
let allowed_dir_uri = PathUri::from_path(&allowed_dir)?;
|
||||
let file_path_uri = PathUri::from_path(&file_path)?;
|
||||
let allowed_dir_uri = PathUri::from_host_native_path(&allowed_dir)?;
|
||||
let file_path_uri = PathUri::from_host_native_path(&file_path)?;
|
||||
file_system
|
||||
.create_directory(
|
||||
&allowed_dir_uri,
|
||||
@@ -1516,7 +1516,7 @@ async fn remote_test_env_sandboxed_read_rejects_symlink_parent_dotdot_escape() -
|
||||
))?;
|
||||
|
||||
let requested_path =
|
||||
PathUri::from_path(allowed_dir.join("link").join("..").join("secret.txt"))?;
|
||||
PathUri::from_host_native_path(allowed_dir.join("link").join("..").join("secret.txt"))?;
|
||||
let sandbox = read_only_sandbox(allowed_dir.clone());
|
||||
let error = match file_system.read_file(&requested_path, Some(&sandbox)).await {
|
||||
Ok(_) => anyhow::bail!("read should fail after path normalization"),
|
||||
@@ -1564,7 +1564,7 @@ async fn remote_test_env_remove_removes_symlink_not_target() -> Result<()> {
|
||||
let sandbox = workspace_write_sandbox(allowed_dir.clone());
|
||||
file_system
|
||||
.remove(
|
||||
&PathUri::from_path(&symlink_path)?,
|
||||
&PathUri::from_host_native_path(&symlink_path)?,
|
||||
RemoveOptions {
|
||||
recursive: false,
|
||||
force: false,
|
||||
@@ -1582,13 +1582,16 @@ async fn remote_test_env_remove_removes_symlink_not_target() -> Result<()> {
|
||||
.is_ok();
|
||||
assert!(!symlink_exists);
|
||||
let outside = file_system
|
||||
.read_file_text(&PathUri::from_path(&outside_file)?, /*sandbox*/ None)
|
||||
.read_file_text(
|
||||
&PathUri::from_host_native_path(&outside_file)?,
|
||||
/*sandbox*/ None,
|
||||
)
|
||||
.await?;
|
||||
assert_eq!(outside, "outside");
|
||||
|
||||
file_system
|
||||
.remove(
|
||||
&PathUri::from_path(&root)?,
|
||||
&PathUri::from_host_native_path(&root)?,
|
||||
RemoveOptions {
|
||||
recursive: true,
|
||||
force: true,
|
||||
@@ -1630,8 +1633,8 @@ async fn remote_test_env_copy_preserves_symlink_source() -> Result<()> {
|
||||
let sandbox = workspace_write_sandbox(allowed_dir.clone());
|
||||
file_system
|
||||
.copy(
|
||||
&PathUri::from_path(&source_symlink)?,
|
||||
&PathUri::from_path(&copied_symlink)?,
|
||||
&PathUri::from_host_native_path(&source_symlink)?,
|
||||
&PathUri::from_host_native_path(&copied_symlink)?,
|
||||
CopyOptions { recursive: false },
|
||||
Some(&sandbox),
|
||||
)
|
||||
@@ -1664,7 +1667,7 @@ async fn remote_test_env_copy_preserves_symlink_source() -> Result<()> {
|
||||
|
||||
file_system
|
||||
.remove(
|
||||
&PathUri::from_path(&root)?,
|
||||
&PathUri::from_host_native_path(&root)?,
|
||||
RemoveOptions {
|
||||
recursive: true,
|
||||
force: true,
|
||||
|
||||
@@ -747,7 +747,7 @@ async fn stdio_server_uses_configured_cwd_before_runtime_fallback() -> anyhow::R
|
||||
let fixture = test_codex()
|
||||
.with_workspace_setup(|cwd, fs| async move {
|
||||
let configured_cwd = cwd.join("mcp-configured-cwd");
|
||||
let configured_cwd_uri = PathUri::from_path(&configured_cwd)?;
|
||||
let configured_cwd_uri = PathUri::from_host_native_path(&configured_cwd)?;
|
||||
fs.create_directory(
|
||||
&configured_cwd_uri,
|
||||
CreateDirectoryOptions { recursive: true },
|
||||
|
||||
@@ -31,7 +31,7 @@ async fn write_repo_skill(
|
||||
body: &str,
|
||||
) -> Result<()> {
|
||||
let skill_dir = cwd.join(".agents").join("skills").join(name);
|
||||
let skill_dir_uri = PathUri::from_path(&skill_dir)?;
|
||||
let skill_dir_uri = PathUri::from_host_native_path(&skill_dir)?;
|
||||
fs.create_directory(
|
||||
&skill_dir_uri,
|
||||
CreateDirectoryOptions { recursive: true },
|
||||
@@ -40,7 +40,7 @@ async fn write_repo_skill(
|
||||
.await?;
|
||||
let contents = format!("---\nname: {name}\ndescription: {description}\n---\n\n{body}\n");
|
||||
let path = skill_dir.join("SKILL.md");
|
||||
let path_uri = PathUri::from_path(&path)?;
|
||||
let path_uri = PathUri::from_host_native_path(&path)?;
|
||||
fs.write_file(&path_uri, contents.into_bytes(), /*sandbox*/ None)
|
||||
.await?;
|
||||
Ok(())
|
||||
|
||||
@@ -229,7 +229,7 @@ async fn create_workspace_directory(
|
||||
rel_path: impl AsRef<std::path::Path>,
|
||||
) -> Result<std::path::PathBuf> {
|
||||
let abs_path = test.config.cwd.join(rel_path.as_ref());
|
||||
let abs_path_uri = PathUri::from_path(&abs_path)?;
|
||||
let abs_path_uri = PathUri::from_host_native_path(&abs_path)?;
|
||||
test.fs()
|
||||
.create_directory(
|
||||
&abs_path_uri,
|
||||
@@ -437,7 +437,7 @@ async fn unified_exec_emits_exec_command_begin_event() -> Result<()> {
|
||||
|
||||
assert_command(&begin_event.command, "-lc", "/bin/echo hello unified exec");
|
||||
|
||||
assert_eq!(begin_event.cwd, PathUri::from_path(&cwd)?);
|
||||
assert_eq!(begin_event.cwd, PathUri::from_host_native_path(&cwd)?);
|
||||
|
||||
wait_for_event(&test.codex, |event| {
|
||||
matches!(event, EventMsg::TurnComplete(_))
|
||||
@@ -508,7 +508,7 @@ async fn unified_exec_resolves_relative_workdir() -> Result<()> {
|
||||
|
||||
assert_eq!(
|
||||
begin_event.cwd,
|
||||
PathUri::from_path(&workdir)?,
|
||||
PathUri::from_host_native_path(&workdir)?,
|
||||
"exec_command cwd should resolve relative workdir against turn cwd",
|
||||
);
|
||||
|
||||
@@ -570,7 +570,7 @@ async fn unified_exec_respects_workdir_override() -> Result<()> {
|
||||
|
||||
assert_eq!(
|
||||
begin_event.cwd,
|
||||
PathUri::from_path(&workdir)?,
|
||||
PathUri::from_host_native_path(&workdir)?,
|
||||
"exec_command cwd should reflect the requested workdir override"
|
||||
);
|
||||
|
||||
|
||||
@@ -133,7 +133,7 @@ fn png_bytes(width: u32, height: u32, rgba: [u8; 4]) -> anyhow::Result<Vec<u8>>
|
||||
|
||||
async fn create_workspace_directory(test: &TestCodex, rel_path: &str) -> anyhow::Result<PathBuf> {
|
||||
let abs_path = test.config.cwd.join(rel_path);
|
||||
let abs_path_uri = PathUri::from_path(&abs_path)?;
|
||||
let abs_path_uri = PathUri::from_host_native_path(&abs_path)?;
|
||||
test.fs()
|
||||
.create_directory(
|
||||
&abs_path_uri,
|
||||
@@ -151,7 +151,7 @@ async fn write_workspace_file(
|
||||
) -> anyhow::Result<PathBuf> {
|
||||
let abs_path = test.config.cwd.join(rel_path);
|
||||
if let Some(parent) = abs_path.parent() {
|
||||
let parent_uri = PathUri::from_path(&parent)?;
|
||||
let parent_uri = PathUri::from_host_native_path(&parent)?;
|
||||
test.fs()
|
||||
.create_directory(
|
||||
&parent_uri,
|
||||
@@ -160,7 +160,7 @@ async fn write_workspace_file(
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
let abs_path_uri = PathUri::from_path(&abs_path)?;
|
||||
let abs_path_uri = PathUri::from_host_native_path(&abs_path)?;
|
||||
test.fs()
|
||||
.write_file(&abs_path_uri, contents, /*sandbox*/ None)
|
||||
.await?;
|
||||
@@ -589,7 +589,7 @@ async fn view_image_routes_to_selected_remote_environment() -> anyhow::Result<()
|
||||
))
|
||||
.abs();
|
||||
let image_path = remote_cwd.join("remote.png");
|
||||
let remote_cwd_uri = PathUri::from_path(&remote_cwd)?;
|
||||
let remote_cwd_uri = PathUri::from_host_native_path(&remote_cwd)?;
|
||||
test.fs()
|
||||
.create_directory(
|
||||
&remote_cwd_uri,
|
||||
@@ -598,7 +598,7 @@ async fn view_image_routes_to_selected_remote_environment() -> anyhow::Result<()
|
||||
)
|
||||
.await?;
|
||||
let png = png_bytes(/*width*/ 1, /*height*/ 1, [0, 255, 0, 255])?;
|
||||
let image_path_uri = PathUri::from_path(&image_path)?;
|
||||
let image_path_uri = PathUri::from_host_native_path(&image_path)?;
|
||||
test.fs()
|
||||
.write_file(&image_path_uri, png, /*sandbox*/ None)
|
||||
.await?;
|
||||
|
||||
@@ -1151,8 +1151,10 @@ mod tests {
|
||||
.start(crate::ExecParams {
|
||||
process_id: ProcessId::from("default-env-proc"),
|
||||
argv: vec!["true".to_string()],
|
||||
cwd: PathUri::from_path(std::env::current_dir().expect("read current dir"))
|
||||
.expect("cwd URI"),
|
||||
cwd: PathUri::from_host_native_path(
|
||||
std::env::current_dir().expect("read current dir"),
|
||||
)
|
||||
.expect("cwd URI"),
|
||||
env_policy: None,
|
||||
env: Default::default(),
|
||||
tty: false,
|
||||
@@ -1188,8 +1190,10 @@ mod tests {
|
||||
.start(crate::ExecParams {
|
||||
process_id: ProcessId::from("local-sandbox-proc"),
|
||||
argv: vec!["true".to_string()],
|
||||
cwd: PathUri::from_path(std::env::current_dir().expect("read current dir"))
|
||||
.expect("cwd URI"),
|
||||
cwd: PathUri::from_host_native_path(
|
||||
std::env::current_dir().expect("read current dir"),
|
||||
)
|
||||
.expect("cwd URI"),
|
||||
env_policy: None,
|
||||
env: Default::default(),
|
||||
tty: false,
|
||||
|
||||
@@ -314,8 +314,9 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn helper_protocol_uses_path_uris() -> serde_json::Result<()> {
|
||||
let local_path = PathUri::from_path(std::env::current_dir().expect("cwd").join("file"))
|
||||
.expect("path URI");
|
||||
let local_path =
|
||||
PathUri::from_host_native_path(std::env::current_dir().expect("cwd").join("file"))
|
||||
.expect("path URI");
|
||||
let paths = [
|
||||
local_path,
|
||||
PathUri::parse("file://server/share/file").expect("path URI"),
|
||||
|
||||
@@ -956,7 +956,8 @@ mod tests {
|
||||
ExecParams {
|
||||
process_id: ProcessId::from("env-test"),
|
||||
argv: vec!["true".to_string()],
|
||||
cwd: PathUri::from_path(std::env::current_dir().expect("cwd")).expect("cwd URI"),
|
||||
cwd: PathUri::from_host_native_path(std::env::current_dir().expect("cwd"))
|
||||
.expect("cwd URI"),
|
||||
env_policy: None,
|
||||
env,
|
||||
tty: false,
|
||||
|
||||
@@ -519,7 +519,7 @@ mod tests {
|
||||
let legacy_cwd = std::env::current_dir().expect("current directory");
|
||||
let native_sandbox = FileSystemSandboxContext::from_permission_profile_with_cwd(
|
||||
PermissionProfile::default(),
|
||||
PathUri::from_path(&legacy_cwd).expect("cwd URI"),
|
||||
PathUri::from_host_native_path(&legacy_cwd).expect("cwd URI"),
|
||||
);
|
||||
let mut legacy_sandbox =
|
||||
serde_json::to_value(&native_sandbox).expect("sandbox should serialize");
|
||||
@@ -531,7 +531,7 @@ mod tests {
|
||||
.expect("legacy absolute path should deserialize");
|
||||
let expected_sandbox = native_sandbox;
|
||||
let expected = FsReadFileParams {
|
||||
path: PathUri::from_path(legacy_path).expect("path URI"),
|
||||
path: PathUri::from_host_native_path(legacy_path).expect("path URI"),
|
||||
sandbox: Some(expected_sandbox.clone()),
|
||||
};
|
||||
|
||||
|
||||
@@ -274,7 +274,7 @@ mod tests {
|
||||
)
|
||||
.expect("runtime paths");
|
||||
let handler = FileSystemHandler::new(runtime_paths);
|
||||
let sandbox_cwd = PathUri::from_path(temp_dir.path()).expect("tempdir URI");
|
||||
let sandbox_cwd = PathUri::from_host_native_path(temp_dir.path()).expect("tempdir URI");
|
||||
let sandbox_context = |sandbox_policy| {
|
||||
FileSystemSandboxContext::from_legacy_sandbox_policy(
|
||||
sandbox_policy,
|
||||
@@ -292,7 +292,8 @@ mod tests {
|
||||
},
|
||||
),
|
||||
] {
|
||||
let path = PathUri::from_path(temp_dir.path().join(file_name)).expect("path URI");
|
||||
let path =
|
||||
PathUri::from_host_native_path(temp_dir.path().join(file_name)).expect("path URI");
|
||||
|
||||
handler
|
||||
.write_file(FsWriteFileParams {
|
||||
@@ -312,7 +313,7 @@ mod tests {
|
||||
.expect("canonicalize file");
|
||||
assert_eq!(
|
||||
canonicalized.path,
|
||||
PathUri::from_path(
|
||||
PathUri::from_host_native_path(
|
||||
std::fs::canonicalize(temp_dir.path().join(file_name)).expect("canonical path"),
|
||||
)
|
||||
.expect("canonical path URI"),
|
||||
|
||||
@@ -27,7 +27,8 @@ fn exec_params_with_argv(process_id: &str, argv: Vec<String>) -> ExecParams {
|
||||
ExecParams {
|
||||
process_id: ProcessId::from(process_id),
|
||||
argv,
|
||||
cwd: PathUri::from_path(std::env::current_dir().expect("cwd")).expect("cwd URI"),
|
||||
cwd: PathUri::from_host_native_path(std::env::current_dir().expect("cwd"))
|
||||
.expect("cwd URI"),
|
||||
env_policy: None,
|
||||
env: inherited_path_env(),
|
||||
tty: false,
|
||||
|
||||
@@ -432,7 +432,8 @@ mod tests {
|
||||
ExecParams {
|
||||
process_id,
|
||||
argv: sleep_then_print_argv(),
|
||||
cwd: PathUri::from_path(std::env::current_dir().expect("cwd")).expect("cwd URI"),
|
||||
cwd: PathUri::from_host_native_path(std::env::current_dir().expect("cwd"))
|
||||
.expect("cwd URI"),
|
||||
env_policy: None,
|
||||
env,
|
||||
tty: false,
|
||||
|
||||
@@ -75,7 +75,7 @@ async fn assert_exec_process_starts_and_exits(use_remote: bool) -> Result<()> {
|
||||
.start(ExecParams {
|
||||
process_id: ProcessId::from("proc-1"),
|
||||
argv: vec!["true".to_string()],
|
||||
cwd: PathUri::from_path(std::env::current_dir()?)?,
|
||||
cwd: PathUri::from_host_native_path(std::env::current_dir()?)?,
|
||||
env_policy: /*env_policy*/ None,
|
||||
env: Default::default(),
|
||||
tty: false,
|
||||
@@ -218,7 +218,7 @@ async fn assert_exec_process_streams_output(use_remote: bool) -> Result<()> {
|
||||
"-c".to_string(),
|
||||
"sleep 0.05; printf 'session output\\n'".to_string(),
|
||||
],
|
||||
cwd: PathUri::from_path(std::env::current_dir()?)?,
|
||||
cwd: PathUri::from_host_native_path(std::env::current_dir()?)?,
|
||||
env_policy: /*env_policy*/ None,
|
||||
env: Default::default(),
|
||||
tty: false,
|
||||
@@ -251,7 +251,7 @@ async fn assert_exec_process_pushes_events(use_remote: bool) -> Result<()> {
|
||||
"-c".to_string(),
|
||||
"printf 'event output\\n'; sleep 0.1; printf 'event err\\n' >&2; sleep 0.1; exit 7".to_string(),
|
||||
],
|
||||
cwd: PathUri::from_path(std::env::current_dir()?)?,
|
||||
cwd: PathUri::from_host_native_path(std::env::current_dir()?)?,
|
||||
env_policy: /*env_policy*/ None,
|
||||
env: Default::default(),
|
||||
tty: false,
|
||||
@@ -300,7 +300,7 @@ async fn assert_exec_process_replays_events_after_close(use_remote: bool) -> Res
|
||||
"-c".to_string(),
|
||||
"printf 'late one\\n'; printf 'late two\\n'".to_string(),
|
||||
],
|
||||
cwd: PathUri::from_path(std::env::current_dir()?)?,
|
||||
cwd: PathUri::from_host_native_path(std::env::current_dir()?)?,
|
||||
env_policy: /*env_policy*/ None,
|
||||
env: Default::default(),
|
||||
tty: false,
|
||||
@@ -350,7 +350,7 @@ async fn assert_exec_process_retains_output_after_exit_until_streams_close(
|
||||
DELAYED_OUTPUT_AFTER_EXIT_PARENT_ARG.to_string(),
|
||||
release_path.to_string_lossy().into_owned(),
|
||||
],
|
||||
cwd: PathUri::from_path(std::env::current_dir()?)?,
|
||||
cwd: PathUri::from_host_native_path(std::env::current_dir()?)?,
|
||||
env_policy: /*env_policy*/ None,
|
||||
env: Default::default(),
|
||||
tty: false,
|
||||
@@ -425,7 +425,7 @@ async fn assert_exec_process_write_then_read(use_remote: bool) -> Result<()> {
|
||||
"-c".to_string(),
|
||||
"IFS= read line; printf 'from-stdin:%s\\n' \"$line\"".to_string(),
|
||||
],
|
||||
cwd: PathUri::from_path(std::env::current_dir()?)?,
|
||||
cwd: PathUri::from_host_native_path(std::env::current_dir()?)?,
|
||||
env_policy: /*env_policy*/ None,
|
||||
env: Default::default(),
|
||||
tty: true,
|
||||
@@ -464,7 +464,7 @@ async fn assert_exec_process_write_then_read_without_tty(use_remote: bool) -> Re
|
||||
"-c".to_string(),
|
||||
"IFS= read line; printf 'from-stdin:%s\\n' \"$line\"".to_string(),
|
||||
],
|
||||
cwd: PathUri::from_path(std::env::current_dir()?)?,
|
||||
cwd: PathUri::from_host_native_path(std::env::current_dir()?)?,
|
||||
env_policy: /*env_policy*/ None,
|
||||
env: Default::default(),
|
||||
tty: false,
|
||||
@@ -499,7 +499,7 @@ async fn assert_exec_process_rejects_write_without_pipe_stdin(use_remote: bool)
|
||||
"-c".to_string(),
|
||||
"sleep 0.3; if IFS= read -r line; then printf 'read:%s\\n' \"$line\"; else printf 'eof\\n'; fi".to_string(),
|
||||
],
|
||||
cwd: PathUri::from_path(std::env::current_dir()?)?,
|
||||
cwd: PathUri::from_host_native_path(std::env::current_dir()?)?,
|
||||
env_policy: /*env_policy*/ None,
|
||||
env: Default::default(),
|
||||
tty: false,
|
||||
@@ -535,7 +535,7 @@ async fn assert_exec_process_signal_interrupts_process(use_remote: bool) -> Resu
|
||||
"-c".to_string(),
|
||||
"trap 'printf \"signal:2\\n\"; exit 7' INT; printf 'ready\\n'; while :; do :; done".to_string(),
|
||||
],
|
||||
cwd: PathUri::from_path(std::env::current_dir()?)?,
|
||||
cwd: PathUri::from_host_native_path(std::env::current_dir()?)?,
|
||||
env_policy: /*env_policy*/ None,
|
||||
env: Default::default(),
|
||||
tty: false,
|
||||
@@ -590,7 +590,7 @@ async fn assert_exec_process_signal_reports_unsupported_on_windows(use_remote: b
|
||||
"/C".to_string(),
|
||||
"echo ready && ping -n 30 127.0.0.1 >NUL".to_string(),
|
||||
],
|
||||
cwd: PathUri::from_path(std::env::current_dir()?)?,
|
||||
cwd: PathUri::from_host_native_path(std::env::current_dir()?)?,
|
||||
env_policy: /*env_policy*/ None,
|
||||
env: Default::default(),
|
||||
tty: false,
|
||||
@@ -632,7 +632,7 @@ async fn assert_exec_process_preserves_queued_events_before_subscribe(
|
||||
"-c".to_string(),
|
||||
"printf 'queued output\\n'".to_string(),
|
||||
],
|
||||
cwd: PathUri::from_path(std::env::current_dir()?)?,
|
||||
cwd: PathUri::from_host_native_path(std::env::current_dir()?)?,
|
||||
env_policy: /*env_policy*/ None,
|
||||
env: Default::default(),
|
||||
tty: false,
|
||||
@@ -683,7 +683,7 @@ async fn remote_exec_process_recovers_after_transport_disconnect() -> Result<()>
|
||||
)
|
||||
.to_string(),
|
||||
],
|
||||
cwd: PathUri::from_path(std::env::current_dir()?)?,
|
||||
cwd: PathUri::from_host_native_path(std::env::current_dir()?)?,
|
||||
env_policy: /*env_policy*/ None,
|
||||
env: HashMap::from([
|
||||
(
|
||||
|
||||
@@ -45,7 +45,10 @@ async fn stream_stops_after_an_exact_block_boundary() -> Result<()> {
|
||||
std::fs::write(&path, vec![b'x'; BLOCK_SIZE * 2])?;
|
||||
|
||||
let chunks = file_system
|
||||
.read_file_stream(&PathUri::from_path(path)?, /*sandbox*/ None)
|
||||
.read_file_stream(
|
||||
&PathUri::from_host_native_path(path)?,
|
||||
/*sandbox*/ None,
|
||||
)
|
||||
.await?
|
||||
.try_collect::<Vec<_>>()
|
||||
.await?;
|
||||
@@ -64,7 +67,7 @@ async fn completed_streams_release_handle_capacity() -> Result<()> {
|
||||
let tmp = TempDir::new()?;
|
||||
let path = tmp.path().join("repeated.txt");
|
||||
std::fs::write(&path, b"repeated")?;
|
||||
let path = PathUri::from_path(path)?;
|
||||
let path = PathUri::from_host_native_path(path)?;
|
||||
|
||||
for _ in 0..=OPEN_FILE_LIMIT {
|
||||
let chunks = file_system
|
||||
@@ -88,7 +91,7 @@ async fn stream_rejects_platform_sandbox() -> Result<()> {
|
||||
|
||||
let result = file_system
|
||||
.read_file_stream(
|
||||
&PathUri::from_path(&path)?,
|
||||
&PathUri::from_host_native_path(&path)?,
|
||||
Some(&read_only_sandbox(tmp.path().to_path_buf())),
|
||||
)
|
||||
.await;
|
||||
@@ -120,7 +123,7 @@ async fn file_reads_reject_fifo_without_waiting_for_a_writer() -> Result<()> {
|
||||
);
|
||||
}
|
||||
|
||||
let path_uri = PathUri::from_path(&path)?;
|
||||
let path_uri = PathUri::from_host_native_path(&path)?;
|
||||
let read_error = timeout(
|
||||
Duration::from_secs(1),
|
||||
file_system.read_file(&path_uri, /*sandbox*/ None),
|
||||
@@ -158,7 +161,7 @@ async fn file_reads_reject_named_pipes() -> Result<()> {
|
||||
let read_error = timeout(
|
||||
Duration::from_secs(1),
|
||||
file_system.read_file(
|
||||
&PathUri::from_path(std::path::Path::new(&read_path))?,
|
||||
&PathUri::from_host_native_path(std::path::Path::new(&read_path))?,
|
||||
/*sandbox*/ None,
|
||||
),
|
||||
)
|
||||
@@ -173,7 +176,7 @@ async fn file_reads_reject_named_pipes() -> Result<()> {
|
||||
let stream_result = timeout(
|
||||
Duration::from_secs(1),
|
||||
file_system.read_file_stream(
|
||||
&PathUri::from_path(std::path::Path::new(&stream_path))?,
|
||||
&PathUri::from_host_native_path(std::path::Path::new(&stream_path))?,
|
||||
/*sandbox*/ None,
|
||||
),
|
||||
)
|
||||
@@ -202,7 +205,10 @@ async fn stream_keeps_reading_the_open_file_after_path_replacement() -> Result<(
|
||||
let path = tmp.path().join("replaceable.bin");
|
||||
std::fs::write(&path, vec![b'a'; BLOCK_SIZE + 1])?;
|
||||
let mut stream = file_system
|
||||
.read_file_stream(&PathUri::from_path(&path)?, /*sandbox*/ None)
|
||||
.read_file_stream(
|
||||
&PathUri::from_host_native_path(&path)?,
|
||||
/*sandbox*/ None,
|
||||
)
|
||||
.await?;
|
||||
|
||||
assert_eq!(
|
||||
@@ -236,7 +242,7 @@ async fn read_block_supports_non_sequential_offsets_and_lengths() -> Result<()>
|
||||
let open = client
|
||||
.fs_open(FsOpenParams {
|
||||
handle_id: Uuid::new_v4().simple().to_string(),
|
||||
path: PathUri::from_path(path)?,
|
||||
path: PathUri::from_host_native_path(path)?,
|
||||
sandbox: None,
|
||||
})
|
||||
.await?;
|
||||
@@ -295,7 +301,7 @@ async fn open_enforces_the_per_connection_limit_and_close_releases_capacity() ->
|
||||
let tmp = TempDir::new()?;
|
||||
let path = tmp.path().join("limited.bin");
|
||||
std::fs::write(&path, b"limited")?;
|
||||
let path = PathUri::from_path(path)?;
|
||||
let path = PathUri::from_host_native_path(path)?;
|
||||
let mut handles = Vec::with_capacity(OPEN_FILE_LIMIT);
|
||||
for _ in 0..OPEN_FILE_LIMIT {
|
||||
let open = client
|
||||
@@ -359,7 +365,7 @@ async fn open_rejects_handle_ids_longer_than_32_bytes() -> Result<()> {
|
||||
let error = client
|
||||
.fs_open(FsOpenParams {
|
||||
handle_id: "x".repeat(33),
|
||||
path: PathUri::from_path(path)?,
|
||||
path: PathUri::from_host_native_path(path)?,
|
||||
sandbox: None,
|
||||
})
|
||||
.await
|
||||
|
||||
@@ -66,7 +66,10 @@ async fn file_system_get_metadata_reports_files_and_directories(
|
||||
std::fs::create_dir(&directory_path)?;
|
||||
|
||||
let file_metadata = file_system
|
||||
.get_metadata(&PathUri::from_path(&file_path)?, /*sandbox*/ None)
|
||||
.get_metadata(
|
||||
&PathUri::from_host_native_path(&file_path)?,
|
||||
/*sandbox*/ None,
|
||||
)
|
||||
.await
|
||||
.with_context(|| format!("mode={implementation}"))?;
|
||||
assert_eq!(
|
||||
@@ -83,7 +86,10 @@ async fn file_system_get_metadata_reports_files_and_directories(
|
||||
assert!(file_metadata.modified_at_ms > 0);
|
||||
|
||||
let directory_metadata = file_system
|
||||
.get_metadata(&PathUri::from_path(&directory_path)?, /*sandbox*/ None)
|
||||
.get_metadata(
|
||||
&PathUri::from_host_native_path(&directory_path)?,
|
||||
/*sandbox*/ None,
|
||||
)
|
||||
.await
|
||||
.with_context(|| format!("mode={implementation}"))?;
|
||||
assert_eq!(
|
||||
@@ -116,7 +122,7 @@ async fn file_system_create_directory_creates_nested_directories(
|
||||
|
||||
file_system
|
||||
.create_directory(
|
||||
&PathUri::from_path(&nested_dir)?,
|
||||
&PathUri::from_host_native_path(&nested_dir)?,
|
||||
CreateDirectoryOptions { recursive: true },
|
||||
/*sandbox*/ None,
|
||||
)
|
||||
@@ -140,7 +146,7 @@ async fn file_system_write_file_writes_bytes(
|
||||
let file_path = tmp.path().join("note.txt");
|
||||
file_system
|
||||
.write_file(
|
||||
&PathUri::from_path(&file_path)?,
|
||||
&PathUri::from_host_native_path(&file_path)?,
|
||||
b"hello from trait".to_vec(),
|
||||
/*sandbox*/ None,
|
||||
)
|
||||
@@ -155,21 +161,21 @@ async fn file_system_write_file_writes_bytes(
|
||||
fn path_uri_join_and_parent_preserve_lexical_paths() -> Result<()> {
|
||||
let tmp = TempDir::new()?;
|
||||
let source_dir = tmp.path().join("source");
|
||||
let source_dir_uri = PathUri::from_path(&source_dir)?;
|
||||
let source_dir_uri = PathUri::from_host_native_path(&source_dir)?;
|
||||
let joined_nested = source_dir_uri.join("nested/note.txt")?;
|
||||
assert_eq!(
|
||||
joined_nested,
|
||||
PathUri::from_path(source_dir.join("nested").join("note.txt"))?
|
||||
PathUri::from_host_native_path(source_dir.join("nested").join("note.txt"))?
|
||||
);
|
||||
let joined_parent = joined_nested.parent();
|
||||
assert_eq!(
|
||||
joined_parent,
|
||||
Some(PathUri::from_path(source_dir.join("nested"))?)
|
||||
Some(PathUri::from_host_native_path(source_dir.join("nested"))?)
|
||||
);
|
||||
let joined_parent_traversal = source_dir_uri.join("../outside")?;
|
||||
assert_eq!(
|
||||
joined_parent_traversal,
|
||||
PathUri::from_path(source_dir.join("../outside"))?
|
||||
PathUri::from_host_native_path(source_dir.join("../outside"))?
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
@@ -188,7 +194,10 @@ async fn file_system_read_file_returns_bytes(
|
||||
std::fs::write(&file_path, "hello from trait")?;
|
||||
|
||||
let contents = file_system
|
||||
.read_file(&PathUri::from_path(&file_path)?, /*sandbox*/ None)
|
||||
.read_file(
|
||||
&PathUri::from_host_native_path(&file_path)?,
|
||||
/*sandbox*/ None,
|
||||
)
|
||||
.await
|
||||
.with_context(|| format!("mode={implementation}"))?;
|
||||
assert_eq!(contents, b"hello from trait");
|
||||
@@ -213,7 +222,10 @@ async fn file_system_read_file_stream_returns_bounded_chunks(
|
||||
std::fs::write(&file_path, &contents)?;
|
||||
|
||||
let chunks = file_system
|
||||
.read_file_stream(&PathUri::from_path(file_path)?, /*sandbox*/ None)
|
||||
.read_file_stream(
|
||||
&PathUri::from_host_native_path(file_path)?,
|
||||
/*sandbox*/ None,
|
||||
)
|
||||
.await
|
||||
.with_context(|| format!("mode={implementation}"))?
|
||||
.try_collect::<Vec<_>>()
|
||||
@@ -249,7 +261,10 @@ async fn file_system_read_file_text_returns_string(
|
||||
std::fs::write(&file_path, "hello from trait")?;
|
||||
|
||||
let contents = file_system
|
||||
.read_file_text(&PathUri::from_path(&file_path)?, /*sandbox*/ None)
|
||||
.read_file_text(
|
||||
&PathUri::from_host_native_path(&file_path)?,
|
||||
/*sandbox*/ None,
|
||||
)
|
||||
.await
|
||||
.with_context(|| format!("mode={implementation}"))?;
|
||||
assert_eq!(contents, "hello from trait");
|
||||
@@ -271,8 +286,8 @@ async fn file_system_copy_copies_file(implementation: FileSystemImplementation)
|
||||
|
||||
file_system
|
||||
.copy(
|
||||
&PathUri::from_path(&source_file)?,
|
||||
&PathUri::from_path(&copied_file)?,
|
||||
&PathUri::from_host_native_path(&source_file)?,
|
||||
&PathUri::from_host_native_path(&copied_file)?,
|
||||
CopyOptions { recursive: false },
|
||||
/*sandbox*/ None,
|
||||
)
|
||||
@@ -302,8 +317,8 @@ async fn file_system_copy_copies_directory_recursively(
|
||||
|
||||
file_system
|
||||
.copy(
|
||||
&PathUri::from_path(&source_dir)?,
|
||||
&PathUri::from_path(&copied_dir)?,
|
||||
&PathUri::from_host_native_path(&source_dir)?,
|
||||
&PathUri::from_host_native_path(&copied_dir)?,
|
||||
CopyOptions { recursive: true },
|
||||
/*sandbox*/ None,
|
||||
)
|
||||
@@ -332,7 +347,10 @@ async fn file_system_read_directory_lists_entries(
|
||||
std::fs::write(source_dir.join("root.txt"), "hello")?;
|
||||
|
||||
let mut entries = file_system
|
||||
.read_directory(&PathUri::from_path(&source_dir)?, /*sandbox*/ None)
|
||||
.read_directory(
|
||||
&PathUri::from_host_native_path(&source_dir)?,
|
||||
/*sandbox*/ None,
|
||||
)
|
||||
.await
|
||||
.with_context(|| format!("mode={implementation}"))?;
|
||||
entries.sort_by(|left, right| left.file_name.cmp(&right.file_name));
|
||||
@@ -370,7 +388,7 @@ async fn file_system_remove_removes_directory(
|
||||
|
||||
file_system
|
||||
.remove(
|
||||
&PathUri::from_path(&directory_path)?,
|
||||
&PathUri::from_host_native_path(&directory_path)?,
|
||||
RemoveOptions {
|
||||
recursive: true,
|
||||
force: true,
|
||||
@@ -398,7 +416,7 @@ async fn file_system_write_file_reports_missing_parent(
|
||||
|
||||
let error = match file_system
|
||||
.write_file(
|
||||
&PathUri::from_path(&missing_parent_path)?,
|
||||
&PathUri::from_host_native_path(&missing_parent_path)?,
|
||||
b"hello from trait".to_vec(),
|
||||
/*sandbox*/ None,
|
||||
)
|
||||
@@ -432,8 +450,8 @@ async fn file_system_copy_rejects_directory_without_recursive(
|
||||
|
||||
let error = file_system
|
||||
.copy(
|
||||
&PathUri::from_path(&source_dir)?,
|
||||
&PathUri::from_path(tmp.path().join("dest"))?,
|
||||
&PathUri::from_host_native_path(&source_dir)?,
|
||||
&PathUri::from_host_native_path(tmp.path().join("dest"))?,
|
||||
CopyOptions { recursive: false },
|
||||
/*sandbox*/ None,
|
||||
)
|
||||
@@ -465,7 +483,7 @@ async fn file_system_sandboxed_metadata_and_read_allow_readable_root(
|
||||
let sandbox = read_only_sandbox(allowed_dir);
|
||||
|
||||
let metadata = file_system
|
||||
.get_metadata(&PathUri::from_path(&file_path)?, Some(&sandbox))
|
||||
.get_metadata(&PathUri::from_host_native_path(&file_path)?, Some(&sandbox))
|
||||
.await
|
||||
.with_context(|| format!("mode={implementation}"))?;
|
||||
assert_eq!(
|
||||
@@ -481,7 +499,7 @@ async fn file_system_sandboxed_metadata_and_read_allow_readable_root(
|
||||
);
|
||||
|
||||
let contents = file_system
|
||||
.read_file(&PathUri::from_path(&file_path)?, Some(&sandbox))
|
||||
.read_file(&PathUri::from_host_native_path(&file_path)?, Some(&sandbox))
|
||||
.await
|
||||
.with_context(|| format!("mode={implementation}"))?;
|
||||
assert_eq!(contents, b"sandboxed hello");
|
||||
@@ -505,8 +523,8 @@ pub(crate) async fn assert_canonicalize_resolves_directory_alias(
|
||||
std::fs::write(&file_path, "canonical hello")?;
|
||||
create_directory_alias(&source_dir, &alias_dir)?;
|
||||
|
||||
let requested_path = PathUri::from_path(alias_dir.join("nested").join("note.txt"))?;
|
||||
let expected_path = PathUri::from_path(std::fs::canonicalize(&file_path)?)?;
|
||||
let requested_path = PathUri::from_host_native_path(alias_dir.join("nested").join("note.txt"))?;
|
||||
let expected_path = PathUri::from_host_native_path(std::fs::canonicalize(&file_path)?)?;
|
||||
assert_ne!(requested_path, expected_path);
|
||||
|
||||
let canonical_path = file_system
|
||||
@@ -535,8 +553,8 @@ pub(crate) async fn assert_sandboxed_canonicalize_resolves_directory_alias(
|
||||
create_directory_alias(&source_dir, &alias_dir)?;
|
||||
let sandbox = read_only_sandbox(tmp.path().to_path_buf());
|
||||
|
||||
let requested_path = PathUri::from_path(alias_dir.join("nested").join("note.txt"))?;
|
||||
let expected_path = PathUri::from_path(std::fs::canonicalize(&file_path)?)?;
|
||||
let requested_path = PathUri::from_host_native_path(alias_dir.join("nested").join("note.txt"))?;
|
||||
let expected_path = PathUri::from_host_native_path(std::fs::canonicalize(&file_path)?)?;
|
||||
assert_ne!(requested_path, expected_path);
|
||||
|
||||
let canonical_path = file_system
|
||||
@@ -591,7 +609,7 @@ async fn file_system_sandboxed_write_allows_additional_write_root(
|
||||
|
||||
file_system
|
||||
.write_file(
|
||||
&PathUri::from_path(&file_path)?,
|
||||
&PathUri::from_host_native_path(&file_path)?,
|
||||
b"created".to_vec(),
|
||||
Some(&sandbox),
|
||||
)
|
||||
@@ -617,8 +635,8 @@ async fn file_system_copy_rejects_copying_directory_into_descendant(
|
||||
|
||||
let error = file_system
|
||||
.copy(
|
||||
&PathUri::from_path(&source_dir)?,
|
||||
&PathUri::from_path(source_dir.join("nested").join("copy"))?,
|
||||
&PathUri::from_host_native_path(&source_dir)?,
|
||||
&PathUri::from_host_native_path(source_dir.join("nested").join("copy"))?,
|
||||
CopyOptions { recursive: true },
|
||||
/*sandbox*/ None,
|
||||
)
|
||||
|
||||
@@ -187,7 +187,7 @@ async fn sandboxed_file_system_helper_finds_bwrap_on_preserved_path() -> Result<
|
||||
|
||||
file_system
|
||||
.write_file(
|
||||
&PathUri::from_path(&file_path)?,
|
||||
&PathUri::from_host_native_path(&file_path)?,
|
||||
b"written through fs helper".to_vec(),
|
||||
Some(&sandbox),
|
||||
)
|
||||
@@ -221,7 +221,10 @@ async fn file_system_get_metadata_reports_symlink_targets(
|
||||
let symlink_path = tmp.path().join("note-link.txt");
|
||||
symlink(&file_path, &symlink_path)?;
|
||||
let symlink_metadata = file_system
|
||||
.get_metadata(&PathUri::from_path(&symlink_path)?, /*sandbox*/ None)
|
||||
.get_metadata(
|
||||
&PathUri::from_host_native_path(&symlink_path)?,
|
||||
/*sandbox*/ None,
|
||||
)
|
||||
.await
|
||||
.with_context(|| format!("mode={implementation}"))?;
|
||||
assert_eq!(
|
||||
@@ -243,7 +246,7 @@ async fn file_system_get_metadata_reports_symlink_targets(
|
||||
symlink(&dir_path, &dir_symlink_path)?;
|
||||
let dir_symlink_metadata = file_system
|
||||
.get_metadata(
|
||||
&PathUri::from_path(&dir_symlink_path)?,
|
||||
&PathUri::from_host_native_path(&dir_symlink_path)?,
|
||||
/*sandbox*/ None,
|
||||
)
|
||||
.await
|
||||
@@ -278,7 +281,7 @@ async fn file_system_sandboxed_write_rejects_unwritable_path(
|
||||
let sandbox = read_only_sandbox(tmp.path().to_path_buf());
|
||||
let error = match file_system
|
||||
.write_file(
|
||||
&PathUri::from_path(&blocked_path)?,
|
||||
&PathUri::from_host_native_path(&blocked_path)?,
|
||||
b"nope".to_vec(),
|
||||
Some(&sandbox),
|
||||
)
|
||||
@@ -314,7 +317,7 @@ async fn file_system_sandboxed_write_allows_explicit_alias_roots(
|
||||
|
||||
file_system
|
||||
.write_file(
|
||||
&PathUri::from_path(&file_path)?,
|
||||
&PathUri::from_host_native_path(&file_path)?,
|
||||
b"created".to_vec(),
|
||||
Some(&sandbox),
|
||||
)
|
||||
@@ -345,7 +348,10 @@ async fn file_system_sandboxed_read_rejects_symlink_escape(
|
||||
let requested_path = allowed_dir.join("link").join("secret.txt");
|
||||
let sandbox = read_only_sandbox(allowed_dir);
|
||||
let error = match file_system
|
||||
.read_file(&PathUri::from_path(&requested_path)?, Some(&sandbox))
|
||||
.read_file(
|
||||
&PathUri::from_host_native_path(&requested_path)?,
|
||||
Some(&sandbox),
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(_) => anyhow::bail!("read should be blocked"),
|
||||
@@ -375,7 +381,7 @@ async fn file_system_sandboxed_read_rejects_symlink_parent_dotdot_escape(
|
||||
symlink(&outside_dir, allowed_dir.join("link"))?;
|
||||
|
||||
let requested_path =
|
||||
PathUri::from_path(allowed_dir.join("link").join("..").join("secret.txt"))?;
|
||||
PathUri::from_host_native_path(allowed_dir.join("link").join("..").join("secret.txt"))?;
|
||||
let sandbox = read_only_sandbox(allowed_dir);
|
||||
let error = match file_system.read_file(&requested_path, Some(&sandbox)).await {
|
||||
Ok(_) => anyhow::bail!("read should fail after path normalization"),
|
||||
@@ -411,7 +417,7 @@ async fn file_system_sandboxed_write_rejects_symlink_escape(
|
||||
let sandbox = workspace_write_sandbox(allowed_dir);
|
||||
let error = match file_system
|
||||
.write_file(
|
||||
&PathUri::from_path(&requested_path)?,
|
||||
&PathUri::from_host_native_path(&requested_path)?,
|
||||
b"nope".to_vec(),
|
||||
Some(&sandbox),
|
||||
)
|
||||
@@ -449,7 +455,7 @@ async fn file_system_sandboxed_write_preserves_existing_hard_link(
|
||||
let sandbox = workspace_write_sandbox(allowed_dir);
|
||||
file_system
|
||||
.write_file(
|
||||
&PathUri::from_path(&hard_link)?,
|
||||
&PathUri::from_host_native_path(&hard_link)?,
|
||||
b"updated through existing hard link\n".to_vec(),
|
||||
Some(&sandbox),
|
||||
)
|
||||
@@ -495,7 +501,7 @@ async fn file_system_create_directory_rejects_symlink_escape(
|
||||
let sandbox = workspace_write_sandbox(allowed_dir);
|
||||
let error = match file_system
|
||||
.create_directory(
|
||||
&PathUri::from_path(&requested_path)?,
|
||||
&PathUri::from_host_native_path(&requested_path)?,
|
||||
CreateDirectoryOptions { recursive: false },
|
||||
Some(&sandbox),
|
||||
)
|
||||
@@ -530,7 +536,10 @@ async fn file_system_read_directory_rejects_symlink_escape(
|
||||
let requested_path = allowed_dir.join("link");
|
||||
let sandbox = read_only_sandbox(allowed_dir);
|
||||
let error = match file_system
|
||||
.read_directory(&PathUri::from_path(&requested_path)?, Some(&sandbox))
|
||||
.read_directory(
|
||||
&PathUri::from_host_native_path(&requested_path)?,
|
||||
Some(&sandbox),
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(_) => anyhow::bail!("read_directory should be blocked"),
|
||||
@@ -562,8 +571,8 @@ async fn file_system_copy_rejects_symlink_escape_destination(
|
||||
let sandbox = workspace_write_sandbox(allowed_dir.clone());
|
||||
let error = match file_system
|
||||
.copy(
|
||||
&PathUri::from_path(allowed_dir.join("source.txt"))?,
|
||||
&PathUri::from_path(&requested_destination)?,
|
||||
&PathUri::from_host_native_path(allowed_dir.join("source.txt"))?,
|
||||
&PathUri::from_host_native_path(&requested_destination)?,
|
||||
CopyOptions { recursive: false },
|
||||
Some(&sandbox),
|
||||
)
|
||||
@@ -600,7 +609,7 @@ async fn file_system_remove_removes_symlink_not_target(
|
||||
let sandbox = workspace_write_sandbox(allowed_dir);
|
||||
file_system
|
||||
.remove(
|
||||
&PathUri::from_path(&symlink_path)?,
|
||||
&PathUri::from_host_native_path(&symlink_path)?,
|
||||
RemoveOptions {
|
||||
recursive: false,
|
||||
force: false,
|
||||
@@ -640,8 +649,8 @@ async fn file_system_copy_preserves_symlink_source(
|
||||
let sandbox = workspace_write_sandbox(allowed_dir.clone());
|
||||
file_system
|
||||
.copy(
|
||||
&PathUri::from_path(&source_symlink)?,
|
||||
&PathUri::from_path(&copied_symlink)?,
|
||||
&PathUri::from_host_native_path(&source_symlink)?,
|
||||
&PathUri::from_host_native_path(&copied_symlink)?,
|
||||
CopyOptions { recursive: false },
|
||||
Some(&sandbox),
|
||||
)
|
||||
@@ -677,7 +686,7 @@ async fn file_system_remove_rejects_symlink_escape(
|
||||
let sandbox = workspace_write_sandbox(allowed_dir);
|
||||
let error = match file_system
|
||||
.remove(
|
||||
&PathUri::from_path(&requested_path)?,
|
||||
&PathUri::from_host_native_path(&requested_path)?,
|
||||
RemoveOptions {
|
||||
recursive: false,
|
||||
force: false,
|
||||
@@ -718,8 +727,8 @@ async fn file_system_copy_rejects_symlink_escape_source(
|
||||
let sandbox = workspace_write_sandbox(allowed_dir);
|
||||
let error = match file_system
|
||||
.copy(
|
||||
&PathUri::from_path(&requested_source)?,
|
||||
&PathUri::from_path(&requested_destination)?,
|
||||
&PathUri::from_host_native_path(&requested_source)?,
|
||||
&PathUri::from_host_native_path(&requested_destination)?,
|
||||
CopyOptions { recursive: false },
|
||||
Some(&sandbox),
|
||||
)
|
||||
@@ -752,8 +761,8 @@ async fn file_system_copy_preserves_symlinks_in_recursive_copy(
|
||||
|
||||
file_system
|
||||
.copy(
|
||||
&PathUri::from_path(&source_dir)?,
|
||||
&PathUri::from_path(&copied_dir)?,
|
||||
&PathUri::from_host_native_path(&source_dir)?,
|
||||
&PathUri::from_host_native_path(&copied_dir)?,
|
||||
CopyOptions { recursive: true },
|
||||
/*sandbox*/ None,
|
||||
)
|
||||
@@ -798,8 +807,8 @@ async fn file_system_copy_ignores_unknown_special_files_in_recursive_copy(
|
||||
|
||||
file_system
|
||||
.copy(
|
||||
&PathUri::from_path(&source_dir)?,
|
||||
&PathUri::from_path(&copied_dir)?,
|
||||
&PathUri::from_host_native_path(&source_dir)?,
|
||||
&PathUri::from_host_native_path(&copied_dir)?,
|
||||
CopyOptions { recursive: true },
|
||||
/*sandbox*/ None,
|
||||
)
|
||||
@@ -837,8 +846,8 @@ async fn file_system_copy_rejects_standalone_fifo_source(
|
||||
|
||||
let error = file_system
|
||||
.copy(
|
||||
&PathUri::from_path(&fifo_path)?,
|
||||
&PathUri::from_path(tmp.path().join("copied"))?,
|
||||
&PathUri::from_host_native_path(&fifo_path)?,
|
||||
&PathUri::from_host_native_path(tmp.path().join("copied"))?,
|
||||
CopyOptions { recursive: false },
|
||||
/*sandbox*/ None,
|
||||
)
|
||||
|
||||
@@ -74,7 +74,10 @@ async fn file_system_remote_fs_helper_respects_windows_sandbox_write_policy() ->
|
||||
let readable_file = readonly_dir.join("readable.txt");
|
||||
std::fs::write(&readable_file, b"readable")?;
|
||||
let read_result = file_system
|
||||
.read_file(&PathUri::from_path(&readable_file)?, Some(&sandbox))
|
||||
.read_file(
|
||||
&PathUri::from_host_native_path(&readable_file)?,
|
||||
Some(&sandbox),
|
||||
)
|
||||
.await;
|
||||
// Some local Windows hosts cannot create restricted tokens. Reaching that
|
||||
// error still proves the remote fs helper went through the Windows sandbox
|
||||
@@ -87,7 +90,7 @@ async fn file_system_remote_fs_helper_respects_windows_sandbox_write_policy() ->
|
||||
let blocked_file = readonly_dir.join("blocked.txt");
|
||||
let error = file_system
|
||||
.write_file(
|
||||
&PathUri::from_path(&blocked_file)?,
|
||||
&PathUri::from_host_native_path(&blocked_file)?,
|
||||
b"blocked".to_vec(),
|
||||
Some(&sandbox),
|
||||
)
|
||||
@@ -104,7 +107,7 @@ async fn file_system_remote_fs_helper_respects_windows_sandbox_write_policy() ->
|
||||
fn read_only_sandbox_for_cwd(cwd: std::path::PathBuf) -> Result<FileSystemSandboxContext> {
|
||||
Ok(FileSystemSandboxContext::from_legacy_sandbox_policy(
|
||||
SandboxPolicy::new_read_only_policy(),
|
||||
PathUri::from_path(cwd)?,
|
||||
PathUri::from_host_native_path(cwd)?,
|
||||
)?)
|
||||
}
|
||||
|
||||
|
||||
@@ -144,7 +144,7 @@ async fn remote_environment_routes_encrypted_exec_server_rpc() -> Result<()> {
|
||||
.exec(ExecParams {
|
||||
process_id: ProcessId::from("proc-1"),
|
||||
argv: vec!["true".to_string()],
|
||||
cwd: PathUri::from_path(std::env::current_dir()?)?,
|
||||
cwd: PathUri::from_host_native_path(std::env::current_dir()?)?,
|
||||
env_policy: None,
|
||||
env: HashMap::new(),
|
||||
tty: false,
|
||||
@@ -167,7 +167,7 @@ async fn remote_environment_routes_encrypted_exec_server_rpc() -> Result<()> {
|
||||
std::fs::write(&large_file_path, &large_file_contents)?;
|
||||
let read_response = client
|
||||
.fs_read_file(FsReadFileParams {
|
||||
path: PathUri::from_path(large_file_path)?,
|
||||
path: PathUri::from_host_native_path(large_file_path)?,
|
||||
sandbox: None,
|
||||
})
|
||||
.await?;
|
||||
|
||||
@@ -488,7 +488,7 @@ impl ExecutorStdioServerLauncher {
|
||||
// before sending an executor request.
|
||||
let argv = Self::process_api_argv(&program, &args).map_err(io::Error::other)?;
|
||||
let env = Self::process_api_env(envs).map_err(io::Error::other)?;
|
||||
let cwd = PathUri::from_path(cwd)?;
|
||||
let cwd = PathUri::from_host_native_path(cwd)?;
|
||||
let process_id = ExecutorProcessTransport::next_process_id();
|
||||
// Start the MCP server process on the executor with raw pipes. `tty=false`
|
||||
// keeps stdout as a clean protocol stream, while `pipe_stdin=true` lets
|
||||
|
||||
@@ -121,7 +121,7 @@ impl PathUri {
|
||||
/// Relative paths are reported as invalid input. Absolute paths without a
|
||||
/// valid URI representation use the fallback documented on
|
||||
/// [`Self::from_abs_path`].
|
||||
pub fn from_path(path: impl AsRef<Path>) -> io::Result<Self> {
|
||||
pub fn from_host_native_path(path: impl AsRef<Path>) -> io::Result<Self> {
|
||||
let path = AbsolutePathBuf::from_absolute_path_checked(path)
|
||||
.map_err(|err| io::Error::new(io::ErrorKind::InvalidInput, err))?;
|
||||
Ok(Self::from_abs_path(&path))
|
||||
|
||||
@@ -423,7 +423,8 @@ fn path_uri_deserializes_legacy_absolute_paths() {
|
||||
|
||||
#[test]
|
||||
fn path_uri_rejects_relative_native_paths() {
|
||||
let error = PathUri::from_path("src/lib.rs").expect_err("relative path should be rejected");
|
||||
let error =
|
||||
PathUri::from_host_native_path("src/lib.rs").expect_err("relative path should be rejected");
|
||||
|
||||
assert_eq!(error.kind(), io::ErrorKind::InvalidInput);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user