Migrate ExecutorFileSystem get_metadata to PathUri

This commit is contained in:
Codex
2026-06-10 06:45:41 +00:00
committed by Adam Perry
parent aea014d745
commit c0dda81226
21 changed files with 126 additions and 45 deletions

View File

@@ -115,9 +115,10 @@ impl FsRequestProcessor {
&self,
params: FsGetMetadataParams,
) -> Result<FsGetMetadataResponse, JSONRPCErrorError> {
let path = PathUri::from_abs_path(&params.path).map_err(map_fs_error)?;
let metadata = self
.file_system()?
.get_metadata(&params.path, /*sandbox*/ None)
.get_metadata(&path, /*sandbox*/ None)
.await
.map_err(map_fs_error)?;
Ok(FsGetMetadataResponse {

View File

@@ -556,7 +556,8 @@ async fn ensure_not_directory(
fs: &dyn ExecutorFileSystem,
sandbox: Option<&FileSystemSandboxContext>,
) -> io::Result<()> {
let metadata = fs.get_metadata(path, sandbox).await?;
let path_uri = PathUri::from_abs_path(path)?;
let metadata = fs.get_metadata(&path_uri, sandbox).await?;
if metadata.is_directory {
return Err(io::Error::new(
io::ErrorKind::InvalidInput,
@@ -614,7 +615,11 @@ async fn note_existing_path_delta_support(
sandbox: Option<&FileSystemSandboxContext>,
exact: &mut bool,
) {
match fs.get_metadata(path, sandbox).await {
let Ok(path_uri) = PathUri::from_abs_path(path) else {
*exact = false;
return;
};
match fs.get_metadata(&path_uri, sandbox).await {
Ok(metadata) if metadata.is_file && !metadata.is_symlink => {}
Ok(_) => *exact = false,
Err(source) if source.kind() == io::ErrorKind::NotFound => {}

View File

@@ -1138,8 +1138,9 @@ async fn find_project_root(
for ancestor in cwd.ancestors() {
for marker in project_root_markers {
let marker_path = ancestor.join(marker);
let marker_path_uri = PathUri::from_abs_path(&marker_path)?;
if fs
.get_metadata(&marker_path, /*sandbox*/ None)
.get_metadata(&marker_path_uri, /*sandbox*/ None)
.await
.is_ok()
{
@@ -1154,14 +1155,20 @@ async fn find_git_checkout_root(
fs: &dyn ExecutorFileSystem,
cwd: &AbsolutePathBuf,
) -> Option<AbsolutePathBuf> {
let base = match fs.get_metadata(cwd, /*sandbox*/ None).await {
let cwd_uri = PathUri::from_abs_path(cwd).ok()?;
let base = match fs.get_metadata(&cwd_uri, /*sandbox*/ None).await {
Ok(metadata) if metadata.is_directory => cwd.clone(),
_ => cwd.parent()?,
};
for dir in base.ancestors() {
let dot_git = dir.join(".git");
if fs.get_metadata(&dot_git, /*sandbox*/ None).await.is_ok() {
let dot_git_uri = PathUri::from_abs_path(&dot_git).ok()?;
if fs
.get_metadata(&dot_git_uri, /*sandbox*/ None)
.await
.is_ok()
{
return Some(dir);
}
}
@@ -1209,8 +1216,9 @@ async fn load_project_layers(
let mut startup_warnings = Vec::new();
for dir in dirs {
let dot_codex_abs = dir.join(".codex");
let dot_codex_uri = PathUri::from_abs_path(&dot_codex_abs)?;
if !fs
.get_metadata(&dot_codex_abs, /*sandbox*/ None)
.get_metadata(&dot_codex_uri, /*sandbox*/ None)
.await
.map(|metadata| metadata.is_directory)
.unwrap_or(false)

View File

@@ -54,7 +54,7 @@ impl ExecutorFileSystem for TestFileSystem {
async fn get_metadata(
&self,
_path: &AbsolutePathBuf,
_path: &PathUri,
_sandbox: Option<&FileSystemSandboxContext>,
) -> FileSystemResult<FileMetadata> {
unimplemented!("test filesystem only supports reads")

View File

@@ -375,7 +375,17 @@ async fn repo_agents_skill_roots(
let mut roots = Vec::new();
for dir in dirs {
let agents_skills = dir.join(AGENTS_DIR_NAME).join(SKILLS_DIR_NAME);
match fs.get_metadata(&agents_skills, /*sandbox*/ None).await {
let agents_skills_uri = match PathUri::from_abs_path(&agents_skills) {
Ok(path) => path,
Err(err) => {
tracing::warn!(
"failed to convert repo skills root {} to URI: {err:#}",
agents_skills.display()
);
continue;
}
};
match fs.get_metadata(&agents_skills_uri, /*sandbox*/ None).await {
Ok(metadata) if metadata.is_directory => roots.push(SkillRoot {
path: agents_skills,
scope: SkillScope::Repo,
@@ -430,7 +440,17 @@ async fn find_project_root(
for ancestor in cwd.ancestors() {
for marker in project_root_markers {
let marker_path = ancestor.join(marker);
match fs.get_metadata(&marker_path, /*sandbox*/ None).await {
let marker_path_uri = match PathUri::from_abs_path(&marker_path) {
Ok(path) => path,
Err(err) => {
tracing::warn!(
"failed to convert project root marker {} to URI: {err:#}",
marker_path.display()
);
continue;
}
};
match fs.get_metadata(&marker_path_uri, /*sandbox*/ None).await {
Ok(_) => return ancestor,
Err(err) if err.kind() == io::ErrorKind::NotFound => {}
Err(err) => {
@@ -499,7 +519,17 @@ async fn discover_skills_under_root(
None => None,
};
match fs.get_metadata(&root, /*sandbox*/ None).await {
let root_uri = match PathUri::from_abs_path(&root) {
Ok(path) => path,
Err(err) => {
tracing::warn!(
"failed to convert skills root {} to URI: {err:#}",
root.display()
);
return;
}
};
match fs.get_metadata(&root_uri, /*sandbox*/ None).await {
Ok(metadata) if metadata.is_directory => {}
Ok(_) => return,
Err(err) if err.kind() == io::ErrorKind::NotFound => return,
@@ -556,7 +586,17 @@ async fn discover_skills_under_root(
}
let path = dir.join(&file_name);
let metadata = match fs.get_metadata(&path, /*sandbox*/ None).await {
let path_uri = match PathUri::from_abs_path(&path) {
Ok(path) => path,
Err(e) => {
tracing::warn!(
"failed to convert skills path {} to URI: {e:#}",
path.display()
);
continue;
}
};
let metadata = match fs.get_metadata(&path_uri, /*sandbox*/ None).await {
Ok(metadata) => metadata,
Err(e) => {
error!("failed to stat skills path {}: {e:#}", path.display());
@@ -747,7 +787,7 @@ async fn load_skill_metadata(
return LoadedSkillMetadata::default();
}
};
match fs.get_metadata(&metadata_path, /*sandbox*/ None).await {
match fs.get_metadata(&metadata_path_uri, /*sandbox*/ None).await {
Ok(metadata) if metadata.is_file => {}
Ok(_) => return LoadedSkillMetadata::default(),
Err(error) if error.kind() == io::ErrorKind::NotFound => {

View File

@@ -163,7 +163,7 @@ impl<'a> AgentsMdManager<'a> {
}
let path_uri = PathUri::from_abs_path(&p)?;
match fs.get_metadata(&p, /*sandbox*/ None).await {
match fs.get_metadata(&path_uri, /*sandbox*/ None).await {
Ok(metadata) if !metadata.is_file => continue,
Ok(_) => {}
Err(err) if err.kind() == io::ErrorKind::NotFound => continue,
@@ -245,12 +245,13 @@ impl<'a> AgentsMdManager<'a> {
for ancestor in dir.ancestors() {
for marker in &project_root_markers {
let marker_path = ancestor.join(marker);
let marker_exists = match fs.get_metadata(&marker_path, /*sandbox*/ None).await
{
Ok(_) => true,
Err(err) if err.kind() == io::ErrorKind::NotFound => false,
Err(err) => return Err(err),
};
let marker_path_uri = PathUri::from_abs_path(&marker_path)?;
let marker_exists =
match fs.get_metadata(&marker_path_uri, /*sandbox*/ None).await {
Ok(_) => true,
Err(err) if err.kind() == io::ErrorKind::NotFound => false,
Err(err) => return Err(err),
};
if marker_exists {
project_root = Some(ancestor.clone());
break;
@@ -286,7 +287,8 @@ impl<'a> AgentsMdManager<'a> {
for d in search_dirs {
for name in &candidate_filenames {
let candidate = d.join(name);
match fs.get_metadata(&candidate, /*sandbox*/ None).await {
let candidate_uri = PathUri::from_abs_path(&candidate)?;
match fs.get_metadata(&candidate_uri, /*sandbox*/ None).await {
Ok(md) if md.is_file => {
found.push(candidate);
break;

View File

@@ -393,8 +393,9 @@ async fn validate_agent_role_config_file(
return Ok(());
};
let config_file_uri = PathUri::from_abs_path(config_file)?;
let metadata = fs
.get_metadata(config_file, /*sandbox*/ None)
.get_metadata(&config_file_uri, /*sandbox*/ None)
.await
.map_err(|e| {
std::io::Error::new(

View File

@@ -153,7 +153,7 @@ impl ViewImageHandler {
})?;
let metadata = fs
.get_metadata(&abs_path, Some(&sandbox))
.get_metadata(&path_uri, Some(&sandbox))
.await
.map_err(|error| {
FunctionCallError::RespondToModel(format!(

View File

@@ -975,7 +975,13 @@ impl TestCodexHarness {
}
pub async fn abs_path_exists(&self, path: &AbsolutePathBuf) -> Result<bool> {
match self.test.fs().get_metadata(path, /*sandbox*/ None).await {
let path_uri = PathUri::from_abs_path(path)?;
match self
.test
.fs()
.get_metadata(&path_uri, /*sandbox*/ None)
.await
{
Ok(_) => Ok(true),
Err(err) if err.kind() == ErrorKind::NotFound => Ok(false),
Err(err) => Err(err.into()),

View File

@@ -1054,7 +1054,10 @@ async fn remote_test_env_remove_removes_symlink_not_target() -> Result<()> {
.await?;
let symlink_exists = file_system
.get_metadata(&absolute_path(symlink_path), /*sandbox*/ None)
.get_metadata(
&PathUri::from_abs_path(&absolute_path(symlink_path))?,
/*sandbox*/ None,
)
.await
.is_ok();
assert!(!symlink_exists);

View File

@@ -231,8 +231,10 @@ pub(crate) async fn run_direct_request(
))
}
FsHelperRequest::GetMetadata(params) => {
let path =
codex_utils_path_uri::PathUri::from_abs_path(&params.path).map_err(map_fs_error)?;
let metadata = file_system
.get_metadata(&params.path, /*sandbox*/ None)
.get_metadata(&path, /*sandbox*/ None)
.await
.map_err(map_fs_error)?;
Ok(FsHelperPayload::GetMetadata(FsGetMetadataResponse {

View File

@@ -120,7 +120,7 @@ impl ExecutorFileSystem for LocalFileSystem {
async fn get_metadata(
&self,
path: &AbsolutePathBuf,
path: &PathUri,
sandbox: Option<&FileSystemSandboxContext>,
) -> FileSystemResult<FileMetadata> {
let (file_system, sandbox) = self.file_system_for(sandbox)?;
@@ -206,7 +206,7 @@ impl ExecutorFileSystem for UnsandboxedFileSystem {
async fn get_metadata(
&self,
path: &AbsolutePathBuf,
path: &PathUri,
sandbox: Option<&FileSystemSandboxContext>,
) -> FileSystemResult<FileMetadata> {
reject_platform_sandbox_context(sandbox)?;
@@ -315,10 +315,11 @@ impl ExecutorFileSystem for DirectFileSystem {
async fn get_metadata(
&self,
path: &AbsolutePathBuf,
path: &PathUri,
sandbox: Option<&FileSystemSandboxContext>,
) -> FileSystemResult<FileMetadata> {
reject_sandbox_context(sandbox)?;
let path = path.to_abs_path()?;
let metadata = tokio::fs::metadata(path.as_path()).await?;
let symlink_metadata = tokio::fs::symlink_metadata(path.as_path()).await?;
Ok(FileMetadata {

View File

@@ -124,14 +124,15 @@ impl ExecutorFileSystem for RemoteFileSystem {
async fn get_metadata(
&self,
path: &AbsolutePathBuf,
path: &PathUri,
sandbox: Option<&FileSystemSandboxContext>,
) -> FileSystemResult<FileMetadata> {
trace!("remote fs get_metadata");
let path = path.to_abs_path()?;
let client = self.client.get().await.map_err(map_remote_error)?;
let response = client
.fs_get_metadata(FsGetMetadataParams {
path: path.clone(),
path,
sandbox: remote_sandbox_context(sandbox),
})
.await

View File

@@ -142,7 +142,7 @@ impl ExecutorFileSystem for SandboxedFileSystem {
async fn get_metadata(
&self,
path: &AbsolutePathBuf,
path: &PathUri,
sandbox: Option<&FileSystemSandboxContext>,
) -> FileSystemResult<FileMetadata> {
let sandbox = require_platform_sandbox(sandbox)?;
@@ -150,7 +150,7 @@ impl ExecutorFileSystem for SandboxedFileSystem {
.run_sandboxed(
sandbox,
FsHelperRequest::GetMetadata(FsGetMetadataParams {
path: path.clone(),
path: path.to_abs_path()?,
sandbox: None,
}),
)

View File

@@ -102,9 +102,10 @@ impl FileSystemHandler {
&self,
params: FsGetMetadataParams,
) -> Result<FsGetMetadataResponse, JSONRPCErrorError> {
let path = PathUri::from_abs_path(&params.path).map_err(map_fs_error)?;
let metadata = self
.file_system
.get_metadata(&params.path, params.sandbox.as_ref())
.get_metadata(&path, params.sandbox.as_ref())
.await
.map_err(map_fs_error)?;
Ok(FsGetMetadataResponse {

View File

@@ -62,7 +62,7 @@ async fn file_system_get_metadata_reports_files_and_directories(
std::fs::create_dir(&directory_path)?;
let file_metadata = file_system
.get_metadata(&absolute_path(&file_path), /*sandbox*/ None)
.get_metadata(&PathUri::from_path(&file_path)?, /*sandbox*/ None)
.await
.with_context(|| format!("mode={implementation}"))?;
assert_eq!(file_metadata.is_directory, false);
@@ -71,7 +71,7 @@ async fn file_system_get_metadata_reports_files_and_directories(
assert!(file_metadata.modified_at_ms > 0);
let directory_metadata = file_system
.get_metadata(&absolute_path(&directory_path), /*sandbox*/ None)
.get_metadata(&PathUri::from_path(&directory_path)?, /*sandbox*/ None)
.await
.with_context(|| format!("mode={implementation}"))?;
assert_eq!(directory_metadata.is_directory, true);

View File

@@ -220,7 +220,7 @@ 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(&absolute_path(&symlink_path), /*sandbox*/ None)
.get_metadata(&PathUri::from_path(&symlink_path)?, /*sandbox*/ None)
.await
.with_context(|| format!("mode={implementation}"))?;
assert_eq!(symlink_metadata.is_directory, false);
@@ -233,7 +233,10 @@ async fn file_system_get_metadata_reports_symlink_targets(
let dir_symlink_path = tmp.path().join("notes-link");
symlink(&dir_path, &dir_symlink_path)?;
let dir_symlink_metadata = file_system
.get_metadata(&absolute_path(&dir_symlink_path), /*sandbox*/ None)
.get_metadata(
&PathUri::from_path(&dir_symlink_path)?,
/*sandbox*/ None,
)
.await
.with_context(|| format!("mode={implementation}"))?;
assert_eq!(dir_symlink_metadata.is_directory, true);

View File

@@ -103,10 +103,10 @@ impl ExecutorFileSystem for SyntheticFileSystem {
async fn get_metadata(
&self,
path: &AbsolutePathBuf,
path: &PathUri,
_sandbox: Option<&FileSystemSandboxContext>,
) -> FileSystemResult<FileMetadata> {
self.metadata(path)
self.metadata(&path.to_abs_path()?)
}
async fn read_directory(

View File

@@ -173,7 +173,7 @@ pub trait ExecutorFileSystem: Send + Sync {
async fn get_metadata(
&self,
path: &AbsolutePathBuf,
path: &PathUri,
sandbox: Option<&FileSystemSandboxContext>,
) -> FileSystemResult<FileMetadata>;

View File

@@ -47,7 +47,8 @@ pub async fn get_git_repo_root_with_fs(
fs: &dyn ExecutorFileSystem,
cwd: &AbsolutePathBuf,
) -> Option<AbsolutePathBuf> {
let base = match fs.get_metadata(cwd, /*sandbox*/ None).await {
let cwd_uri = PathUri::from_abs_path(cwd).ok()?;
let base = match fs.get_metadata(&cwd_uri, /*sandbox*/ None).await {
Ok(metadata) if metadata.is_directory => cwd.clone(),
_ => cwd.parent()?,
};
@@ -806,7 +807,7 @@ pub async fn resolve_root_git_project_for_trust(
let dot_git = repo_root.join(".git");
let dot_git_uri = PathUri::from_abs_path(&dot_git).ok()?;
if fs
.get_metadata(&dot_git, /*sandbox*/ None)
.get_metadata(&dot_git_uri, /*sandbox*/ None)
.await
.ok()?
.is_directory
@@ -858,7 +859,12 @@ async fn find_ancestor_git_entry_with_fs(
) -> Option<(AbsolutePathBuf, AbsolutePathBuf)> {
for dir in base_dir.ancestors() {
let dot_git = dir.join(".git");
if fs.get_metadata(&dot_git, /*sandbox*/ None).await.is_ok() {
let dot_git_uri = PathUri::from_abs_path(&dot_git).ok()?;
if fs
.get_metadata(&dot_git_uri, /*sandbox*/ None)
.await
.is_ok()
{
return Some((dir, dot_git));
}
}

View File

@@ -30,7 +30,8 @@ async fn plugin_manifest_name(
let mut manifest_path = None;
for relative_path in DISCOVERABLE_PLUGIN_MANIFEST_PATHS {
let candidate = plugin_root.join(relative_path);
match fs.get_metadata(&candidate, /*sandbox*/ None).await {
let candidate_uri = PathUri::from_abs_path(&candidate).ok()?;
match fs.get_metadata(&candidate_uri, /*sandbox*/ None).await {
Ok(metadata) if metadata.is_file => {
manifest_path = Some(candidate);
break;