From c760b1f7a45c512cd34c91d8e078046dfdc453ba Mon Sep 17 00:00:00 2001 From: Ondrej Mirtes Date: Tue, 13 Dec 2022 10:43:34 +0100 Subject: [PATCH] Discover phpunit-bridge automatically --- src/Internal/ComposerHelper.php | 10 +++++ ...JsonAndInstalledJsonSourceLocatorMaker.php | 39 +++++++++++++++++++ 2 files changed, 49 insertions(+) diff --git a/src/Internal/ComposerHelper.php b/src/Internal/ComposerHelper.php index 50e21572d5..e4442857ce 100644 --- a/src/Internal/ComposerHelper.php +++ b/src/Internal/ComposerHelper.php @@ -56,6 +56,16 @@ public static function getVendorDirFromComposerConfig(string $root, array $compo return $root . '/' . trim($vendorDirectory, '/'); } + /** + * @param array $composerConfig + */ + public static function getBinDirFromComposerConfig(string $root, array $composerConfig): string + { + $vendorDirectory = $composerConfig['config']['bin-dir'] ?? 'vendor/bin'; + + return $root . '/' . trim($vendorDirectory, '/'); + } + public static function getPhpStanVersion(): string { if (self::$phpstanVersion !== null) { diff --git a/src/Reflection/BetterReflection/SourceLocator/ComposerJsonAndInstalledJsonSourceLocatorMaker.php b/src/Reflection/BetterReflection/SourceLocator/ComposerJsonAndInstalledJsonSourceLocatorMaker.php index c930d375b7..34c6105a58 100644 --- a/src/Reflection/BetterReflection/SourceLocator/ComposerJsonAndInstalledJsonSourceLocatorMaker.php +++ b/src/Reflection/BetterReflection/SourceLocator/ComposerJsonAndInstalledJsonSourceLocatorMaker.php @@ -11,15 +11,20 @@ use PHPStan\File\CouldNotReadFileException; use PHPStan\File\FileReader; use PHPStan\Internal\ComposerHelper; +use PHPStan\Php\PhpVersion; use function array_filter; use function array_key_exists; use function array_map; use function array_merge; use function array_merge_recursive; +use function array_reverse; use function count; use function dirname; +use function glob; use function is_dir; use function is_file; +use function strpos; +use const GLOB_ONLYDIR; class ComposerJsonAndInstalledJsonSourceLocatorMaker { @@ -28,6 +33,7 @@ public function __construct( private OptimizedDirectorySourceLocatorRepository $optimizedDirectorySourceLocatorRepository, private OptimizedPsrAutoloaderLocatorFactory $optimizedPsrAutoloaderLocatorFactory, private OptimizedDirectorySourceLocatorFactory $optimizedDirectorySourceLocatorFactory, + private PhpVersion $phpVersion, ) { } @@ -125,6 +131,39 @@ public function create(string $projectInstallationPath): ?SourceLocator $locators[] = $this->optimizedDirectorySourceLocatorFactory->createByFiles($files); } + $binDir = ComposerHelper::getBinDirFromComposerConfig($projectInstallationPath, $composer); + $phpunitBridgeDir = $binDir . '/.phpunit'; + if (!is_dir($vendorDirectory . '/phpunit/phpunit') && is_dir($phpunitBridgeDir)) { + // from https://github.com/composer/composer/blob/8ff237afb61b8766efa576b8ae1cc8560c8aed96/phpstan/locate-phpunit-autoloader.php + $bestDirFound = null; + $phpunitBridgeDirectories = glob($phpunitBridgeDir . '/phpunit-*', GLOB_ONLYDIR); + if ($phpunitBridgeDirectories !== false) { + foreach (array_reverse($phpunitBridgeDirectories) as $dir) { + $bestDirFound = $dir; + if ($this->phpVersion->getVersionId() >= 80100 && strpos($dir, 'phpunit-10') !== false) { + break; + } + if ($this->phpVersion->getVersionId() >= 80000) { + if (strpos($dir, 'phpunit-9') !== false) { + break; + } + continue; + } + + if (strpos($dir, 'phpunit-8') !== false || strpos($dir, 'phpunit-7') !== false) { + break; + } + } + + if ($bestDirFound !== null) { + $phpunitBridgeLocator = $this->create($bestDirFound); + if ($phpunitBridgeLocator !== null) { + $locators[] = $phpunitBridgeLocator; + } + } + } + } + return new AggregateSourceLocator($locators); }