diff --git a/bin/composer-dependency-analyser b/bin/composer-dependency-analyser index 459fba9..1093343 100755 --- a/bin/composer-dependency-analyser +++ b/bin/composer-dependency-analyser @@ -39,7 +39,7 @@ try { $configuration = $initializer->initConfiguration($options, $composerJson); $classLoaders = $initializer->initComposerClassLoaders(); - $analyser = new Analyser($stopwatch, $classLoaders, $configuration, $composerJson->dependencies); + $analyser = new Analyser($stopwatch, $composerJson->composerVendorDir, $classLoaders, $configuration, $composerJson->dependencies); $result = $analyser->run(); $formatter = $initializer->initFormatter($options); diff --git a/src/Analyser.php b/src/Analyser.php index 811d9a8..2c984bd 100644 --- a/src/Analyser.php +++ b/src/Analyser.php @@ -22,6 +22,7 @@ use function array_filter; use function array_key_exists; use function array_keys; +use function array_values; use function explode; use function file_get_contents; use function get_declared_classes; @@ -50,9 +51,12 @@ class Analyser private $stopwatch; /** - * vendorDir => ClassLoader - * - * @var array + * @var list + */ + private $vendorDirs; + + /** + * @var list */ private $classLoaders; @@ -95,6 +99,7 @@ class Analyser */ public function __construct( Stopwatch $stopwatch, + string $defaultVendorDir, array $classLoaders, Configuration $config, array $composerJsonDependencies @@ -103,7 +108,8 @@ public function __construct( $this->stopwatch = $stopwatch; $this->config = $config; $this->composerJsonDependencies = $composerJsonDependencies; - $this->classLoaders = $classLoaders; + $this->vendorDirs = array_keys($classLoaders + [$defaultVendorDir => null]); + $this->classLoaders = array_values($classLoaders); $this->initExistingSymbols(); } @@ -311,7 +317,7 @@ private function isDevDependency(string $packageName): bool private function getPackageNameFromVendorPath(string $realPath): string { - foreach ($this->classLoaders as $vendorDir => $_) { + foreach ($this->vendorDirs as $vendorDir) { if (strpos($realPath, $vendorDir) === 0) { $filePathInVendor = trim(str_replace($vendorDir, '', $realPath), DIRECTORY_SEPARATOR); [$vendor, $package] = explode(DIRECTORY_SEPARATOR, $filePathInVendor, 3); @@ -366,7 +372,7 @@ private function listPhpFilesIn(string $path): Generator private function isVendorPath(string $realPath): bool { - foreach ($this->classLoaders as $vendorDir => $_) { + foreach ($this->vendorDirs as $vendorDir) { if (strpos($realPath, $vendorDir) === 0) { return true; } diff --git a/src/ComposerJson.php b/src/ComposerJson.php index c43dc27..6280556 100644 --- a/src/ComposerJson.php +++ b/src/ComposerJson.php @@ -31,6 +31,12 @@ class ComposerJson { + /** + * @readonly + * @var string + */ + public $composerVendorDir; + /** * @readonly * @var string @@ -72,7 +78,8 @@ public function __construct( $basePath = dirname($composerJsonPath); $composerJsonData = $this->parseComposerJson($composerJsonPath); - $this->composerAutoloadPath = $this->resolveComposerAutoloadPath($basePath, $composerJsonData['config']['vendor-dir'] ?? 'vendor'); + $this->composerVendorDir = $this->resolveComposerVendorDir($basePath, $composerJsonData['config']['vendor-dir'] ?? 'vendor'); + $this->composerAutoloadPath = Path::normalize($this->composerVendorDir . '/autoload.php'); $requiredPackages = $composerJsonData['require'] ?? []; $requiredDevPackages = $composerJsonData['require-dev'] ?? []; @@ -261,13 +268,13 @@ private function parseComposerJson(string $composerJsonPath): array return $composerJsonData; // @phpstan-ignore-line ignore mixed returned } - private function resolveComposerAutoloadPath(string $basePath, string $vendorDir): string + private function resolveComposerVendorDir(string $basePath, string $vendorDir): string { if (Path::isAbsolute($vendorDir)) { - return Path::normalize($vendorDir . '/autoload.php'); + return Path::normalize($vendorDir); } - return Path::normalize($basePath . '/' . $vendorDir . '/autoload.php'); + return Path::normalize($basePath . '/' . $vendorDir); } } diff --git a/tests/AnalyserTest.php b/tests/AnalyserTest.php index 720de96..0f6ed15 100644 --- a/tests/AnalyserTest.php +++ b/tests/AnalyserTest.php @@ -45,6 +45,7 @@ public function test(callable $editConfig, AnalysisResult $expectedResult): void $detector = new Analyser( $this->getStopwatchMock(), + $vendorDir, [$vendorDir => $this->getClassLoaderMock()], $config, $dependencies @@ -477,12 +478,14 @@ public function testNativeTypesNotReported(): void $path = realpath(__DIR__ . '/data/not-autoloaded/builtin/native-symbols.php'); self::assertNotFalse($path); + $vendorDir = __DIR__; $config = new Configuration(); $config->addPathToScan($path, false); $detector = new Analyser( $this->getStopwatchMock(), - [__DIR__ => $this->getClassLoaderMock()], + $vendorDir, + [$vendorDir => $this->getClassLoaderMock()], $config, [] ); @@ -503,13 +506,16 @@ public function testNoMultipleScansOfTheSameFile(): void $path = realpath(__DIR__ . '/data/not-autoloaded/analysis/unknown-classes.php'); self::assertNotFalse($path); + $vendorDir = __DIR__ . '/data/autoloaded/vendor'; + $config = new Configuration(); $config->addPathToScan($path, true); $config->addPathToScan($path, true); $detector = new Analyser( $this->getStopwatchMock(), - [__DIR__ . '/data/autoloaded/vendor' => $this->getClassLoaderMock()], + $vendorDir, + [$vendorDir => $this->getClassLoaderMock()], $config, [] ); @@ -538,6 +544,7 @@ public function testDevPathInsideProdPath(): void $detector = new Analyser( $this->getStopwatchMock(), + $vendorDir, [$vendorDir => $this->getClassLoaderMock()], $config, [ @@ -565,6 +572,7 @@ public function testProdPathInsideDevPath(): void $detector = new Analyser( $this->getStopwatchMock(), + $vendorDir, [$vendorDir => $this->getClassLoaderMock()], $config, [ @@ -591,6 +599,7 @@ public function testOtherSymbols(): void $detector = new Analyser( $this->getStopwatchMock(), + $vendorDir, [$vendorDir => $this->getClassLoaderMock()], $config, [] @@ -626,6 +635,7 @@ public function testPharSupport(): void $detector = new Analyser( $this->getStopwatchMock(), + $vendorDir, [$vendorDir => $this->getClassLoaderMock()], $config, [ @@ -665,6 +675,7 @@ public function testMultipleClassloaders(): void $detector = new Analyser( $this->getStopwatchMock(), + $vendorDir, $classLoaders, $config, [ @@ -692,6 +703,7 @@ public function testFunctions(): void $detector = new Analyser( $this->getStopwatchMock(), + $vendorDir, [$vendorDir => $this->getClassLoaderMock()], $config, ['org/package' => false] @@ -713,6 +725,7 @@ public function testExplicitFileWithoutExtension(): void $detector = new Analyser( $this->getStopwatchMock(), + $vendorDir, [$vendorDir => $this->getClassLoaderMock()], $config, [