Repository navigation
fix(project): classify a path through a regular file as absent on every platform - #501
Conversation
|
CI classification for the |
A directory whose 'src' is a regular file made the src/main.opy default-entry probe fail ENOTDIR, which the #484 classification mapped to EntryUnreadable and the provider to targetUnreadable. An absent intermediate directory names an entry that does not exist, the same as an empty directory, so NotADirectory now joins NotFound in the absent classification: the probe reports DefaultEntryNotFound/targetNotFound. A direct entry path through a regular file (file.opy/child.opy) now carries the not-found reason as well. Windows already reports a not-found error for such paths, so classifying NotADirectory as absent keeps the reason consistent across platforms.
7c4f4ef to
8f3e2a4
Compare
e54-bot
left a comment
There was a problem hiding this comment.
Reviewed at 8f3e2a4 (worktree wt-501-absent-io). Verdict: approve-equivalent — semantics are correct, scoped narrowly, and platform consistency holds.
Semantics: file.opy/child.opy names an entry that cannot exist — an intermediate regular file makes the path unresolvable at lookup, indistinguishable from a missing component — so EntryNotFound/entryNotFound is the right answer to #497's open question, and the commit message states the reason as the issue asked. Cross-platform consistency is robust: on Windows a path through a file surfaces as ERROR_PATH_NOT_FOUND → NotFound, and even if an API returns ERROR_DIRECTORY (267), current Rust maps it to NotADirectory — is_absent covers both, so platforms agree whichever error kind Windows reports.
No over-reach: is_absent (project.rs:70-72) admits only NotFound | NotADirectory. ELOOP → FilesystemLoop and PermissionDenied remain non-absent: unresolvable_entry_is_not_classified_as_missing, unresolvable_default_entry_is_not_classified_as_missing, and unreadable_entry_reports_unreadable still assert EntryUnreadable and pass. is_entry_not_found (project.rs:120-126) still reports the real category for an EntryNotFound carrying a non-absent cause constructed through the public fields.
Coverage: all three classification sites now share is_absent (load canonicalize, default_entry probe, is_entry_not_found); the provider mirrors it in validate_target_kind (main.rs:1113-1116). entry_inside_a_file_is_entry_not_found flips correctly, empty_directory_is_default_entry_not_found pins the parity baseline, and test comments state the verified platform per #497's second criterion. New LPP test asserts targetNotFound end-to-end.
Verification: cargo test -p opy-rs --lib project → 20/20 pass; cargo test -p opy-provider --test lpp (new test + unresolvable_entry_reports_unreadable_reason + contract test) → 3/3 pass.
One low-severity observation, not a blocker: the new LPP test exercises the default_entry path already fixed by #511, so it would pass on #511 alone; the #501-specific provider delta — a file-kind target through a regular file hitting validate_target_kind's NotADirectory arm → entryNotFound — is covered only by the entry_inside_a_file_is_entry_not_found unit test at the load layer, not end-to-end. Fine to leave as-is given the arm is a four-line match, but an LPP case for file.opy/child.opy would close the loop.
The review noted the prior LPP test exercised only the default_entry path; a file-kind entry addressed through a regular file now verifies entryNotFound end to end.
|
Review note addressed: the new LPP test |
Completes #497's cross-platform consistency clause on top of #511 (which landed the
default_entryhalf).Change
A shared
is_absentclassification (NotFound | NotADirectory) now covers every I/O classification site, so a path through a regular file reports the same "absent" answer on Unix (ENOTDIR) and Windows (NotFound):FilesystemProject::loadcanonicalize:file.opy/child.opy→EntryNotFound(wasEntryUnreadableon Unix; Windows already classified it not-found).FilesystemProjectError::is_entry_not_found: anEntryNotFoundcarrying anENOTDIRcause reports not-found.validate_target_kind: same unification for theentryNotFound/targetNotFoundreasons.Test plan
file_named_src_is_default_entry_not_found+empty_directory_is_default_entry_not_foundbaseline parityentry_inside_a_file_is_entry_not_found— the platform-unified classification (comment states verified platform)srcreportstargetNotFoundthrough the providercargo test --workspace --all-targets,cargo fmt,cargo clippy -D warningsclean