fix: Stop compile mode sweeping the working directory and skipping about help - #213
Merged
Conversation
…out help Two defects in Build-PSBuildModule's staging, both silent, both producing a plausible artifact from a build that reported success. Researched against consumer usage and peer tools before choosing between the options each issue listed. #206 -- CompileDirectories defaulted to @(), and PowerShell treats an empty -Path as "not supplied" and falls back to the current location. So -Compile without the parameter concatenated every .ps1 beneath the working directory into the root module. Found when a test compiled this repository's own test files into a fixture module. The fix is a default plus a guard, because they close different halves. The default -- @('Enum', 'Classes', 'Private', 'Public') -- covers an omitted argument and matches what the tasks already pass, what the README has always documented, and what ModuleBuilder declares in the same position. The guard covers an explicit empty array, which both task files forward unguarded when a consumer sets $PSBPreference.Build.CompileDirectories = @(); that reached the same sweep through supported configuration, so the default alone would not have closed it. ValidateNotNullOrEmpty was considered and rejected on evidence: validation attributes are not applied to default values, so it leaves the omitted case open while breaking the explicit one. Throwing was rejected because compiling only to wrap an existing .psm1 in a header and footer is a coherent request. Upstream declined to change Get-ChildItem's null handling (PowerShell/PowerShell#17793, Won't Fix) with the working group advising callers to validate, so the guard belongs here. Compiling to an empty set now warns. That is the #201 precedent -- the failure mode is a module with no functions and a green build, and a warning makes it visible without forbidding the legitimate case. #207 -- the Copy-Item writing about_<Module>.help.txt sat inside the Test-Path branch that creates the culture directory, so an existing directory meant no about help file at all. CopyDirectories runs earlier, and in compile mode naming the culture directory there is the only way to ship a locale directory, so any compiled module with localized data suppressed its own about help. The Force on that copy was already present and unreachable: the author intended an unconditional overwrite and a misplaced brace prevented it. This restores that. The shape now matches Build-PSBuildMAMLHelp and ModuleBuilder's CopyReadMe, from which this code appears to descend -- the port collapsed two guards into one. The test pinning the broken behaviour is inverted deliberately, not discovered as a failure. Its comment now records what was fixed. Closes #206 Closes #207 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01U1Jhu7fgTRJq7LK5MuKteE
Test Results 4 files ± 0 889 suites +8 2m 23s ⏱️ -15s Results for commit ee449a9. ± Comparison against base commit b764fbb. This pull request removes 1 and adds 7 tests. Note that renamed tests count towards both. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #206 · Closes #207
Both are silent defects in
Build-PSBuildModule's staging that produce a plausible artifact from a green build. The option each issue listed was chosen after researching consumer usage and peer tools — that research changed the answer for #206.#206 — compile mode swept the working directory
CompileDirectoriesdefaulted to@(), and PowerShell treats an empty-Pathas not supplied, falling back to the current location. So-Compilewithout the parameter concatenated every.ps1beneath wherever the build ran into the root module. Found when a test compiled this repository's ownMeta.tests.ps1into a fixture module — the built module then failed to import while the build reported success.The fix is a default and a guard, because they close different halves. I originally planned only the default; the research corrected that:
So the claim in #206 that task consumers can't hit this holds only for consumers who leave the setting alone.
Options rejected, with reasons:
[ValidateNotNullOrEmpty()]— tested, and validation attributes are not applied to default values. It leaves the omitted case broken while breaking the explicit one. Exactly backwards..psm1inCompileHeader/CompileFooteris a coherent request, and it's what the parameter literally says.$Path— makes an empty list mean "everything", which is how the two staging mechanisms got tangled in the first place.Corroboration for the default value:
PoshCode/ModuleBuilder'sBuild-Module.ps1:95-99declares the same four names in the same order, in the function signature. PowerShellBuild was the only comparable tool whose real default lived solely in a config file while the signature declared something unusable. Upstream declined to changeGet-ChildItem's null handling (PowerShell#17793,Resolution-Won't Fix), with the working group advising callers to validate — so the guard belongs here.Compiling to an empty set now warns. That's the #201 precedent: the failure mode is a module with no functions and a green build, and a warning makes it visible without forbidding the legitimate case.
#207 — about help skipped when the culture directory existed
The
Copy-Itemwritingabout_<Module>.help.txtsat inside theTest-Pathbranch that creates the culture directory.CopyDirectoriesruns earlier, so naming the culture directory there suppressed the about help — and in compile mode that's the only way to ship a locale directory at all, so any compiled module with localized data silently suppressed its own about topic.This isn't a behaviour decision.
Copy-Itemwas already called withForce = $true; a misplaced closing brace made it unreachable. The author intended an unconditional overwrite. The guard now covers only the directory creation — matchingBuild-PSBuildMAMLHelp.ps1:59-62character-for-character, and matching ModuleBuilder'sCopyReadMe.ps1, from which this code appears to descend. The port collapsed two guards into one.New-Item -Force(the issue's option 3) is factually sound — verified against the docs and both engines — but would make this the only directory creation in the module not using the house idiom.Blast radius
The consumer census read 88 build files across 86 public repositories:
Nobody is relying on either broken behaviour. The one theoretical regression for #206 — a direct caller who omits the parameter, runs from their source root, and keeps functions outside those four directory names — is why the warning is there.
Tests
Red-before-green on both, each failing only its own case:
Compiles nothing from the current working directoryred — it fails by matching this repository's test-file content in the built module.The context that pinned #207's broken behaviour with
Should -Not -Existis inverted deliberately, not discovered as a failure; its comment now records what changed and why.Verification
Full suite 591 passed, 0 failed, 3 skipped. All five touched files verified CRLF-only, no lone LF, no
\r\r\n. Migration guide TOC re-verified: 18 headings, 18 links, nothing dangling.Related, filed not fixed
The research surfaced three more defects in this same staging logic, all separate: #210 (a hand-written about topic is dropped when compiling — verified in three published packages), #211 (a culture directory's
.psd1is flattened into the output root), #212 (compile and non-compile disagree on whether the readme or a source about file wins — only visible once #207 is fixed).🤖 Generated with Claude Code
https://claude.ai/code/session_01U1Jhu7fgTRJq7LK5MuKteE