apply-patch: carry paths as PathUri (#28854)

## Why

Allows the model to edit files that are hosted on a different OS than
where app-server is running.

## What

* Use `PathUri` for apply_patch-internal data structures
* Limit `PathUri` -> `AbsolutePathBuf` conversion to cases where the
inferred path convention matches the host OS, allows requiring valid
paths to pass to perms check
* Adds `PathConvention::path_segments()` for iterating over path
segments regardless of OS
* Handle cross-platform relative paths in path filename parsing for
sniffing a shell
* Ensure we can apply patches in the wine e2e test
This commit is contained in:
Adam Perry @ OpenAI authored and GitHub committed 2026-06-18 19:31:19 +00:00
1 parent a52a3b5197
commit 0f89dd768c
20 files changed
+626 -370

No files matched your search

+58 -12
View File
@@ -34,21 +34,24 @@ fn file_uri_round_trips_an_absolute_path() {
#[test]
fn non_native_uri_io_conversion_is_invalid_input() {
#[cfg(unix)]
let uri = PathUri::parse("file://server/share/file.txt").expect("valid file URI");
let uris = ["file://server/share/file.txt", "file:///C:/workspace"];
#[cfg(windows)]
let uri = PathUri::parse("file:///usr/local/file.txt").expect("valid file URI");
let uris = ["file:///usr/local/file.txt"];
let error = uri
.to_abs_path()
.expect_err("URI should not be host-native");
for uri in uris {
let uri = PathUri::parse(uri).expect("valid file URI");
let error = uri
.to_abs_path()
.expect_err("URI should not be host-native");
assert_eq!(
(error.kind(), error.to_string()),
(
io::ErrorKind::InvalidInput,
format!("'{uri}' is invalid on '{}'", std::env::consts::OS),
)
);
assert_eq!(
(error.kind(), error.to_string()),
(
io::ErrorKind::InvalidInput,
format!("'{uri}' is invalid on '{}'", std::env::consts::OS),
)
);
}
}
#[test]
@@ -90,6 +93,35 @@ fn infers_path_conventions_from_uri_shape() {
}
}
#[test]
fn path_convention_splits_absolute_relative_and_bare_path_text() {
for (convention, path, expected) in [
(
PathConvention::Posix,
"/usr/local/bin/bash",
vec!["", "usr", "local", "bin", "bash"],
),
(
PathConvention::Posix,
r"tools\pwsh.exe",
vec![r"tools\pwsh.exe"],
),
(
PathConvention::Windows,
r"C:\Program Files\PowerShell\7\pwsh.exe",
vec!["C:", "Program Files", "PowerShell", "7", "pwsh.exe"],
),
(
PathConvention::Windows,
"tools/pwsh.exe",
vec!["tools", "pwsh.exe"],
),
(PathConvention::Windows, "cmd.exe", vec!["cmd.exe"]),
] {
assert_eq!(convention.path_segments(path).collect::<Vec<_>>(), expected);
}
}
#[test]
fn drive_shaped_posix_uri_is_intentionally_inferred_as_windows() {
let path = PathUri::parse("file:///C:/actually/a/posix/path").expect("valid path URI");
@@ -475,6 +507,20 @@ fn basename_uses_decoded_uri_segments() {
}
}
#[test]
fn path_buf_uses_the_inferred_native_spelling() {
let windows = PathUri::parse("file:///C:/Program%20Files/pwsh.exe").expect("Windows URI");
let posix = PathUri::parse("file:///usr/local/bin/bash").expect("POSIX URI");
assert_eq!(
(windows.to_path_buf(), posix.to_path_buf()),
(
PathBuf::from(r"C:\Program Files\pwsh.exe"),
PathBuf::from("/usr/local/bin/bash"),
)
);
}
#[test]
fn parent_uses_uri_hierarchy_and_preserves_authority() {
for (input, expected) in [