Skip to content

Commit

Permalink
Support zero composer classloaders (#161)
Browse files Browse the repository at this point in the history
  • Loading branch information
janedbal authored Jul 15, 2024
1 parent 8875c57 commit 213c157
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 13 deletions.
2 changes: 1 addition & 1 deletion bin/composer-dependency-analyser
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
18 changes: 12 additions & 6 deletions src/Analyser.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -50,9 +51,12 @@ class Analyser
private $stopwatch;

/**
* vendorDir => ClassLoader
*
* @var array<string, ClassLoader>
* @var list<string>
*/
private $vendorDirs;

/**
* @var list<ClassLoader>
*/
private $classLoaders;

Expand Down Expand Up @@ -95,6 +99,7 @@ class Analyser
*/
public function __construct(
Stopwatch $stopwatch,
string $defaultVendorDir,
array $classLoaders,
Configuration $config,
array $composerJsonDependencies
Expand All @@ -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();
}
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
}
Expand Down
15 changes: 11 additions & 4 deletions src/ComposerJson.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@
class ComposerJson
{

/**
* @readonly
* @var string
*/
public $composerVendorDir;

/**
* @readonly
* @var string
Expand Down Expand Up @@ -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'] ?? [];
Expand Down Expand Up @@ -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);
}

}
17 changes: 15 additions & 2 deletions tests/AnalyserTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ public function test(callable $editConfig, AnalysisResult $expectedResult): void

$detector = new Analyser(
$this->getStopwatchMock(),
$vendorDir,
[$vendorDir => $this->getClassLoaderMock()],
$config,
$dependencies
Expand Down Expand Up @@ -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,
[]
);
Expand All @@ -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,
[]
);
Expand Down Expand Up @@ -538,6 +544,7 @@ public function testDevPathInsideProdPath(): void

$detector = new Analyser(
$this->getStopwatchMock(),
$vendorDir,
[$vendorDir => $this->getClassLoaderMock()],
$config,
[
Expand Down Expand Up @@ -565,6 +572,7 @@ public function testProdPathInsideDevPath(): void

$detector = new Analyser(
$this->getStopwatchMock(),
$vendorDir,
[$vendorDir => $this->getClassLoaderMock()],
$config,
[
Expand All @@ -591,6 +599,7 @@ public function testOtherSymbols(): void

$detector = new Analyser(
$this->getStopwatchMock(),
$vendorDir,
[$vendorDir => $this->getClassLoaderMock()],
$config,
[]
Expand Down Expand Up @@ -626,6 +635,7 @@ public function testPharSupport(): void

$detector = new Analyser(
$this->getStopwatchMock(),
$vendorDir,
[$vendorDir => $this->getClassLoaderMock()],
$config,
[
Expand Down Expand Up @@ -665,6 +675,7 @@ public function testMultipleClassloaders(): void

$detector = new Analyser(
$this->getStopwatchMock(),
$vendorDir,
$classLoaders,
$config,
[
Expand Down Expand Up @@ -692,6 +703,7 @@ public function testFunctions(): void

$detector = new Analyser(
$this->getStopwatchMock(),
$vendorDir,
[$vendorDir => $this->getClassLoaderMock()],
$config,
['org/package' => false]
Expand All @@ -713,6 +725,7 @@ public function testExplicitFileWithoutExtension(): void

$detector = new Analyser(
$this->getStopwatchMock(),
$vendorDir,
[$vendorDir => $this->getClassLoaderMock()],
$config,
[
Expand Down

0 comments on commit 213c157

Please sign in to comment.