diff --git a/scripts/NodeVersion.ps1 b/scripts/NodeVersion.ps1 index 819ac5e..0f76294 100644 --- a/scripts/NodeVersion.ps1 +++ b/scripts/NodeVersion.ps1 @@ -61,9 +61,22 @@ function Use-Node { $raw = Get-NodeVersionString if ($raw) { - # `latest` is whatever nvm decided, so there is nothing to compare a - # version string against — the caller checks the major instead. - if ($Version -eq 'latest' -or $raw.TrimStart('v') -eq $Version.TrimStart('v')) { + # An alias resolves to whatever nvm picked, so there is no version + # string to compare it against — the caller checks the major + # instead. What is checked here is nvm's own report, because it + # announces a switch it could not make while still exiting 0. + # Treating an alias as always-successful is what turned "the version + # nvm wanted is not installed" into a claim that the newest install + # was too old, which sent the reader to `nvm install` holding a list + # that already had newer versions on it. + $switched = if ($Version -in @('latest', 'lts', 'newest')) { + $output -notmatch 'activation error|not installed' + } + else { + $raw.TrimStart('v') -eq $Version.TrimStart('v') + } + + if ($switched) { if ($Note) { & $Note "node $raw" } return $raw } @@ -94,26 +107,41 @@ can write that link: "@ } +# The version every local run uses. Pinned rather than asked for by alias, so +# two machines run the same Node instead of whatever each happens to have +# installed. Bump it here and it moves for start-local.ps1 and run-tests.ps1 +# together; the floor check below is a backstop against pinning it too low, not +# the specification. +$script:NODE_VERSION = '26.7.0' + <# - Switches to the newest installed version and insists it is new enough. - `nvm use latest` picks the highest version nvm has installed locally, which - can still be older than this project needs. + Switches to the pinned version and insists it clears the floor. + + Asking nvm for an alias is what this used to do, and the two alias names are + worth recording because they are easy to swap by accident. `newest` means + the newest version installed on this machine. `latest` means the newest that + exists — nvm-windows resolves it against the remote release list — so on a + machine whose newest install is behind the current release, `nvm use latest` + reports "activation error: Version not installed" and leaves the old version + running. This asked for `latest` and reported the failure as "the newest + version nvm has installed is too old", which was false and sent the reader + to install something they already had. See #198. + + A version that is not installed is Use-Node's error to report, and it now + reports nvm's own reason, so there is nothing to say about it here. #> function Use-NodeLatest { param([scriptblock]$Step, [scriptblock]$Note) - Use-Node -Version 'latest' -Why 'this project needs Node 20 or newer' -Step $Step -Note $Note | Out-Null + Use-Node -Version $script:NODE_VERSION -Why 'this project needs Node 20 or newer' -Step $Step -Note $Note | Out-Null $major = Get-NodeMajor if ($major -lt 20) { throw @" -Node is still v$major after 'nvm use latest'. This project needs Node 20 or newer. +Node is v$major after switching to $($script:NODE_VERSION), which is below the 20 this project needs. -The newest version nvm has installed is too old. Install a newer one: - - nvm install 24.13.1 - -Installed versions: nvm list +NODE_VERSION in scripts/NodeVersion.ps1 is pinned to a version that is too old. +node-pg-migrate, ts-jest and Playwright all need 20 or newer. "@ } }