From 56c65a58e2a1b6bded738cb4928a71957f9bb141 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Wed, 4 Nov 2020 23:41:58 +0100 Subject: [PATCH] Make platform-check only check non-dev requires, refs #9412 --- src/Composer/Autoload/AutoloadGenerator.php | 10 +++++++-- src/Composer/Installer.php | 3 +++ src/Composer/Package/Locker.php | 16 ++++++++++++++ .../Repository/FilesystemRepository.php | 14 +++++++++---- .../Repository/WritableArrayRepository.php | 21 +++++++++++++++++++ .../WritableRepositoryInterface.php | 10 +++++++++ .../Test/Autoload/AutoloadGeneratorTest.php | 9 +++++--- .../Repository/FilesystemRepositoryTest.php | 10 +++++++-- 8 files changed, 82 insertions(+), 11 deletions(-) diff --git a/src/Composer/Autoload/AutoloadGenerator.php b/src/Composer/Autoload/AutoloadGenerator.php index 75c5ed44f..71d40c116 100644 --- a/src/Composer/Autoload/AutoloadGenerator.php +++ b/src/Composer/Autoload/AutoloadGenerator.php @@ -192,6 +192,7 @@ return array( EOF; // Collect information from all packages. + $devPackageNames = $localRepo->getDevPackageNames(); $packageMap = $this->buildPackageMap($installationManager, $mainPackage, $localRepo->getCanonicalPackages()); $autoloads = $this->parseAutoloads($packageMap, $mainPackage, $this->devMode === false); @@ -350,7 +351,7 @@ EOF; $checkPlatform = $config->get('platform-check') && $this->ignorePlatformReqs !== true; $platformCheckContent = null; if ($checkPlatform) { - $platformCheckContent = $this->getPlatformCheck($packageMap, $this->ignorePlatformReqs ?: array(), $config->get('platform-check')); + $platformCheckContent = $this->getPlatformCheck($packageMap, $this->ignorePlatformReqs ?: array(), $config->get('platform-check'), $devPackageNames); if (null === $platformCheckContent) { $checkPlatform = false; } @@ -609,7 +610,7 @@ EOF; return $baseDir . (($path !== false) ? var_export($path, true) : ""); } - protected function getPlatformCheck($packageMap, array $ignorePlatformReqs, $checkPlatform) + protected function getPlatformCheck(array $packageMap, array $ignorePlatformReqs, $checkPlatform, array $devPackageNames) { $lowestPhpVersion = Bound::zero(); $requiredExtensions = array(); @@ -626,6 +627,11 @@ EOF; foreach ($packageMap as $item) { $package = $item[0]; + // skip dev dependencies platform requirements as platform-check really should only be a production safeguard + if (in_array($package->getName(), $devPackageNames, true)) { + continue; + } + foreach ($package->getRequires() as $link) { if (in_array($link->getTarget(), $ignorePlatformReqs, true)) { continue; diff --git a/src/Composer/Installer.php b/src/Composer/Installer.php index 7e83bf136..04ad49c25 100644 --- a/src/Composer/Installer.php +++ b/src/Composer/Installer.php @@ -708,6 +708,9 @@ class Installer } if ($this->executeOperations) { + if ($localRepo instanceof WritableRepositoryInterface) { + $localRepo->setDevPackageNames($this->locker->getDevPackageNames()); + } $this->installationManager->execute($localRepo, $localRepoTransaction->getOperations(), $this->devMode, $this->runScripts); } else { foreach ($localRepoTransaction->getOperations() as $operation) { diff --git a/src/Composer/Package/Locker.php b/src/Composer/Package/Locker.php index a4eef3efa..6cf4f1d28 100644 --- a/src/Composer/Package/Locker.php +++ b/src/Composer/Package/Locker.php @@ -198,6 +198,22 @@ class Locker throw new \RuntimeException('Your composer.lock is invalid. Run "composer update" to generate a new one.'); } + /** + * @return string[] Names of dependencies installed through require-dev + */ + public function getDevPackageNames() + { + $names = array(); + $lockData = $this->getLockData(); + if (isset($lockData['packages-dev'])) { + foreach ($lockData['packages-dev'] as $package) { + $names[] = strtolower($package['name']); + } + } + + return $names; + } + /** * Returns the platform requirements stored in the lock file * diff --git a/src/Composer/Repository/FilesystemRepository.php b/src/Composer/Repository/FilesystemRepository.php index 9125a97cd..b63c802a7 100644 --- a/src/Composer/Repository/FilesystemRepository.php +++ b/src/Composer/Repository/FilesystemRepository.php @@ -69,9 +69,8 @@ class FilesystemRepository extends WritableArrayRepository $packages = $data; } - // forward compatibility for composer v2 installed.json - if (isset($packages['packages'])) { - $packages = $packages['packages']; + if (isset($data['dev-package-names'])) { + $this->setDevPackageNames($data['dev-package-names']); } if (!is_array($packages)) { @@ -99,7 +98,7 @@ class FilesystemRepository extends WritableArrayRepository */ public function write($devMode, InstallationManager $installationManager) { - $data = array('packages' => array(), 'dev' => $devMode); + $data = array('packages' => array(), 'dev' => $devMode, 'dev-package-names' => array()); $dumper = new ArrayDumper(); $fs = new Filesystem(); $repoDir = dirname($fs->normalizePath($this->file->getPath())); @@ -109,8 +108,15 @@ class FilesystemRepository extends WritableArrayRepository $path = $installationManager->getInstallPath($package); $pkgArray['install-path'] = ('' !== $path && null !== $path) ? $fs->findShortestPath($repoDir, $fs->isAbsolutePath($path) ? $path : getcwd() . '/' . $path, true) : null; $data['packages'][] = $pkgArray; + + // only write to the files the names which are really installed, as we receive the full list + // of dev package names before they get installed during composer install + if (in_array($package->getName(), $this->devPackageNames, true)) { + $data['dev-package-names'][] = $package->getName(); + } } + sort($data['dev-package-names']); usort($data['packages'], function ($a, $b) { return strcmp($a['name'], $b['name']); }); diff --git a/src/Composer/Repository/WritableArrayRepository.php b/src/Composer/Repository/WritableArrayRepository.php index 3580593bb..de253112d 100644 --- a/src/Composer/Repository/WritableArrayRepository.php +++ b/src/Composer/Repository/WritableArrayRepository.php @@ -22,6 +22,27 @@ use Composer\Installer\InstallationManager; */ class WritableArrayRepository extends ArrayRepository implements WritableRepositoryInterface { + /** + * @var string[] + */ + protected $devPackageNames = array(); + + /** + * {@inheritDoc} + */ + public function setDevPackageNames(array $devPackageNames) + { + $this->devPackageNames = $devPackageNames; + } + + /** + * {@inheritDoc} + */ + public function getDevPackageNames() + { + return $this->devPackageNames; + } + /** * {@inheritDoc} */ diff --git a/src/Composer/Repository/WritableRepositoryInterface.php b/src/Composer/Repository/WritableRepositoryInterface.php index c35fdb257..f1d8b9e95 100644 --- a/src/Composer/Repository/WritableRepositoryInterface.php +++ b/src/Composer/Repository/WritableRepositoryInterface.php @@ -54,4 +54,14 @@ interface WritableRepositoryInterface extends RepositoryInterface * Forces a reload of all packages. */ public function reload(); + + /** + * @param string[] $devPackageNames + */ + public function setDevPackageNames(array $devPackageNames); + + /** + * @return string[] Names of dependencies installed through require-dev + */ + public function getDevPackageNames(); } diff --git a/tests/Composer/Test/Autoload/AutoloadGeneratorTest.php b/tests/Composer/Test/Autoload/AutoloadGeneratorTest.php index 4a6dd95f3..53837e90f 100644 --- a/tests/Composer/Test/Autoload/AutoloadGeneratorTest.php +++ b/tests/Composer/Test/Autoload/AutoloadGeneratorTest.php @@ -135,6 +135,9 @@ class AutoloadGeneratorTest extends TestCase return $that->vendorDir.'/'.$package->getName() . ($targetDir ? '/'.$targetDir : ''); })); $this->repository = $this->getMockBuilder('Composer\Repository\InstalledRepositoryInterface')->getMock(); + $this->repository->expects($this->any()) + ->method('getDevPackageNames') + ->willReturn(array()); $this->eventDispatcher = $this->getMockBuilder('Composer\EventDispatcher\EventDispatcher') ->disableOriginalConstructor() @@ -952,15 +955,15 @@ EOF; $notAutoloadPackages[] = $b = new Package('b/b', '1.0', '1.0'); $notAutoloadPackages[] = $c = new Package('c/c', '1.0', '1.0'); - $this->repository->expects($this->at(0)) + $this->repository->expects($this->at(1)) ->method('getCanonicalPackages') ->will($this->returnValue($autoloadPackages)); - $this->repository->expects($this->at(1)) + $this->repository->expects($this->at(3)) ->method('getCanonicalPackages') ->will($this->returnValue($notAutoloadPackages)); - $this->repository->expects($this->at(2)) + $this->repository->expects($this->at(5)) ->method('getCanonicalPackages') ->will($this->returnValue($notAutoloadPackages)); diff --git a/tests/Composer/Test/Repository/FilesystemRepositoryTest.php b/tests/Composer/Test/Repository/FilesystemRepositoryTest.php index 0f64f2488..7279f175b 100644 --- a/tests/Composer/Test/Repository/FilesystemRepositoryTest.php +++ b/tests/Composer/Test/Repository/FilesystemRepositoryTest.php @@ -84,7 +84,7 @@ class FilesystemRepositoryTest extends TestCase $im = $this->getMockBuilder('Composer\Installer\InstallationManager') ->disableOriginalConstructor() ->getMock(); - $im->expects($this->once()) + $im->expects($this->exactly(2)) ->method('getInstallPath') ->will($this->returnValue('/foo/bar/vendor/woop/woop')); @@ -104,10 +104,16 @@ class FilesystemRepositoryTest extends TestCase ->expects($this->once()) ->method('write') ->with(array( - 'packages' => array(array('name' => 'mypkg', 'type' => 'library', 'version' => '0.1.10', 'version_normalized' => '0.1.10.0', 'install-path' => '../woop/woop')), + 'packages' => array( + array('name' => 'mypkg', 'type' => 'library', 'version' => '0.1.10', 'version_normalized' => '0.1.10.0', 'install-path' => '../woop/woop'), + array('name' => 'mypkg2', 'type' => 'library', 'version' => '1.2.3', 'version_normalized' => '1.2.3.0', 'install-path' => '../woop/woop'), + ), 'dev' => true, + 'dev-package-names' => array('mypkg2'), )); + $repository->setDevPackageNames(array('mypkg2')); + $repository->addPackage($this->getPackage('mypkg2', '1.2.3')); $repository->addPackage($this->getPackage('mypkg', '0.1.10')); $repository->write(true, $im); }