From 362d34cb32a056f42c1ab57840b77c18fcb55a2f Mon Sep 17 00:00:00 2001 From: James Titcumb Date: Mon, 9 Mar 2026 12:03:17 +0000 Subject: [PATCH] Improve the exception_dir exception message with more details --- phpstan-baseline.neon | 6 --- .../Exception/ExtensionPathProblem.php | 39 ++++++++++++++ src/Platform/TargetPhp/PhpBinaryPath.php | 6 ++- .../Exception/ExtensionPathProblemTest.php | 54 +++++++++++++++++++ 4 files changed, 97 insertions(+), 8 deletions(-) create mode 100644 src/Platform/TargetPhp/Exception/ExtensionPathProblem.php create mode 100644 test/unit/Platform/TargetPhp/Exception/ExtensionPathProblemTest.php diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 484f95bd..4f97e58e 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -294,12 +294,6 @@ parameters: count: 1 path: src/Platform/InstalledPiePackages.php - - - message: '#^Call to function array_key_exists\(\) with 1 and array\{non\-falsy\-string, non\-empty\-string, non\-empty\-string\} will always evaluate to true\.$#' - identifier: function.alreadyNarrowedType - count: 1 - path: src/Platform/TargetPhp/PhpBinaryPath.php - - message: '#^Call to function array_key_exists\(\) with 2 and array\{non\-falsy\-string, string, string\} will always evaluate to true\.$#' identifier: function.alreadyNarrowedType diff --git a/src/Platform/TargetPhp/Exception/ExtensionPathProblem.php b/src/Platform/TargetPhp/Exception/ExtensionPathProblem.php new file mode 100644 index 00000000..d4d74115 --- /dev/null +++ b/src/Platform/TargetPhp/Exception/ExtensionPathProblem.php @@ -0,0 +1,39 @@ +phpBinaryPath; + + if ($extensionPath === null) { + $message .= '; extension_dir => not set'; + } else { + $message .= '; extension_dir => ' . $extensionPath; + + if (file_exists($extensionPath)) { + $message .= '; exists'; + + if (is_dir($extensionPath)) { + $message .= ', is a directory'; + } else { + $message .= ', not a directory'; + } + } else { + $message .= '; does not exist'; + } + } + + return new self($message); + } +} diff --git a/src/Platform/TargetPhp/PhpBinaryPath.php b/src/Platform/TargetPhp/PhpBinaryPath.php index f0f231c9..9f1729e8 100644 --- a/src/Platform/TargetPhp/PhpBinaryPath.php +++ b/src/Platform/TargetPhp/PhpBinaryPath.php @@ -12,6 +12,7 @@ use Php\Pie\Platform\DebugBuild; use Php\Pie\Platform\OperatingSystem; use Php\Pie\Platform\OperatingSystemFamily; +use Php\Pie\Platform\TargetPhp\Exception\ExtensionPathProblem; use Php\Pie\Util\Process; use RuntimeException; use Symfony\Component\Process\PhpExecutableFinder; @@ -109,9 +110,10 @@ public function extensionPath(string|null $prefixInstallRoot = null): string { $phpinfo = $this->phpinfo(); + $extensionPath = null; + if ( preg_match('#^extension_dir\s+=>\s+([^=]+)\s+=>\s+([^=]+)$#m', $phpinfo, $matches) - && array_key_exists(1, $matches) && trim($matches[1]) !== '' && trim($matches[1]) !== 'no value' ) { @@ -142,7 +144,7 @@ public function extensionPath(string|null $prefixInstallRoot = null): string } } - throw new RuntimeException('Could not determine extension path for ' . $this->phpBinaryPath); + throw ExtensionPathProblem::new($this, $extensionPath); } public function assertExtensionIsLoadedInRuntime(ExtensionName $extension, IOInterface|null $io = null): void diff --git a/test/unit/Platform/TargetPhp/Exception/ExtensionPathProblemTest.php b/test/unit/Platform/TargetPhp/Exception/ExtensionPathProblemTest.php new file mode 100644 index 00000000..01edeb40 --- /dev/null +++ b/test/unit/Platform/TargetPhp/Exception/ExtensionPathProblemTest.php @@ -0,0 +1,54 @@ +phpBinaryPath . '; extension_dir => not set', + ExtensionPathProblem::new($php, null)->getMessage(), + ); + } + + public function testExtensionPathDoesNotExist(): void + { + $php = PhpBinaryPath::fromCurrentProcess(); + + self::assertSame( + 'Could not determine extension path for ' . $php->phpBinaryPath . '; extension_dir => /path/does/not/exist; does not exist', + ExtensionPathProblem::new($php, '/path/does/not/exist')->getMessage(), + ); + } + + public function testExtensionPathIsAFile(): void + { + $php = PhpBinaryPath::fromCurrentProcess(); + + self::assertSame( + 'Could not determine extension path for ' . $php->phpBinaryPath . '; extension_dir => ' . __FILE__ . '; exists, not a directory', + ExtensionPathProblem::new($php, __FILE__)->getMessage(), + ); + } + + public function testExtensionPathIsADir(): void + { + $php = PhpBinaryPath::fromCurrentProcess(); + + self::assertSame( + 'Could not determine extension path for ' . $php->phpBinaryPath . '; extension_dir => ' . __DIR__ . '; exists, is a directory', + ExtensionPathProblem::new($php, __DIR__)->getMessage(), + ); + } +}