diff --git a/src/Composer/Command/InitCommand.php b/src/Composer/Command/InitCommand.php index 469df7ffb..e06b670b9 100644 --- a/src/Composer/Command/InitCommand.php +++ b/src/Composer/Command/InitCommand.php @@ -869,10 +869,10 @@ EOT return array($name, $requiredVersion ?: '*'); } - // Check whether the PHP version was the problem + // Check whether the package requirements were the problem if (true !== $ignorePlatformReqs && ($candidate = $versionSelector->findBestCandidate($name, $requiredVersion, $preferredStability, true))) { throw new \InvalidArgumentException(sprintf( - 'Package %s%s has a PHP requirement incompatible with your PHP version, PHP extensions and Composer version' . $this->getPlatformExceptionDetails($candidate, $platformRepo), + 'Package %s%s has requirements incompatible with your PHP version, PHP extensions and Composer version' . $this->getPlatformExceptionDetails($candidate, $platformRepo), $name, $requiredVersion ? ' at version '.$requiredVersion : '' )); diff --git a/src/Composer/Package/Version/VersionSelector.php b/src/Composer/Package/Version/VersionSelector.php index 046cccde6..79972999a 100644 --- a/src/Composer/Package/Version/VersionSelector.php +++ b/src/Composer/Package/Version/VersionSelector.php @@ -82,14 +82,20 @@ class VersionSelector $reqs = $pkg->getRequires(); foreach ($reqs as $name => $link) { - if (!in_array($name, $ignorePlatformReqs, true) && isset($platformConstraints[$name])) { - foreach ($platformConstraints[$name] as $constraint) { - if ($link->getConstraint()->matches($constraint)) { - continue 2; + if (!in_array($name, $ignorePlatformReqs, true)) { + if (isset($platformConstraints[$name])) { + foreach ($platformConstraints[$name] as $constraint) { + if ($link->getConstraint()->matches($constraint)) { + continue 2; + } } - } - return false; + return false; + } elseif (PlatformRepository::isPlatformPackage($name)) { + // Package requires a platform package that is unknown on current platform. + // It means that current platform cannot validate this constraint and so package is not installable. + return false; + } } } diff --git a/tests/Composer/Test/Package/Version/VersionSelectorTest.php b/tests/Composer/Test/Package/Version/VersionSelectorTest.php index abe77ba0f..e02470e6b 100644 --- a/tests/Composer/Test/Package/Version/VersionSelectorTest.php +++ b/tests/Composer/Test/Package/Version/VersionSelectorTest.php @@ -100,6 +100,31 @@ class VersionSelectorTest extends TestCase $this->assertSame($package2, $best, 'Latest version should be returned when ignoring platform reqs (2.0.0)'); } + public function testLatestVersionIsReturnedThatMatchesPlatformExt() + { + $packageName = 'foobar'; + + $platform = new PlatformRepository(); + $repositorySet = $this->createMockRepositorySet(); + $versionSelector = new VersionSelector($repositorySet, $platform); + + $parser = new VersionParser; + $package1 = $this->createPackage('1.0.0'); + $package2 = $this->createPackage('2.0.0'); + $package2->setRequires(array('ext-barfoo' => new Link($packageName, 'ext-barfoo', $parser->parseConstraints('*'), Link::TYPE_REQUIRE, '*'))); + $packages = array($package1, $package2); + + $repositorySet->expects($this->any()) + ->method('findPackages') + ->with($packageName, null) + ->will($this->returnValue($packages)); + + $best = $versionSelector->findBestCandidate($packageName); + $this->assertSame($package1, $best, 'Latest version not requiring ext-barfoo should be returned (1.0.0)'); + $best = $versionSelector->findBestCandidate($packageName, null, 'stable', true); + $this->assertSame($package2, $best, 'Latest version should be returned when ignoring platform reqs (2.0.0)'); + } + public function testLatestVersionIsReturnedThatMatchesComposerRequirements() { $packageName = 'foobar';