fix: preflight.ps1 asset-mode helper renamed to Exit-Asset so PSScriptAnalyzer passes (#151, C)
CI / verify (push) Successful in 2m20s
CI / pwsh (push) Successful in 1m45s
Release / release (push) Successful in 34s

Files changed:
- CHANGES.md
- VERSION
- tools/preflight.ps1
This commit is contained in:
torben committed 2026-10-01 13:46:51 +02:00
1 parent c33e8cdfb1
commit d6e973c3ce
3 files changed
+26 -17

No files matched your search

+12 -3
View File
@@ -59,7 +59,7 @@ concern - readable here, never shipped as something to parse.
--- ---
## 8.0.0-beta.16 - 2026-10-01 - Preflight as a release asset: download, verify and unpack the stack, then run the tree preflight ## 8.0.0-beta.17 - 2026-10-01 - preflight.ps1: the asset-mode error helper is Exit-Asset, so PSScriptAnalyzer passes
**Author:** Torben Nehmer **Author:** Torben Nehmer
@@ -125,8 +125,16 @@ concern - readable here, never shipped as something to parse.
- bug-report instruction: step 1 no longer calls every bundle unpseudonymised - bug-report instruction: step 1 no longer calls every bundle unpseudonymised
- setup-instance step 15 names --no-push for a local-only first publish; gates.md and a docstring follow #159 - setup-instance step 15 names --no-push for a local-only first publish; gates.md and a docstring follow #159
- raw/CONTRACT.md points at the path budget for a name accepted from incoming/ - raw/CONTRACT.md points at the path budget for a name accepted from incoming/
- preflight.ps1: the asset-mode error helper is Exit-Asset, so PSScriptAnalyzer passes
<!-- /wikitool:bumps --> <!-- /wikitool:bumps -->
### preflight.ps1: the asset-mode error helper is Exit-Asset, so PSScriptAnalyzer passes
The helper that ends asset mode with exit 1 was called `Stop-Asset`. `Stop` is one of the verbs
PSScriptAnalyzer reads as changing system state, so `PSUseShouldProcessForStateChangingFunctions`
failed the CI `pwsh` job on the previous bump. It is now `Exit-Asset`, beside `Exit-WithGuide`;
behaviour is unchanged.
### Preflight as a release asset: download, verify and unpack the stack, then run the tree preflight ### Preflight as a release asset: download, verify and unpack the stack, then run the tree preflight
Section C of #151, the first install. Until now a new user had to get the stack onto the machine Section C of #151, the first install. Until now a new user had to get the stack onto the machine
@@ -148,8 +156,9 @@ script with empty placeholders and no `--archive` exits 1 saying it does not com
for a machine that cannot download, and is the entry point the tests use. for a machine that cannot download, and is the entry point the tests use.
On POSIX asset mode needs `curl`, `tar` and `sha256sum` (or `shasum`) and stops with exit 42 and On POSIX asset mode needs `curl`, `tar` and `sha256sum` (or `shasum`) and stops with exit 42 and
the usual guidance block when one is missing; the PowerShell script uses what Windows ships plus the usual guidance block when one is missing; the PowerShell script uses what Windows 10 and 11
`tar`. On Windows with long paths off, the 95-character folder limit is judged at the final ship (`Invoke-WebRequest`, `Get-FileHash`, `tar.exe`) and stops the same way only when `tar` is
gone. On Windows with long paths off, the 95-character folder limit is judged at the final
target before anything is unpacked, so a too-long `--into` stops with exit 42 and the fix is a target before anything is unpacked, so a too-long `--into` stops with exit 42 and the fix is a
shorter folder. Git Bash gets the target and archive converted with `cygpath -u`, because GNU shorter folder. Git Bash gets the target and archive converted with `cygpath -u`, because GNU
tar would read `C:` as a host. tar would read `C:` as a host.
+1 -1
View File
@@ -1 +1 @@
8.0.0-beta.16 8.0.0-beta.17
+13 -13
View File
@@ -221,7 +221,7 @@ function Test-LongPathsEnabled {
} }
} }
function Stop-Asset { function Exit-Asset {
param([string]$Message) param([string]$Message)
Write-ErrorLine "preflight: $Message" Write-ErrorLine "preflight: $Message"
exit 1 exit 1
@@ -238,19 +238,19 @@ function Resolve-AssetPath {
function Invoke-AssetMode { function Invoke-AssetMode {
$target = if ($Into) { Resolve-AssetPath $Into } else { Join-Path $Dir 'chemenu' } $target = if ($Into) { Resolve-AssetPath $Into } else { Join-Path $Dir 'chemenu' }
if ($null -ne (Get-Item -LiteralPath $target -Force -ErrorAction SilentlyContinue)) { if ($null -ne (Get-Item -LiteralPath $target -Force -ErrorAction SilentlyContinue)) {
Stop-Asset "$target already exists - nothing was unpacked. Choose another folder with --into <path>, or move the existing one away." Exit-Asset "$target already exists - nothing was unpacked. Choose another folder with --into <path>, or move the existing one away."
} }
if (-not $Archive -and (-not $ReleaseArchiveUrl -or -not $ReleaseChecksumUrl)) { if (-not $Archive -and (-not $ReleaseArchiveUrl -or -not $ReleaseChecksumUrl)) {
Stop-Asset 'this copy of the script does not come from a release (it has no download address). Download preflight.ps1 from the release page, or pass --archive <tarball>.' Exit-Asset 'this copy of the script does not come from a release (it has no download address). Download preflight.ps1 from the release page, or pass --archive <tarball>.'
} }
if ($Archive) { if ($Archive) {
$Archive = Resolve-AssetPath $Archive $Archive = Resolve-AssetPath $Archive
if (-not (Test-Path -LiteralPath $Archive -PathType Leaf)) { if (-not (Test-Path -LiteralPath $Archive -PathType Leaf)) {
Stop-Asset "--archive: $Archive is not a file." Exit-Asset "--archive: $Archive is not a file."
} }
if (-not (Test-Path -LiteralPath "$Archive.sha256" -PathType Leaf)) { if (-not (Test-Path -LiteralPath "$Archive.sha256" -PathType Leaf)) {
Stop-Asset "--archive: $Archive.sha256 is missing - the checksum file has to lie next to the tarball." Exit-Asset "--archive: $Archive.sha256 is missing - the checksum file has to lie next to the tarball."
} }
} }
@@ -278,7 +278,7 @@ function Invoke-AssetMode {
try { try {
Invoke-WebRequest -Uri $pair[0] -OutFile $pair[1] Invoke-WebRequest -Uri $pair[0] -OutFile $pair[1]
} catch { } catch {
Stop-Asset "the download failed: $($pair[0]) ($($_.Exception.Message)) - check the internet connection, then run this again." Exit-Asset "the download failed: $($pair[0]) ($($_.Exception.Message)) - check the internet connection, then run this again."
} }
} }
} }
@@ -286,18 +286,18 @@ function Invoke-AssetMode {
$first = Get-Content -LiteralPath $checksumPath -TotalCount 1 -Encoding utf8 $first = Get-Content -LiteralPath $checksumPath -TotalCount 1 -Encoding utf8
$match = [regex]::Match("$first", '^([0-9A-Fa-f]{64})') $match = [regex]::Match("$first", '^([0-9A-Fa-f]{64})')
if (-not $match.Success) { if (-not $match.Success) {
Stop-Asset 'the checksum file holds no sha256 in its first line - nothing was unpacked.' Exit-Asset 'the checksum file holds no sha256 in its first line - nothing was unpacked.'
} }
$want = $match.Groups[1].Value.ToLowerInvariant() $want = $match.Groups[1].Value.ToLowerInvariant()
$have = (Get-FileHash -LiteralPath $archivePath -Algorithm SHA256).Hash.ToLowerInvariant() $have = (Get-FileHash -LiteralPath $archivePath -Algorithm SHA256).Hash.ToLowerInvariant()
if ($want -ne $have) { if ($want -ne $have) {
Stop-Asset "the sha256 of the archive does not match its checksum file (expected $want, got $have) - nothing was unpacked. Delete the download and run this again." Exit-Asset "the sha256 of the archive does not match its checksum file (expected $want, got $have) - nothing was unpacked. Delete the download and run this again."
} }
Write-Line 'sha256 OK' Write-Line 'sha256 OK'
$listing = Invoke-Native $tar.Source @('-tzf', $archivePath) $listing = Invoke-Native $tar.Source @('-tzf', $archivePath)
if ($null -eq $listing) { if ($null -eq $listing) {
Stop-Asset 'the archive could not be read - nothing was unpacked.' Exit-Asset 'the archive could not be read - nothing was unpacked.'
} }
$tops = @( $tops = @(
$listing -split "`n" | $listing -split "`n" |
@@ -306,13 +306,13 @@ function Invoke-AssetMode {
Select-Object -Unique Select-Object -Unique
) )
if ($tops.Count -ne 1) { if ($tops.Count -ne 1) {
Stop-Asset 'the archive does not hold exactly one top-level folder - nothing was unpacked.' Exit-Asset 'the archive does not hold exactly one top-level folder - nothing was unpacked.'
} }
$top = $tops[0] $top = $tops[0]
$manifestText = Invoke-Native $tar.Source @('-xOzf', $archivePath, "$top/tools/prerequisites.txt") $manifestText = Invoke-Native $tar.Source @('-xOzf', $archivePath, "$top/tools/prerequisites.txt")
if ($null -eq $manifestText) { if ($null -eq $manifestText) {
Stop-Asset "the archive holds no $top/tools/prerequisites.txt - nothing was unpacked." Exit-Asset "the archive holds no $top/tools/prerequisites.txt - nothing was unpacked."
} }
$limit = 0 $limit = 0
foreach ($line in ($manifestText -split "`n")) { foreach ($line in ($manifestText -split "`n")) {
@@ -338,7 +338,7 @@ function Invoke-AssetMode {
$null = New-Item -ItemType Directory -Path $unpack $null = New-Item -ItemType Directory -Path $unpack
$null = Invoke-NativeVerbose $tar.Source @('-xzf', $archivePath, '-C', $unpack) $null = Invoke-NativeVerbose $tar.Source @('-xzf', $archivePath, '-C', $unpack)
if (-not (Test-Path -LiteralPath (Join-Path $unpack $top) -PathType Container)) { if (-not (Test-Path -LiteralPath (Join-Path $unpack $top) -PathType Container)) {
Stop-Asset "unpacking failed - the target was not created." Exit-Asset "unpacking failed - the target was not created."
} }
Move-Item -LiteralPath (Join-Path $unpack $top) -Destination $target Move-Item -LiteralPath (Join-Path $unpack $top) -Destination $target
} finally { } finally {
@@ -351,7 +351,7 @@ function Invoke-AssetMode {
$treeScript = Join-Path $target 'tools/preflight.ps1' $treeScript = Join-Path $target 'tools/preflight.ps1'
if (-not (Test-Path -LiteralPath $treeScript -PathType Leaf)) { if (-not (Test-Path -LiteralPath $treeScript -PathType Leaf)) {
Stop-Asset 'the unpacked stack has no tools/preflight.ps1.' Exit-Asset 'the unpacked stack has no tools/preflight.ps1.'
} }
Write-Line "Unpacked into $target." Write-Line "Unpacked into $target."
Write-Line 'If a later step stops, run tools/preflight.ps1 from inside that folder.' Write-Line 'If a later step stops, run tools/preflight.ps1 from inside that folder.'