Skip to content

Windows one-liner install, Linux install fixes, older-patch hint (1.9.1)#20

Merged
devhardiyanto merged 4 commits into
mainfrom
fix/windows-oneliner-install
Jul 14, 2026
Merged

Windows one-liner install, Linux install fixes, older-patch hint (1.9.1)#20
devhardiyanto merged 4 commits into
mainfrom
fix/windows-oneliner-install

Conversation

@devhardiyanto

@devhardiyanto devhardiyanto commented Jul 14, 2026

Copy link
Copy Markdown
Owner

What

Follow-up fixes after 1.9.0 hit real machines. Two of them are regressions from the 1.9.0 spinner; the rest are long-standing drift. Bumps 1.9.0 -> 1.9.1.

Why

cd leaked into the user's shell (Linux/macOS). phpvm.sh is sourced, so phpvm_install's cd "$src_dir" moved the user's own shell into the build directory — which cleanup then deleted, stranding them in a dangling cwd:

➜  php-8.5.8 pwd
/home/user/.phpvm/cache/php-8.5.8     # and `ls` is empty — it was just rm -rf'd

This is not distro- or environment-specific: it follows from the script being sourced, so it affects every shell that sources phpvm.sh. None of the failure paths cd'd back either, so a failed build stranded the user just as a successful one did.

Job-control noise (regression from 1.9.0). The new spinner's background job made the interactive shell announce it on every build step:

[3] 2015
  / Configuring ... 0m21s[3]  + done       "$@" >> "$PHPVM_LOG" 2>&1

CI never caught this — job control is off in non-interactive shells.

One-liner install. Linux installs with a single curl … | bash; Windows made users download two files by hand. install.ps1 read phpvm.ps1 from $PSScriptRoot, which is empty when piped into iex, so the one-liner could never have worked. linux/install.sh already fetches from the repo — Windows was the outlier.

Composer stderr banner. After phpvm composer, two unindented lines broke the output. Composer writes its PHP banner and the "run diagnose" hint to stderr, bypassing the formatting pipeline. Not an error, just noise. linux/phpvm.sh already redirected it; Windows had drifted. Same class as the phpvm use banner fixed in 1.9.0.

Older-patch hint. phpvm install 8 resolves to the newest patch and installs it alongside any older patch of the same line, quietly leaving both. It now says so. It does not remove the old one: another project may pin that exact patch in .phpvmrc, and silently deleting a PHP someone still uses is not a tradeoff worth making.

How

  • linux/phpvm.sh — the build runs in a subshell, so the cd cannot escape at all, rather than being undone at four separate return points. Whatever directory you run phpvm install from, you are still in it afterwards — including when the build fails. _phpvm_run_logged turns the shell's monitor mode off while its job runs and restores it exactly as found.
  • windows/install.ps1 — use the local phpvm.ps1 when running from a clone, otherwise fetch from raw.githubusercontent.com. The failure path throws rather than exits: under irm … | iex, exit closes the user's whole session instead of aborting the install.
  • windows/phpvm.ps12>$null on the composer version probe; new Get-OlderPatch / Show-OlderPatchHint, mirrored by _phpvm_older_patches / _phpvm_older_patch_hint on Linux.
  • README.md — lead with the one-liner; keep the manual flow for anyone who would rather read the script first.

Changes

  • linux/phpvm.sh — subshell'd build, monitor-mode handling, older-patch hint
  • windows/install.ps1 — remote fetch fallback, throw instead of exit
  • windows/phpvm.ps1 — composer stderr, older-patch hint
  • tests/ — 5 new bats + 4 new Pester tests for the patch-line selection (numeric sort, 8.50.x must not count as the 8.5 line)
  • README.md, version.txt, install scripts — 1.9.1

Testing Done

  • Pester 58/58, PSScriptAnalyzer clean
  • bats 56/56, ShellCheck clean
  • CI green on all three jobs
  • Re-run phpvm install on Linux: no [3] … job noise, and the shell stays in the directory it started in. (Only verifiable once merged, or by sourcing linux/phpvm.sh from this branch directly — phpvm upgrade still serves 1.9.0 until this lands.)
  • Smoke test irm … | iex against a fresh PHPVM_DIR — the one path that cannot be unit tested.

Not fixed here

phpvm install on Windows prefers the thread-safe build (Resolve-PHPURL tries the non-nts URL first), but windows.php.net recommends NTS for CLI and FastCGI; TS is only needed for Apache mod_php, which phpvm never touches. Worth flipping, but it changes what gets installed, so it belongs in its own PR.

- install.ps1 now downloads phpvm.ps1 from the repo when it is not sitting next
  to the script, so `irm .../windows/install.ps1 | iex` works with nothing on
  disk. This is what linux/install.sh already did; Windows was the outlier and
  the reason the README had to ask for a two-file manual download. Running from
  a clone still copies the local file. The download failure path throws instead
  of calling exit, which under `iex` would close the user's whole session.
- phpvm composer: redirect the version probe's stderr. Composer prints its PHP
  banner and the "run diagnose" hint on stderr, which bypassed the formatting
  pipeline and leaked unindented into the output. linux/phpvm.sh:1049 already
  did this; Windows had drifted.

devhardiyanto
…ser's shell

Both surfaced testing 1.9.0 on WSL2.

- phpvm.sh is sourced, so phpvm_install's `cd "$src_dir"` moved the *user's own*
  shell into the build directory — which the cleanup step then deleted, leaving
  them sitting in a dangling cwd. None of the failure paths cd'd back either.
  The build now runs in a subshell, so the cd cannot escape at all rather than
  being undone at four separate return points.
- The spinner's background job printed the interactive shell's job-control
  notices ("[3] 2015", "[3] + done ...") around every build step. Turn the
  monitor off while the job runs and restore it exactly as found. CI never saw
  this: job control is off in non-interactive shells.

Windows is unaffected — Invoke-Install extracts a zip and never changes
directory.

devhardiyanto
@devhardiyanto devhardiyanto changed the title Windows: one-liner install via irm | iex, and quiet the composer stderr banner (1.9.1) Windows one-liner install, WSL2 install fixes, older-patch hint (1.9.1) Jul 14, 2026
An em-dash slipped into a comment, tripping PSScriptAnalyzer's
PSUseBOMForUnicodeEncodedFile. The rest of the Windows scripts are ASCII.

devhardiyanto
Linux got five bats tests for the patch-line selection; Windows had none, so
the same off-by-one risks (lexical sort, 8.50.x matching the 8.5 line) were
untested there.

devhardiyanto
@devhardiyanto devhardiyanto changed the title Windows one-liner install, WSL2 install fixes, older-patch hint (1.9.1) Windows one-liner install, Linux install fixes, older-patch hint (1.9.1) Jul 14, 2026
@devhardiyanto devhardiyanto merged commit 46bb7cb into main Jul 14, 2026
3 checks passed
@devhardiyanto devhardiyanto deleted the fix/windows-oneliner-install branch July 14, 2026 01:54
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