diff --git a/src/Composer/Package/Loader/ValidatingArrayLoader.php b/src/Composer/Package/Loader/ValidatingArrayLoader.php index 383956e79..ddd9ca328 100644 --- a/src/Composer/Package/Loader/ValidatingArrayLoader.php +++ b/src/Composer/Package/Loader/ValidatingArrayLoader.php @@ -16,24 +16,30 @@ use Composer\Package; use Composer\Package\BasePackage; use Composer\Package\LinkConstraint\VersionConstraint; use Composer\Package\Version\VersionParser; +use Composer\Repository\PlatformRepository; /** * @author Jordi Boggiano */ class ValidatingArrayLoader implements LoaderInterface { + const CHECK_ALL = 1; + const CHECK_UNBOUND_CONSTRAINTS = 1; + private $loader; private $versionParser; private $errors; private $warnings; private $config; private $strictName; + private $flags; - public function __construct(LoaderInterface $loader, $strictName = true, VersionParser $parser = null) + public function __construct(LoaderInterface $loader, $strictName = true, VersionParser $parser = null, $flags = 0) { $this->loader = $loader; $this->versionParser = $parser ?: new VersionParser(); $this->strictName = $strictName; + $this->flags = $flags; } public function load(array $config, $class = 'Composer\Package\CompletePackage') @@ -163,20 +169,17 @@ class ValidatingArrayLoader implements LoaderInterface continue; } - if ('conflict' === $linkType || 'require-dev' === $linkType) { - continue; // conflict can be unbound, and require-dev constraints will not impact shared libraries as they are root-only - } - - if ($linkConstraint->matches($unboundConstraint)) { - $this->warnings[] = $linkType.'.'.$package.' : unbound version constraint detected ('.$constraint.')'; - unset($this->config[$linkType][$package]); + // check requires for unbound constraints on non-platform packages + if ( + ($this->flags & self::CHECK_UNBOUND_CONSTRAINTS) + && 'require' === $linkType + && $linkConstraint->matches($unboundConstraint) + && !preg_match(PlatformRepository::PLATFORM_PACKAGE_REGEX, $package) + ) { + $this->warnings[] = $linkType.'.'.$package.' : unbound version constraints ('.$constraint.') should be avoided'; } } } - - if (empty($this->config[$linkType])) { - unset($this->config[$linkType]); - } } } diff --git a/src/Composer/Repository/PlatformRepository.php b/src/Composer/Repository/PlatformRepository.php index 2b462fca9..f1a27c648 100644 --- a/src/Composer/Repository/PlatformRepository.php +++ b/src/Composer/Repository/PlatformRepository.php @@ -21,7 +21,7 @@ use Composer\Plugin\PluginInterface; */ class PlatformRepository extends ArrayRepository { - const PLATFORM_PACKAGE_REGEX = '{^(?:php(?:-64bit)?|(?:ext|lib)-[^/]+)$}i'; + const PLATFORM_PACKAGE_REGEX = '{^(?:php(?:-64bit)?|hhvm|(?:ext|lib)-[^/]+)$}i'; protected function initialize() { diff --git a/src/Composer/Util/ConfigValidator.php b/src/Composer/Util/ConfigValidator.php index 5bd915388..731575e90 100644 --- a/src/Composer/Util/ConfigValidator.php +++ b/src/Composer/Util/ConfigValidator.php @@ -119,7 +119,7 @@ class ConfigValidator } try { - $loader = new ValidatingArrayLoader(new ArrayLoader()); + $loader = new ValidatingArrayLoader(new ArrayLoader(), true, null, ValidatingArrayLoader::CHECK_ALL); if (!isset($manifest['version'])) { $manifest['version'] = '1.0.0'; } diff --git a/tests/Composer/Test/Package/Loader/ValidatingArrayLoaderTest.php b/tests/Composer/Test/Package/Loader/ValidatingArrayLoaderTest.php index b64fc0624..09bb4afd9 100644 --- a/tests/Composer/Test/Package/Loader/ValidatingArrayLoaderTest.php +++ b/tests/Composer/Test/Package/Loader/ValidatingArrayLoaderTest.php @@ -29,7 +29,7 @@ class ValidatingArrayLoaderTest extends \PHPUnit_Framework_TestCase ->method('load') ->with($config); - $loader = new ValidatingArrayLoader($internalLoader); + $loader = new ValidatingArrayLoader($internalLoader, true, null, ValidatingArrayLoader::CHECK_ALL); $loader->load($config); } @@ -163,7 +163,7 @@ class ValidatingArrayLoaderTest extends \PHPUnit_Framework_TestCase public function testLoadFailureThrowsException($config, $expectedErrors) { $internalLoader = $this->getMock('Composer\Package\Loader\LoaderInterface'); - $loader = new ValidatingArrayLoader($internalLoader); + $loader = new ValidatingArrayLoader($internalLoader, true, null, ValidatingArrayLoader::CHECK_ALL); try { $loader->load($config); $this->fail('Expected exception to be thrown'); @@ -181,7 +181,7 @@ class ValidatingArrayLoaderTest extends \PHPUnit_Framework_TestCase public function testLoadWarnings($config, $expectedWarnings) { $internalLoader = $this->getMock('Composer\Package\Loader\LoaderInterface'); - $loader = new ValidatingArrayLoader($internalLoader); + $loader = new ValidatingArrayLoader($internalLoader, true, null, ValidatingArrayLoader::CHECK_ALL); $loader->load($config); $warnings = $loader->getWarnings(); @@ -193,15 +193,19 @@ class ValidatingArrayLoaderTest extends \PHPUnit_Framework_TestCase /** * @dataProvider warningProvider */ - public function testLoadSkipsWarningDataWhenIgnoringErrors($config) + public function testLoadSkipsWarningDataWhenIgnoringErrors($config, $expectedWarnings, $mustCheck = true) { + if (!$mustCheck) { + $this->assertTrue(true); + return; + } $internalLoader = $this->getMock('Composer\Package\Loader\LoaderInterface'); $internalLoader ->expects($this->once()) ->method('load') ->with(array('name' => 'a/b')); - $loader = new ValidatingArrayLoader($internalLoader); + $loader = new ValidatingArrayLoader($internalLoader, true, null, ValidatingArrayLoader::CHECK_ALL); $config['name'] = 'a/b'; $loader->load($config); } @@ -297,20 +301,17 @@ class ValidatingArrayLoaderTest extends \PHPUnit_Framework_TestCase 'require' => array( 'foo/baz' => '*', 'bar/baz' => '>=1.0', - ), - 'provide' => array( 'bar/foo' => 'dev-master', - ), - 'replace' => array( 'bar/hacked' => '@stable', - ) + ), ), array( - 'require.foo/baz : unbound version constraint detected (*)', - 'require.bar/baz : unbound version constraint detected (>=1.0)', - 'provide.bar/foo : unbound version constraint detected (dev-master)', - 'replace.bar/hacked : unbound version constraint detected (@stable)', - ) + 'require.foo/baz : unbound version constraints (*) should be avoided', + 'require.bar/baz : unbound version constraints (>=1.0) should be avoided', + 'require.bar/foo : unbound version constraints (dev-master) should be avoided', + 'require.bar/hacked : unbound version constraints (@stable) should be avoided', + ), + false ), ); }