Skip to content

Ask PHPStan for its version, not the program that launches it - #64

Merged
zonuexe merged 1 commit into
fix/container-path-normalizationfrom
fix/container-version-detection
Jul 17, 2026
Merged

Ask PHPStan for its version, not the program that launches it#64
zonuexe merged 1 commit into
fix/container-path-normalizationfrom
fix/container-version-detection

Conversation

@zonuexe

@zonuexe zonuexe commented Jul 17, 2026

Copy link
Copy Markdown
Member

Editor mode detection asked the wrong program for its version, so it was silently disabled for every setup except a directly executable phpstan — not just for containers, as I first thought when filing this.

Stacked on #63 (which is stacked on #62). Merge order: #62#63#64.

The bug

phpstan-get-command-args probed with:

(phpstan-editor-mode-available-p (car (phpstan-get-executable-and-args)))

The car of that command line is PHPStan itself only when PHPStan is directly executable. Everywhere else it is whatever launches PHPStan, and that program answered for its own version:

phpstan-executable command line probed parsed as PHPStan version
docker / container ("docker" "run" ... IMAGE) docker --version d1c06ef
("docker" "run" ...) as given docker --version d1c06ef
a PHAR without +x ("php" "/path/phpstan.phar") php --version Technologies
an executable phpstan ("/path/phpstan") phpstan --version 1.12.33

phpstan-version takes the last whitespace-separated token, so Docker version 29.5.3, build d1c06ef yields d1c06ef and PHP's banner ending in Zend Technologies yields Technologies. Neither starts with 1 or 2, so phpstan-editor-mode-available-p returned nil.

It failed safe — those setups fell back to the in-place copy — but no one outside the one supported configuration ever got editor mode.

The fix

Pass the whole command line down and run COMMAND... --version, which reaches the real PHPStan in every case. phpstan-version and phpstan-editor-mode-available-p now take a command list; a bare string is still accepted.

Two details that fall out of this:

  • STDERR. phpstan-version used shell-command-to-string, which merges STDERR. Apple container prints progress there, so it would have been read as part of the version. It now captures STDOUT only.
  • Cache. Probing may now start a container, so the cache is keyed by the whole command line instead of the executable. For a plain executable the key is unchanged. Measured at ~0.4s warm for Docker, and only on a cache miss.

Support is also treated as absent when the version cannot be determined, rather than signalling from elt on an empty string.

Verification

Version detection, cache, and editor-mode decision, with the cache cleared per case:

phpstan-executable version editor mode
local vendor/bin/phpstan (executable) 1.12.33 t ✅
non-executable .phar (runs via php) 1.12.33 t ✅
docker 2.2.5 t ✅
("docker" "run" ...) 2.2.5 t ✅

Cache: first probe 0.34s, second 0.000s.

With a modified buffer and auto-detection, both docker and container now actually select editor mode and pass --tmp-file /app/INPLACE.php — the in-place copy introduced in #63, not the system temporary directory. That branch was unreachable by auto-detection until this fix; it only ran with phpstan-activate-editor-mode set to enabled.

Full Flycheck runs against ghcr.io/phpstan/phpstan still pass on both runtimes with editor mode now on by default, and local execution is unchanged.

`phpstan-get-command-args' probed editor mode support with

    (phpstan-editor-mode-available-p (car (phpstan-get-executable-and-args)))

but the car of that command line is only PHPStan itself when PHPStan is
directly executable.  Everywhere else it is whatever launches PHPStan, and
that program answered for its own version:

  * `(phpstan-executable . docker)' and `container' probed the runtime, so
    `Docker version 29.5.3, build d1c06ef' parsed as version "d1c06ef";
  * a PHAR without the executable bit runs as ("php" "..."), so PHP's
    `--version' banner parsed as version "Technologies".

Neither starts with "1" or "2", so `phpstan-editor-mode-available-p'
returned nil and editor mode was silently off for every setup but one.

Pass the whole command line down and run `COMMAND... --version', which
reaches the real PHPStan in each case.  Both `phpstan-version' and
`phpstan-editor-mode-available-p' still accept a bare string.

`phpstan-version' also captured STDERR, because `shell-command-to-string'
merges it.  Apple container prints its progress there, so it would have
been read as part of the version; capture only STDOUT.  Probing may now
have to start a container (measured at ~0.4s warm for Docker), so the
cache is keyed by the whole command line rather than the executable.  For
a plain executable that key is unchanged.

Support is now treated as absent when the version cannot be determined,
rather than signalling from `elt' on an empty string.
@zonuexe
zonuexe merged commit ee0e42f into fix/container-path-normalization Jul 17, 2026
12 of 14 checks passed
zonuexe added a commit that referenced this pull request Jul 17, 2026
#63 and #64 were merged into their base branches rather than master:
#62 landed on master first, which left the rest of the stack behind on
feature/flycheck-generic-checker and fix/container-path-normalization.

Bring in the four commits that never reached master.
@zonuexe
zonuexe deleted the fix/container-version-detection branch July 17, 2026 16:28
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