Fix autoload regression with metapackage dependencies (#11481)
fixes #11480 introduced by #11455pull/11494/head
parent
4893b67efa
commit
33c293aec3
|
@ -473,7 +473,7 @@ EOF;
|
|||
|
||||
/**
|
||||
* @param PackageInterface[] $packages
|
||||
* @return array<int, array{0: PackageInterface, 1: string}>
|
||||
* @return non-empty-array<int, array{0: PackageInterface, 1: string|null}>
|
||||
*/
|
||||
public function buildPackageMap(InstallationManager $installationManager, PackageInterface $rootPackage, array $packages)
|
||||
{
|
||||
|
@ -485,14 +485,9 @@ EOF;
|
|||
continue;
|
||||
}
|
||||
$this->validatePackage($package);
|
||||
$installPath = $installationManager->getInstallPath($package);
|
||||
if ($installPath === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$packageMap[] = [
|
||||
$package,
|
||||
$installPath,
|
||||
$installationManager->getInstallPath($package),
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -523,7 +518,7 @@ EOF;
|
|||
/**
|
||||
* Compiles an ordered list of namespace => path mappings
|
||||
*
|
||||
* @param array<int, array{0: PackageInterface, 1: string}> $packageMap array of array(package, installDir-relative-to-composer.json)
|
||||
* @param non-empty-array<int, array{0: PackageInterface, 1: string|null}> $packageMap array of array(package, installDir-relative-to-composer.json or null for metapackages)
|
||||
* @param RootPackageInterface $rootPackage root package instance
|
||||
* @param bool|string[] $filteredDevPackages If an array, the list of packages that must be removed. If bool, whether to filter out require-dev packages
|
||||
* @return array
|
||||
|
@ -613,7 +608,7 @@ EOF;
|
|||
}
|
||||
|
||||
/**
|
||||
* @param array<int, array{0: PackageInterface, 1: string}> $packageMap
|
||||
* @param array<int, array{0: PackageInterface, 1: string|null}> $packageMap
|
||||
* @return ?string
|
||||
*/
|
||||
protected function getIncludePathsFile(array $packageMap, Filesystem $filesystem, string $basePath, string $vendorPath, string $vendorPathCode, string $appBaseDirCode)
|
||||
|
@ -623,6 +618,11 @@ EOF;
|
|||
foreach ($packageMap as $item) {
|
||||
[$package, $installPath] = $item;
|
||||
|
||||
// packages that are not installed cannot autoload anything
|
||||
if (null === $installPath) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (null !== $package->getTargetDir() && strlen($package->getTargetDir()) > 0) {
|
||||
$installPath = substr($installPath, 0, -strlen('/'.$package->getTargetDir()));
|
||||
}
|
||||
|
@ -716,7 +716,7 @@ EOF;
|
|||
}
|
||||
|
||||
/**
|
||||
* @param array<int, array{0: PackageInterface, 1: string}> $packageMap
|
||||
* @param array<int, array{0: PackageInterface, 1: string|null}> $packageMap
|
||||
* @param bool|'php-only' $checkPlatform
|
||||
* @param string[] $devPackageNames
|
||||
* @return ?string
|
||||
|
@ -1149,7 +1149,7 @@ INITIALIZER;
|
|||
}
|
||||
|
||||
/**
|
||||
* @param array<int, array{0: PackageInterface, 1: string}> $packageMap
|
||||
* @param array<int, array{0: PackageInterface, 1: string|null}> $packageMap
|
||||
* @param string $type one of: 'psr-0'|'psr-4'|'classmap'|'files'
|
||||
* @return array<int, string>|array<string, array<string>>|array<string, string>
|
||||
*/
|
||||
|
@ -1160,6 +1160,11 @@ INITIALIZER;
|
|||
foreach ($packageMap as $item) {
|
||||
[$package, $installPath] = $item;
|
||||
|
||||
// packages that are not installed cannot autoload anything
|
||||
if (null === $installPath) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$autoload = $package->getAutoload();
|
||||
if ($this->devMode && $package === $rootPackage) {
|
||||
$autoload = array_merge_recursive($autoload, $package->getDevAutoload());
|
||||
|
@ -1249,10 +1254,8 @@ INITIALIZER;
|
|||
/**
|
||||
* Filters out dev-dependencies
|
||||
*
|
||||
* @param array<int, array{0: PackageInterface, 1: string}> $packageMap
|
||||
* @return array<int, array{0: PackageInterface, 1: string}>
|
||||
*
|
||||
* @phpstan-param array<int, array{0: PackageInterface, 1: string}> $packageMap
|
||||
* @param array<int, array{0: PackageInterface, 1: string|null}> $packageMap
|
||||
* @return array<int, array{0: PackageInterface, 1: string|null}>
|
||||
*/
|
||||
protected function filterPackageMap(array $packageMap, RootPackageInterface $rootPackage)
|
||||
{
|
||||
|
@ -1305,8 +1308,8 @@ INITIALIZER;
|
|||
*
|
||||
* Packages of equal weight are sorted alphabetically
|
||||
*
|
||||
* @param array<int, array{0: PackageInterface, 1: string}> $packageMap
|
||||
* @return array<int, array{0: PackageInterface, 1: string}>
|
||||
* @param array<int, array{0: PackageInterface, 1: string|null}> $packageMap
|
||||
* @return array<int, array{0: PackageInterface, 1: string|null}>
|
||||
*/
|
||||
protected function sortPackageMap(array $packageMap)
|
||||
{
|
||||
|
|
|
@ -131,7 +131,11 @@ class AutoloadGeneratorTest extends TestCase
|
|||
->getMock();
|
||||
$this->im->expects($this->any())
|
||||
->method('getInstallPath')
|
||||
->will($this->returnCallback(function ($package): string {
|
||||
->will($this->returnCallback(function ($package): ?string {
|
||||
if ($package->getType() === 'metapackage') {
|
||||
return null;
|
||||
}
|
||||
|
||||
$targetDir = $package->getTargetDir();
|
||||
|
||||
return $this->vendorDir.'/'.$package->getName() . ($targetDir ? '/'.$targetDir : '');
|
||||
|
@ -398,6 +402,40 @@ class AutoloadGeneratorTest extends TestCase
|
|||
$this->assertFileExists($this->vendorDir.'/composer/autoload_classmap.php', "ClassMap file needs to be generated, even if empty.");
|
||||
}
|
||||
|
||||
public function testVendorsAutoloadingWithMetapackages(): void
|
||||
{
|
||||
$package = new RootPackage('root/a', '1.0', '1.0');
|
||||
$package->setRequires([
|
||||
'a/a' => new Link('a', 'a/a', new MatchAllConstraint()),
|
||||
]);
|
||||
|
||||
$packages = [];
|
||||
$packages[] = $a = new Package('a/a', '1.0', '1.0');
|
||||
$packages[] = $b = new Package('b/b', '1.0', '1.0');
|
||||
$packages[] = $c = new AliasPackage($b, '1.2', '1.2');
|
||||
$a->setAutoload(['psr-0' => ['A' => 'src/', 'A\\B' => 'lib/']]);
|
||||
$b->setAutoload(['psr-0' => ['B\\Sub\\Name' => 'src/']]);
|
||||
$a->setType('metapackage');
|
||||
$a->setRequires([
|
||||
'b/b' => new Link('a/a', 'b/b', new MatchAllConstraint()),
|
||||
]);
|
||||
|
||||
$this->repository->expects($this->once())
|
||||
->method('getCanonicalPackages')
|
||||
->will($this->returnValue($packages));
|
||||
|
||||
$this->fs->ensureDirectoryExists($this->vendorDir.'/composer');
|
||||
$this->fs->ensureDirectoryExists($this->vendorDir.'/b/b/src');
|
||||
// creating a/a files to make sure they would be found by autoloader even tho they are technically not
|
||||
// needed as the package is a metapackage, but if it fails to be excluded it would find these
|
||||
$this->fs->ensureDirectoryExists($this->vendorDir.'/a/a/src');
|
||||
$this->fs->ensureDirectoryExists($this->vendorDir.'/a/a/lib');
|
||||
|
||||
$this->generator->dump($this->config, $this->repository, $package, $this->im, 'composer', false, '_5');
|
||||
$this->assertAutoloadFiles('vendors_meta', $this->vendorDir.'/composer');
|
||||
$this->assertFileExists($this->vendorDir.'/composer/autoload_classmap.php', "ClassMap file needs to be generated, even if empty.");
|
||||
}
|
||||
|
||||
public function testNonDevAutoloadExclusionWithRecursion(): void
|
||||
{
|
||||
$package = new RootPackage('root/a', '1.0', '1.0');
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
// autoload_namespaces.php @generated by Composer
|
||||
|
||||
$vendorDir = dirname(__DIR__);
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
'B\\Sub\\Name' => array($vendorDir . '/b/b/src'),
|
||||
);
|
Loading…
Reference in New Issue