Skip to content

Commit 213c157

Browse files
authored
Support zero composer classloaders (#161)
1 parent 8875c57 commit 213c157

File tree

4 files changed

+39
-13
lines changed

4 files changed

+39
-13
lines changed

bin/composer-dependency-analyser

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ try {
3939
$configuration = $initializer->initConfiguration($options, $composerJson);
4040
$classLoaders = $initializer->initComposerClassLoaders();
4141

42-
$analyser = new Analyser($stopwatch, $classLoaders, $configuration, $composerJson->dependencies);
42+
$analyser = new Analyser($stopwatch, $composerJson->composerVendorDir, $classLoaders, $configuration, $composerJson->dependencies);
4343
$result = $analyser->run();
4444

4545
$formatter = $initializer->initFormatter($options);

src/Analyser.php

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
use function array_filter;
2323
use function array_key_exists;
2424
use function array_keys;
25+
use function array_values;
2526
use function explode;
2627
use function file_get_contents;
2728
use function get_declared_classes;
@@ -50,9 +51,12 @@ class Analyser
5051
private $stopwatch;
5152

5253
/**
53-
* vendorDir => ClassLoader
54-
*
55-
* @var array<string, ClassLoader>
54+
* @var list<string>
55+
*/
56+
private $vendorDirs;
57+
58+
/**
59+
* @var list<ClassLoader>
5660
*/
5761
private $classLoaders;
5862

@@ -95,6 +99,7 @@ class Analyser
9599
*/
96100
public function __construct(
97101
Stopwatch $stopwatch,
102+
string $defaultVendorDir,
98103
array $classLoaders,
99104
Configuration $config,
100105
array $composerJsonDependencies
@@ -103,7 +108,8 @@ public function __construct(
103108
$this->stopwatch = $stopwatch;
104109
$this->config = $config;
105110
$this->composerJsonDependencies = $composerJsonDependencies;
106-
$this->classLoaders = $classLoaders;
111+
$this->vendorDirs = array_keys($classLoaders + [$defaultVendorDir => null]);
112+
$this->classLoaders = array_values($classLoaders);
107113

108114
$this->initExistingSymbols();
109115
}
@@ -311,7 +317,7 @@ private function isDevDependency(string $packageName): bool
311317

312318
private function getPackageNameFromVendorPath(string $realPath): string
313319
{
314-
foreach ($this->classLoaders as $vendorDir => $_) {
320+
foreach ($this->vendorDirs as $vendorDir) {
315321
if (strpos($realPath, $vendorDir) === 0) {
316322
$filePathInVendor = trim(str_replace($vendorDir, '', $realPath), DIRECTORY_SEPARATOR);
317323
[$vendor, $package] = explode(DIRECTORY_SEPARATOR, $filePathInVendor, 3);
@@ -366,7 +372,7 @@ private function listPhpFilesIn(string $path): Generator
366372

367373
private function isVendorPath(string $realPath): bool
368374
{
369-
foreach ($this->classLoaders as $vendorDir => $_) {
375+
foreach ($this->vendorDirs as $vendorDir) {
370376
if (strpos($realPath, $vendorDir) === 0) {
371377
return true;
372378
}

src/ComposerJson.php

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,12 @@
3131
class ComposerJson
3232
{
3333

34+
/**
35+
* @readonly
36+
* @var string
37+
*/
38+
public $composerVendorDir;
39+
3440
/**
3541
* @readonly
3642
* @var string
@@ -72,7 +78,8 @@ public function __construct(
7278
$basePath = dirname($composerJsonPath);
7379

7480
$composerJsonData = $this->parseComposerJson($composerJsonPath);
75-
$this->composerAutoloadPath = $this->resolveComposerAutoloadPath($basePath, $composerJsonData['config']['vendor-dir'] ?? 'vendor');
81+
$this->composerVendorDir = $this->resolveComposerVendorDir($basePath, $composerJsonData['config']['vendor-dir'] ?? 'vendor');
82+
$this->composerAutoloadPath = Path::normalize($this->composerVendorDir . '/autoload.php');
7683

7784
$requiredPackages = $composerJsonData['require'] ?? [];
7885
$requiredDevPackages = $composerJsonData['require-dev'] ?? [];
@@ -261,13 +268,13 @@ private function parseComposerJson(string $composerJsonPath): array
261268
return $composerJsonData; // @phpstan-ignore-line ignore mixed returned
262269
}
263270

264-
private function resolveComposerAutoloadPath(string $basePath, string $vendorDir): string
271+
private function resolveComposerVendorDir(string $basePath, string $vendorDir): string
265272
{
266273
if (Path::isAbsolute($vendorDir)) {
267-
return Path::normalize($vendorDir . '/autoload.php');
274+
return Path::normalize($vendorDir);
268275
}
269276

270-
return Path::normalize($basePath . '/' . $vendorDir . '/autoload.php');
277+
return Path::normalize($basePath . '/' . $vendorDir);
271278
}
272279

273280
}

tests/AnalyserTest.php

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ public function test(callable $editConfig, AnalysisResult $expectedResult): void
4545

4646
$detector = new Analyser(
4747
$this->getStopwatchMock(),
48+
$vendorDir,
4849
[$vendorDir => $this->getClassLoaderMock()],
4950
$config,
5051
$dependencies
@@ -477,12 +478,14 @@ public function testNativeTypesNotReported(): void
477478
$path = realpath(__DIR__ . '/data/not-autoloaded/builtin/native-symbols.php');
478479
self::assertNotFalse($path);
479480

481+
$vendorDir = __DIR__;
480482
$config = new Configuration();
481483
$config->addPathToScan($path, false);
482484

483485
$detector = new Analyser(
484486
$this->getStopwatchMock(),
485-
[__DIR__ => $this->getClassLoaderMock()],
487+
$vendorDir,
488+
[$vendorDir => $this->getClassLoaderMock()],
486489
$config,
487490
[]
488491
);
@@ -503,13 +506,16 @@ public function testNoMultipleScansOfTheSameFile(): void
503506
$path = realpath(__DIR__ . '/data/not-autoloaded/analysis/unknown-classes.php');
504507
self::assertNotFalse($path);
505508

509+
$vendorDir = __DIR__ . '/data/autoloaded/vendor';
510+
506511
$config = new Configuration();
507512
$config->addPathToScan($path, true);
508513
$config->addPathToScan($path, true);
509514

510515
$detector = new Analyser(
511516
$this->getStopwatchMock(),
512-
[__DIR__ . '/data/autoloaded/vendor' => $this->getClassLoaderMock()],
517+
$vendorDir,
518+
[$vendorDir => $this->getClassLoaderMock()],
513519
$config,
514520
[]
515521
);
@@ -538,6 +544,7 @@ public function testDevPathInsideProdPath(): void
538544

539545
$detector = new Analyser(
540546
$this->getStopwatchMock(),
547+
$vendorDir,
541548
[$vendorDir => $this->getClassLoaderMock()],
542549
$config,
543550
[
@@ -565,6 +572,7 @@ public function testProdPathInsideDevPath(): void
565572

566573
$detector = new Analyser(
567574
$this->getStopwatchMock(),
575+
$vendorDir,
568576
[$vendorDir => $this->getClassLoaderMock()],
569577
$config,
570578
[
@@ -591,6 +599,7 @@ public function testOtherSymbols(): void
591599

592600
$detector = new Analyser(
593601
$this->getStopwatchMock(),
602+
$vendorDir,
594603
[$vendorDir => $this->getClassLoaderMock()],
595604
$config,
596605
[]
@@ -626,6 +635,7 @@ public function testPharSupport(): void
626635

627636
$detector = new Analyser(
628637
$this->getStopwatchMock(),
638+
$vendorDir,
629639
[$vendorDir => $this->getClassLoaderMock()],
630640
$config,
631641
[
@@ -665,6 +675,7 @@ public function testMultipleClassloaders(): void
665675

666676
$detector = new Analyser(
667677
$this->getStopwatchMock(),
678+
$vendorDir,
668679
$classLoaders,
669680
$config,
670681
[
@@ -692,6 +703,7 @@ public function testFunctions(): void
692703

693704
$detector = new Analyser(
694705
$this->getStopwatchMock(),
706+
$vendorDir,
695707
[$vendorDir => $this->getClassLoaderMock()],
696708
$config,
697709
['org/package' => false]
@@ -713,6 +725,7 @@ public function testExplicitFileWithoutExtension(): void
713725

714726
$detector = new Analyser(
715727
$this->getStopwatchMock(),
728+
$vendorDir,
716729
[$vendorDir => $this->getClassLoaderMock()],
717730
$config,
718731
[

0 commit comments

Comments
 (0)