Skip to content

fix(path): normalize package-relative path joins#128

Merged
raphaelvigee merged 1 commit into
masterfrom
fix/pkg-rel-path-normalization
Jun 25, 2026
Merged

fix(path): normalize package-relative path joins#128
raphaelvigee merged 1 commit into
masterfrom
fix/pkg-rel-path-normalization

Conversation

@raphaelvigee

@raphaelvigee raphaelvigee commented Jun 25, 2026

Copy link
Copy Markdown
Member

Problem

Spotted in a generated .gitignore:

/some/./path.yaml # //some:gen

The stray ./ mid-path is a path-normalization smell. Root cause is not gitignore-specific: package-relative paths were joined with a bare format!("{pkg}/{rel}") that left ./.. segments intact. A ./openapi/... output declared in a BUILD file became pkg/./openapi/... and flowed straight through to every consumer (gitignore just rendered it visibly).

Fix

Single normalizing join helper in hmodel::htpkg:

  • join_rel_checked(pkg, rel) — lexically normalizes (drop ./empty, resolve ..), preserves a trailing slash (DirPath classification) and glob metacharacters, and hard-errors when a .. escapes the workspace root.

Routed all three package-relative join sites through it:

  • plugin-exec spec_path_to_target_path — the output/support-path producer (the reported bug)
  • plugin-buildfile resolve_fs_pathheph.file / heph.glob
  • builtins heph.fs.glob — replaces its local format! + normalize_path

Declaring a path outside the workspace root is now a hard error at every site, rather than a silently-mangled path.

Also derives Debug on the public path::Path / Content types (per the Debug-on-public-types guideline; needed for Result assertions in tests).

Tests

  • hmodel::htpkg unit tests: ./empty collapse, .. resolution, trailing-slash + glob-metachar preservation, root-escape error.
  • plugin-exec test freezing spec_path_to_target_path normalization, File/Dir/Glob classification, and the escape hard-error.

All touched-crate tests pass; cargo clippy -- -D warnings clean; full workspace builds.

🤖 Generated with Claude Code

Output and fs paths declared relative to a package were joined with a
bare `format!("{pkg}/{rel}")`, leaving `.` and `..` segments in the
result. A `./`-prefixed output surfaced as `pkg/./sub/file` — visible in
the generated .gitignore, but a general normalization gap across every
package-relative join site.

Add `hmodel::htpkg::join_rel_checked`, a single lexical-normalizing join
(collapse `.`/empty, resolve `..`, preserve trailing slash + glob
metachars) that hard-errors when a `..` escapes the workspace root.
Route all three join sites through it:

- plugin-exec `spec_path_to_target_path` (the output-path producer)
- plugin-buildfile `resolve_fs_path` (heph.file / heph.glob)
- builtins `heph.fs.glob` (replaces its local format!+normalize_path)

Escaping the workspace root is now a hard error everywhere, not a
silently-mangled path. Derive `Debug` on the public `path::Path` /
`Content` types per the Debug-on-public-types guideline.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
@raphaelvigee raphaelvigee enabled auto-merge (squash) June 25, 2026 08:25
@raphaelvigee raphaelvigee merged commit 9301b4d into master Jun 25, 2026
12 checks passed
@raphaelvigee raphaelvigee deleted the fix/pkg-rel-path-normalization branch June 25, 2026 08:36
raphaelvigee added a commit to hephbuild/hephbuild.github.io that referenced this pull request Jun 25, 2026
Paths passed to file(), glob(), out, and support_files are now
lexically normalized and hard-error when .. escapes the workspace
root (hephbuild/heph#128). Document this behavior in buildfile.md
and exec.md to match the existing note in fs.md.
raphaelvigee added a commit to hephbuild/hephbuild.github.io that referenced this pull request Jun 25, 2026
Paths passed to file(), glob(), out, and support_files are now
lexically normalized and hard-error when .. escapes the workspace
root (hephbuild/heph#128). Document this behavior in buildfile.md
and exec.md to match the existing note in fs.md.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant