Skip to content

Do not error normalizing a nil path under a container - #67

Merged
zonuexe merged 1 commit into
masterfrom
fix/normalize-path-nil
Jul 17, 2026
Merged

Do not error normalizing a nil path under a container#67
zonuexe merged 1 commit into
masterfrom
fix/normalize-path-nil

Conversation

@zonuexe

@zonuexe zonuexe commented Jul 17, 2026

Copy link
Copy Markdown
Member

Fixes a container run erroring when the project has no configuration file — found while writing the test suite in #66.

The bug

phpstan-get-command-args opens with:

(config (or config (phpstan-normalize-path (phpstan-get-config-file))))

phpstan-get-config-file returns nil when the project has no phpstan.neon(.dist) and phpstan-config-file is unset. For a container executable, phpstan-normalize-path then passed that nil to replace-regexp-in-string, raising (wrong-type-argument arrayp nil). The local case was unaffected — it returns (or source source-original) without touching the path.

So M-x phpstan-analyze-project, phpstan-analyze-this-file, flycheck, and flymake all errored under (phpstan-executable . docker) / container whenever the project had no config file. That combination is real: phpstan-enable-on-no-config-file explicitly enables PHPStan from a Composer autoload alone.

(cl-letf (((symbol-function 'php-project-get-root-dir) (lambda () "/proj/")))
  (let ((phpstan-executable 'docker))
    (phpstan-normalize-path nil)))
;; => (wrong-type-argument arrayp nil)   ; now => nil

The fix

Guard phpstan-normalize-path at the source: a nil path falls through to the (or source source-original) branch instead of the container rewrite, returning nil (or the optional SOURCE fallback) rather than erroring. Fixing the one function protects every caller. With config nil, the command line now simply omits -c, which is correct.

Tests

Two regression tests in test/phpstan-test.el, both verified to fail (with the original wrong-type-argument) when the fix is reverted:

  • phpstan-test-normalize-path-nil — nil in, nil out across docker / container / explicit-command / local / executable forms, and that the optional SOURCE fallback still applies.
  • phpstan-test-command-args-without-config-under-container — a docker run with phpstan-get-config-file stubbed to nil produces a command line with no -c and no error.

15/15 pass on system Emacs and Emacs 27.2; compile is warning-free on both.

`phpstan-get-command-args' starts with

    (config (or config (phpstan-normalize-path (phpstan-get-config-file))))

and `phpstan-get-config-file' returns nil when the project has no
phpstan.neon and `phpstan-config-file' is unset.  For a container
executable `phpstan-normalize-path' then passed that nil to
`replace-regexp-in-string', raising `(wrong-type-argument arrayp nil)'.
The local case was unaffected, since it returns `(or source
source-original)' without touching the path.

So `M-x phpstan-analyze-project', `phpstan-analyze-this-file', flycheck,
and flymake all errored under `(phpstan-executable . docker)' /
`container' whenever the project had no config file -- which
`phpstan-enable-on-no-config-file' explicitly allows (Composer autoload is
enough to enable PHPStan).

Guard `phpstan-normalize-path' at the source: a nil path falls through to
the `(or source source-original)' branch instead of the container
rewrite, so it returns nil (or the optional SOURCE fallback) rather than
erroring.  Fixing it in the one function protects every caller.  With
config nil the command line now simply omits `-c', which is correct.
@zonuexe
zonuexe merged commit c38ddd8 into master Jul 17, 2026
9 checks passed
@zonuexe
zonuexe deleted the fix/normalize-path-nil branch July 17, 2026 16:23
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