1
0
Fork 0

Merge branch '2.5'

pull/11485/head
Jordi Boggiano 2023-05-24 15:00:53 +02:00
commit 52f6f74b7c
No known key found for this signature in database
GPG Key ID: 7BBD42C429EC80BC
4 changed files with 74 additions and 18 deletions

View File

@ -1,3 +1,7 @@
### [2.5.7] 2023-05-24
* Fixed regression preventing autoloading the dependencies of metapackages when running --no-dev (#11481)
### [2.5.6] 2023-05-24 ### [2.5.6] 2023-05-24
* BC Warning: Installers and `InstallationManager::getInstallPath` will now return `null` instead of an empty string for metapackages' paths. This may have adverse effects on plugin code using this expecting always a string but it is unlikely (#11455) * BC Warning: Installers and `InstallationManager::getInstallPath` will now return `null` instead of an empty string for metapackages' paths. This may have adverse effects on plugin code using this expecting always a string but it is unlikely (#11455)
@ -1720,6 +1724,7 @@
* Initial release * Initial release
[2.5.7]: https://github.com/composer/composer/compare/2.5.6...2.5.7
[2.5.6]: https://github.com/composer/composer/compare/2.5.5...2.5.6 [2.5.6]: https://github.com/composer/composer/compare/2.5.5...2.5.6
[2.5.5]: https://github.com/composer/composer/compare/2.5.4...2.5.5 [2.5.5]: https://github.com/composer/composer/compare/2.5.4...2.5.5
[2.5.4]: https://github.com/composer/composer/compare/2.5.3...2.5.4 [2.5.4]: https://github.com/composer/composer/compare/2.5.3...2.5.4

View File

@ -473,7 +473,7 @@ EOF;
/** /**
* @param PackageInterface[] $packages * @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) public function buildPackageMap(InstallationManager $installationManager, PackageInterface $rootPackage, array $packages)
{ {
@ -485,14 +485,9 @@ EOF;
continue; continue;
} }
$this->validatePackage($package); $this->validatePackage($package);
$installPath = $installationManager->getInstallPath($package);
if ($installPath === null) {
continue;
}
$packageMap[] = [ $packageMap[] = [
$package, $package,
$installPath, $installationManager->getInstallPath($package),
]; ];
} }
@ -523,7 +518,7 @@ EOF;
/** /**
* Compiles an ordered list of namespace => path mappings * 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 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 * @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 * @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 * @return ?string
*/ */
protected function getIncludePathsFile(array $packageMap, Filesystem $filesystem, string $basePath, string $vendorPath, string $vendorPathCode, string $appBaseDirCode) protected function getIncludePathsFile(array $packageMap, Filesystem $filesystem, string $basePath, string $vendorPath, string $vendorPathCode, string $appBaseDirCode)
@ -623,6 +618,11 @@ EOF;
foreach ($packageMap as $item) { foreach ($packageMap as $item) {
[$package, $installPath] = $item; [$package, $installPath] = $item;
// packages that are not installed cannot autoload anything
if (null === $installPath) {
continue;
}
if (null !== $package->getTargetDir() && strlen($package->getTargetDir()) > 0) { if (null !== $package->getTargetDir() && strlen($package->getTargetDir()) > 0) {
$installPath = substr($installPath, 0, -strlen('/'.$package->getTargetDir())); $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 bool|'php-only' $checkPlatform
* @param string[] $devPackageNames * @param string[] $devPackageNames
* @return ?string * @return ?string
@ -1164,7 +1164,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' * @param string $type one of: 'psr-0'|'psr-4'|'classmap'|'files'
* @return array<int, string>|array<string, array<string>>|array<string, string> * @return array<int, string>|array<string, array<string>>|array<string, string>
*/ */
@ -1175,6 +1175,11 @@ INITIALIZER;
foreach ($packageMap as $item) { foreach ($packageMap as $item) {
[$package, $installPath] = $item; [$package, $installPath] = $item;
// packages that are not installed cannot autoload anything
if (null === $installPath) {
continue;
}
$autoload = $package->getAutoload(); $autoload = $package->getAutoload();
if ($this->devMode && $package === $rootPackage) { if ($this->devMode && $package === $rootPackage) {
$autoload = array_merge_recursive($autoload, $package->getDevAutoload()); $autoload = array_merge_recursive($autoload, $package->getDevAutoload());
@ -1264,10 +1269,8 @@ INITIALIZER;
/** /**
* Filters out dev-dependencies * Filters out dev-dependencies
* *
* @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}> * @return array<int, array{0: PackageInterface, 1: string|null}>
*
* @phpstan-param array<int, array{0: PackageInterface, 1: string}> $packageMap
*/ */
protected function filterPackageMap(array $packageMap, RootPackageInterface $rootPackage) protected function filterPackageMap(array $packageMap, RootPackageInterface $rootPackage)
{ {
@ -1320,8 +1323,8 @@ INITIALIZER;
* *
* Packages of equal weight are sorted alphabetically * Packages of equal weight are sorted alphabetically
* *
* @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}> * @return array<int, array{0: PackageInterface, 1: string|null}>
*/ */
protected function sortPackageMap(array $packageMap) protected function sortPackageMap(array $packageMap)
{ {

View File

@ -131,7 +131,11 @@ class AutoloadGeneratorTest extends TestCase
->getMock(); ->getMock();
$this->im->expects($this->any()) $this->im->expects($this->any())
->method('getInstallPath') ->method('getInstallPath')
->will($this->returnCallback(function ($package): string { ->will($this->returnCallback(function ($package): ?string {
if ($package->getType() === 'metapackage') {
return null;
}
$targetDir = $package->getTargetDir(); $targetDir = $package->getTargetDir();
return $this->vendorDir.'/'.$package->getName() . ($targetDir ? '/'.$targetDir : ''); 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."); $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 public function testNonDevAutoloadExclusionWithRecursion(): void
{ {
$package = new RootPackage('root/a', '1.0', '1.0'); $package = new RootPackage('root/a', '1.0', '1.0');

View File

@ -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'),
);