diff --git a/crates/xgen-adapter-filesystem/src/atomic_commit.rs b/crates/xgen-adapter-filesystem/src/atomic_commit.rs index 2aad9b0..53c1f1d 100644 --- a/crates/xgen-adapter-filesystem/src/atomic_commit.rs +++ b/crates/xgen-adapter-filesystem/src/atomic_commit.rs @@ -146,7 +146,9 @@ fn open_parent(root: &Dir, path: &RelativePath) -> Result<(Dir, String), AtomicC OpenErrorClass::Missing | OpenErrorClass::NotADirectory => { AtomicCommitFailure::ParentNotFound } - OpenErrorClass::Refused => AtomicCommitFailure::OpenParent, + OpenErrorClass::Directory | OpenErrorClass::Refused => { + AtomicCommitFailure::OpenParent + } } })?; if is_windows_reparse_point( diff --git a/crates/xgen-adapter-filesystem/src/path.rs b/crates/xgen-adapter-filesystem/src/path.rs index 918bba8..51c7db4 100644 --- a/crates/xgen-adapter-filesystem/src/path.rs +++ b/crates/xgen-adapter-filesystem/src/path.rs @@ -73,6 +73,9 @@ pub(crate) enum OpenErrorClass { Missing, /// Something other than a directory exists at the name. NotADirectory, + /// A directory exists at the name. Some platforms refuse to open a directory as a file, so + /// this is how a file open learns that the name has the wrong kind. + Directory, /// The name exists but is refused, such as a symbolic link, or the error is not classified. Refused, } @@ -85,15 +88,16 @@ pub(crate) fn classify_open_error( name: &str, error: &std::io::Error, ) -> OpenErrorClass { - match error.kind() { - std::io::ErrorKind::NotFound => OpenErrorClass::Missing, - std::io::ErrorKind::NotADirectory - if !parent - .symlink_metadata(name) - .is_ok_and(|metadata| metadata.file_type().is_symlink()) => - { - OpenErrorClass::NotADirectory - } + if error.kind() == std::io::ErrorKind::NotFound { + return OpenErrorClass::Missing; + } + let file_type = parent + .symlink_metadata(name) + .map(|metadata| metadata.file_type()); + match file_type { + Ok(file_type) if file_type.is_symlink() => OpenErrorClass::Refused, + _ if error.kind() == std::io::ErrorKind::NotADirectory => OpenErrorClass::NotADirectory, + Ok(file_type) if file_type.is_dir() => OpenErrorClass::Directory, _ => OpenErrorClass::Refused, } } diff --git a/crates/xgen-adapter-filesystem/src/query.rs b/crates/xgen-adapter-filesystem/src/query.rs index 72b9a52..65d1056 100644 --- a/crates/xgen-adapter-filesystem/src/query.rs +++ b/crates/xgen-adapter-filesystem/src/query.rs @@ -1009,7 +1009,7 @@ fn open_directory(root: &Dir, path: &RelativePath) -> Result