From 08d4428dec58672af9201b236931cd758983f6a5 Mon Sep 17 00:00:00 2001 From: Irfan Hardiyanto <52022757+devhardiyanto@users.noreply.github.com> Date: Fri, 24 Jul 2026 09:29:57 +0700 Subject: [PATCH 1/3] fix(windows): ext info emits valid PHP; add doctor to did-you-mean; tidy comment - ext info: the -r snippet used PowerShell operators ($version -eq $null) inside PHP code, a parse error that 2>$null swallowed, so 'phpvm ext info' printed nothing. Mirror the Linux snippet: (getVersion() ?? 'n/a'). - did-you-mean: register 'doctor' (shipped 1.12.0) so a 'doctro' typo suggests it. - tidy the Invoke-Doctor header comment that got split by the 1.12.1 Test-ExtDirMatch insertion. Comment-only. devhardiyanto --- windows/phpvm.ps1 | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/windows/phpvm.ps1 b/windows/phpvm.ps1 index 71a4c4c..8044a13 100644 --- a/windows/phpvm.ps1 +++ b/windows/phpvm.ps1 @@ -1165,9 +1165,7 @@ function Ext-Info ([string]$extName) { if (extension_loaded('$extName')) { `$r = new ReflectionExtension('$extName'); echo 'Name : ' . `$r->getName() . PHP_EOL; - `$version = `$r->getVersion(); - if (`$version -eq `$null) { `$version = 'n/a'; } - echo 'Version : ' . `$version . PHP_EOL; + echo 'Version : ' . (`$r->getVersion() ?? 'n/a') . PHP_EOL; `$classes = `$r->getClassNames(); if (`$classes) echo 'Classes : ' . implode(', ', `$classes) . PHP_EOL; } else { @@ -1592,7 +1590,6 @@ function Invoke-Cacert ([string]$sub) { } -# Read-only health check. Never mutates state - every finding points at the # True when the ini's extension_dir points at the active version's ext folder. # `current` is a junction to versions\, so the versions\\ext and # current\ext spellings name the same directory - accept either rather than @@ -1604,6 +1601,7 @@ function Test-ExtDirMatch ([string]$iniExtDir, [string]$cur) { return ($acceptable -icontains $iniExtDir.TrimEnd('\')) } +# Read-only health check. Never mutates state - every finding points at the # command that fixes it. Exit-code-neutral: it's a report, not a gate. function Invoke-Doctor { Write-Host "" @@ -1751,7 +1749,7 @@ function Get-Levenshtein ([string]$a, [string]$b) { # Unknown command: suggest the nearest match instead of dumping the full help. function Invoke-Unknown ([string]$cmd) { $cmds = @("install","use","list","ls","current","uninstall","remove", - "which","ini","fix-ini","cacert","ext","composer","wp-cli","auto","hook", + "which","ini","fix-ini","cacert","doctor","ext","composer","wp-cli","auto","hook", "upgrade","update","version","help") $best = ""; $bestd = 99 foreach ($c in $cmds) { From 63feb305d0777615209e51811f48ab7d02122845 Mon Sep 17 00:00:00 2001 From: Irfan Hardiyanto <52022757+devhardiyanto@users.noreply.github.com> Date: Fri, 24 Jul 2026 09:30:02 +0700 Subject: [PATCH 2/3] fix(linux): add doctor to did-you-mean suggestions 'doctor' (shipped 1.12.0) was missing from _PHPVM_COMMANDS, so a typo like 'doctro' never suggested it. Parity with the Windows fix. devhardiyanto --- linux/phpvm.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linux/phpvm.sh b/linux/phpvm.sh index f119ecc..04ad1d4 100644 --- a/linux/phpvm.sh +++ b/linux/phpvm.sh @@ -1534,7 +1534,7 @@ _phpvm_levenshtein() { } # Canonical command list (includes aliases) for suggestions. -_PHPVM_COMMANDS="install use list ls current uninstall remove which ini deps ext composer wp-cli fix-ini auto hook upgrade update version help" +_PHPVM_COMMANDS="install use list ls current uninstall remove which doctor ini deps ext composer wp-cli fix-ini auto hook upgrade update version help" # Unknown command: suggest the nearest match instead of dumping the full help. _phpvm_unknown() { From 75b6bf11da12a60431b711c17f040d5a4c59785d Mon Sep 17 00:00:00 2001 From: Irfan Hardiyanto <52022757+devhardiyanto@users.noreply.github.com> Date: Fri, 24 Jul 2026 09:30:03 +0700 Subject: [PATCH 3/3] test(windows,linux): cover doctor did-you-mean suggestion devhardiyanto --- tests/linux/commands.bats | 6 ++++++ tests/windows/PureFunctions.Tests.ps1 | 5 +++++ 2 files changed, 11 insertions(+) diff --git a/tests/linux/commands.bats b/tests/linux/commands.bats index 1023991..48980ef 100644 --- a/tests/linux/commands.bats +++ b/tests/linux/commands.bats @@ -278,6 +278,12 @@ EOF [[ "$output" != *"Did you mean"* ]] } +@test "unknown: suggests doctor for a doctor typo" { + run phpvm doctro + [ "$status" -ne 0 ] + [[ "$output" == *"Did you mean 'doctor'?"* ]] +} + # ---------- partial version resolution ---------- @test "resolve: full x.y.z passes through without network" { diff --git a/tests/windows/PureFunctions.Tests.ps1 b/tests/windows/PureFunctions.Tests.ps1 index 70906b2..9ac3340 100644 --- a/tests/windows/PureFunctions.Tests.ps1 +++ b/tests/windows/PureFunctions.Tests.ps1 @@ -164,6 +164,11 @@ Describe 'Invoke-Unknown' { $out | Should -Match "is not a phpvm command" $out | Should -Not -Match "Did you mean" } + + It 'Suggests doctor for a doctor typo' { + $out = Invoke-Unknown 'doctro' 6>&1 | Out-String + $out | Should -Match "Did you mean 'doctor'\?" + } } Describe 'Get-PHPZipHash' {