diff --git a/src/Composer/Installer.php b/src/Composer/Installer.php index dad53d023..e1417019f 100644 --- a/src/Composer/Installer.php +++ b/src/Composer/Installer.php @@ -250,9 +250,14 @@ class Installer } } + $platformReqs = $this->extractPlatformRequirements($this->package->getRequires()); + $platformDevReqs = $this->devMode ? $this->extractPlatformRequirements($this->package->getDevRequires()) : array(); + $updatedLock = $this->locker->setLockData( array_diff($localRepo->getPackages(), (array) $devPackages), $devPackages, + $platformReqs, + $platformDevReqs, $aliases, $this->package->getMinimumStability(), $this->package->getStabilityFlags() @@ -350,6 +355,10 @@ class Installer $constraint->setPrettyString($package->getPrettyVersion()); $request->install($package->getName(), $constraint); } + + foreach ($this->locker->getPlatformRequirements($withDevReqs) as $link) { + $request->install($link->getTarget(), $link->getConstraint()); + } } else { $this->io->write('Installing dependencies'.($withDevReqs?' (including require-dev)':'').''); @@ -675,6 +684,17 @@ class Installer return false; } + private function extractPlatformRequirements($links) { + $platformReqs = array(); + foreach ($links as $link) { + if (preg_match('{^(?:php(?:-64bit)?|(?:ext|lib)-[^/]+)$}i', $link->getTarget())) { + $platformReqs[$link->getTarget()] = $link->getPrettyConstraint(); + } + } + + return $platformReqs; + } + /** * Adds all dependencies of the update whitelist to the whitelist, too. * diff --git a/src/Composer/Package/Locker.php b/src/Composer/Package/Locker.php index 424983787..e8390816a 100644 --- a/src/Composer/Package/Locker.php +++ b/src/Composer/Package/Locker.php @@ -20,6 +20,7 @@ use Composer\Package\AliasPackage; use Composer\Repository\ArrayRepository; use Composer\Package\Dumper\ArrayDumper; use Composer\Package\Loader\ArrayLoader; +use Composer\Package\Version\VersionParser; /** * Reads/writes project lockfile (composer.lock). @@ -178,6 +179,41 @@ class Locker return $packages; } + /** + * Returns the platform requirements stored in the lock file + * + * @param bool $withDevReqs if true, the platform requirements from the require-dev block are also returned + * @return \Composer\Package\Link[] + */ + public function getPlatformRequirements($withDevReqs = false) + { + $lockData = $this->getLockData(); + $versionParser = new VersionParser(); + $requirements = array(); + + if (!empty($lockData['platform'])) { + $requirements = $versionParser->parseLinks( + '__ROOT__', + '1.0.0', + 'requires', + isset($lockData['platform']) ? $lockData['platform'] : array() + ); + } + + if ($withDevReqs && !empty($lockData['platform-dev'])) { + $devRequirements = $versionParser->parseLinks( + '__ROOT__', + '1.0.0', + 'requires', + isset($lockData['platform-dev']) ? $lockData['platform-dev'] : array() + ); + + $requirements = array_merge($requirements, $devRequirements); + } + + return $requirements; + } + public function getMinimumStability() { $lockData = $this->getLockData(); @@ -217,13 +253,15 @@ class Locker * * @param array $packages array of packages * @param mixed $devPackages array of dev packages or null if installed without --dev + * @param array $platformReqs array of package name => constraint for required platform packages + * @param mixed $platformDevReqs array of package name => constraint for dev-required platform packages * @param array $aliases array of aliases * @param string $minimumStability * @param array $stabilityFlags * * @return bool */ - public function setLockData(array $packages, $devPackages, array $aliases, $minimumStability, array $stabilityFlags) + public function setLockData(array $packages, $devPackages, array $platformReqs, $platformDevReqs, array $aliases, $minimumStability, array $stabilityFlags) { $lock = array( 'hash' => $this->hash, @@ -258,6 +296,9 @@ class Locker return false; } + $lock['platform'] = $platformReqs; + $lock['platform-dev'] = $platformDevReqs; + if (!$this->isLocked() || $lock !== $this->getLockData()) { $this->lockFile->write($lock); $this->lockDataCache = null; diff --git a/tests/Composer/Test/Fixtures/installer/install-dev-using-dist.test b/tests/Composer/Test/Fixtures/installer/install-dev-using-dist.test index 69b56fa1d..91e30c546 100644 --- a/tests/Composer/Test/Fixtures/installer/install-dev-using-dist.test +++ b/tests/Composer/Test/Fixtures/installer/install-dev-using-dist.test @@ -46,7 +46,9 @@ install --prefer-dist "minimum-stability": "dev", "stability-flags": { "a/a": 20 - } + }, + "platform": [], + "platform-dev": [] } --EXPECT-- Installing a/a (dev-master) diff --git a/tests/Composer/Test/Fixtures/installer/update-alias-lock.test b/tests/Composer/Test/Fixtures/installer/update-alias-lock.test index f30f3a17f..46ce63b75 100644 --- a/tests/Composer/Test/Fixtures/installer/update-alias-lock.test +++ b/tests/Composer/Test/Fixtures/installer/update-alias-lock.test @@ -63,7 +63,9 @@ update "packages-dev": null, "aliases": [], "minimum-stability": "dev", - "stability-flags": [] + "stability-flags": [], + "platform": [], + "platform-dev": [] } --EXPECT-- Updating a/a (dev-master 1234) to a/a (dev-master master) \ No newline at end of file diff --git a/tests/Composer/Test/Fixtures/installer/updating-dev-updates-url-and-reference.test b/tests/Composer/Test/Fixtures/installer/updating-dev-updates-url-and-reference.test index 272dfc819..ee92652e6 100644 --- a/tests/Composer/Test/Fixtures/installer/updating-dev-updates-url-and-reference.test +++ b/tests/Composer/Test/Fixtures/installer/updating-dev-updates-url-and-reference.test @@ -56,7 +56,9 @@ update "packages-dev": null, "aliases": [], "minimum-stability": "dev", - "stability-flags": {"a/a":20} + "stability-flags": {"a/a":20}, + "platform": [], + "platform-dev": [] } --EXPECT-- Updating a/a (dev-master oldref) to a/a (dev-master newref) diff --git a/tests/Composer/Test/Package/LockerTest.php b/tests/Composer/Test/Package/LockerTest.php index b9b1950c9..35cb90e04 100644 --- a/tests/Composer/Test/Package/LockerTest.php +++ b/tests/Composer/Test/Package/LockerTest.php @@ -171,9 +171,11 @@ class LockerTest extends \PHPUnit_Framework_TestCase 'aliases' => array(), 'minimum-stability' => 'dev', 'stability-flags' => array(), + 'platform' => array(), + 'platform-dev' => array(), )); - $locker->setLockData(array($package1, $package2), array(), array(), 'dev', array()); + $locker->setLockData(array($package1, $package2), array(), array(), array(), array(), 'dev', array()); } public function testLockBadPackages() @@ -192,7 +194,7 @@ class LockerTest extends \PHPUnit_Framework_TestCase $this->setExpectedException('LogicException'); - $locker->setLockData(array($package1), array(), array(), 'dev', array()); + $locker->setLockData(array($package1), array(), array(), array(), array(), 'dev', array()); } public function testIsFresh()