Create the --output directory up front instead of failing late on index.html (fixes #446) - #471
Conversation
…ex.html (fixes #446) `xchtmlreport <bundle> --output /missing/dir` parsed the bundle, exported attachments and rendered the whole report, then died at the final `html.write(toFile:)` with Error: An error has occured while creating the report Error: The file "index.html" doesn't exist. Neither line names the real problem, and both arrive after all the work is done — in linking mode, after payloads have already been exported into the bundle. This is what made the first scheduled toolchain-drift run (#444) look like toolchain drift. Create the output directory, intermediates included, before the `Summary` is built. Create-by-default is what every CLI this one sits next to does, and it is a no-op on the common path where the directory already exists. A directory that genuinely cannot be created — no write permission on the parent, a file in the way — is a usage error, not a degraded report: it throws `ValidationError`, so it exits 64 like the tool's other usage errors rather than 3, and the message names the path and the reason before any work starts. The `An error has occured` string is untouched; this fix simply makes that path unreachable for a missing output directory. Drop the `mkdir -p` that #445 added to the toolchain-drift workflow as a workaround for this bug. Pointing that job at an uncreated path is now part of what the step asserts, so restoring the mkdir would mask a regression. README's exit-code section documented the old behaviour verbatim ("Exit 1 covers failures to write the output — for example `-o` pointing at a directory that does not exist"); corrected, and `--output`'s help text now says the directory is created if missing. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (4)
📝 WalkthroughWalkthroughThe CLI now creates missing output directories before report generation. It reports directory creation failures as argument errors with exit code 64. Tests, documentation, and the toolchain workflow cover this behavior. ChangesOutput directory handling
Estimated code review effort: 3 (Moderate) | ~20 minutes Merge Risk: ⚪ Minimal · up to The PR creates missing output directories up front and reports uncreatable paths as usage errors; it is merge-ready after normal checks and review, with no actionable merge-blocking risk remaining. Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
|
Post-merge note from review: |
Fixes #446.
The bug
Neither line names the real problem. The failure is the final
html.write(toFile:)inrun(), so it arrives after all the work is done —and in linking mode after payloads have already been exported into the bundle.
index.htmlis a red herring: the file that doesn't exist is the directoryabove it. This is what made the first scheduled toolchain-drift run (#444) look
like toolchain drift.
The fix
Create the output directory, intermediates included, before anything else
happens — before the
Summaryis built, before parsing, rendering orexporting. Create-by-default is what every CLI this one sits next to does, and
it is a no-op on the overwhelmingly common path where the directory already
exists.
When the directory genuinely cannot be created — no write permission on the
parent, a file in the way — that is a usage error, not a degraded report:
it throws
ValidationError, so it exits 64 like the tool's other usageerrors, never 3, which is reserved for collected faults. The message names the
path and the reason, and arrives before any work:
The
An error has occured while creating the reportstring (typo included) isuntouched — this fix makes that path unreachable for a missing output
directory, and rewording it is a separate concern.
The #445 workaround comes out
.github/workflows/toolchain-drift.ymlgained amkdir -p "$RUNNER_TEMP/drift-report"in #445 specifically to stop this bug from being misreported as drift. It is
removed here, with a comment saying why it must not come back: pointing the
drift job at an uncreated path is now part of what the step asserts, so a
regression in the fix would show up as a failed scheduled run rather than
being masked.
(
test.yml'smkdir -p "$RUNNER_TEMP/report"is left alone — it came from#457's render step, not from this bug.)
Tests
Both written before the fix and watched fail against the old behaviour:
CliTests.testNonexistentNestedOutputDirectoryIsCreated— renders to anonexistent nested path, asserts exit 0 and that
index.htmlis there.Before the fix: exit 1, no
index.html.CliTests.testUnwritableOutputDirectoryFailsFastNamingThePath— a0o555parent, asserts exit 64, that stderr names the path, and — the fail-fast
half — that
Building HTMLnever ran and that stderr no longer blamesindex.html. Before the fix: exit 1, all four assertions failed. Skippedwhen running as root, which ignores directory permissions.
Docs
README.md's exit-code section documented the old behaviour verbatim ("Exit 1covers failures to write the output — for example
-opointing at a directorythat does not exist"). Corrected. The
--outputhelp text now says thedirectory is created if missing.
Summary by CodeRabbit