1
0
Fork 0

Add wildcard support to ignore-platform-req, fixes #10045 (#10083)

pull/9261/head
Martin Herndl 2021-11-11 15:56:38 +01:00 committed by GitHub
parent 8542321a31
commit 7eca450d9b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 180 additions and 16 deletions

View File

@ -117,7 +117,7 @@ resolution.
See also the [`platform`](06-config.md#platform) config option.
* **--ignore-platform-req:** ignore a specific platform requirement(`php`,
`hhvm`, `lib-*` and `ext-*`) and force the installation even if the local machine
does not fulfill it.
does not fulfill it. Multiple requirements can be ignored via wildcard.
## update / u
@ -202,7 +202,7 @@ php composer.phar update vendor/package:2.0.1 vendor/package2:3.0.*
See also the [`platform`](06-config.md#platform) config option.
* **--ignore-platform-req:** ignore a specific platform requirement(`php`,
`hhvm`, `lib-*` and `ext-*`) and force the installation even if the local machine
does not fulfill it.
does not fulfill it. Multiple requirements can be ignored via wildcard.
* **--prefer-stable:** Prefer stable versions of dependencies.
* **--prefer-lowest:** Prefer lowest versions of dependencies. Useful for testing minimal
versions of requirements, generally used with `--prefer-stable`.
@ -258,7 +258,7 @@ If you do not specify a package, Composer will prompt you to search for a packag
See also the [`platform`](06-config.md#platform) config option.
* **--ignore-platform-req:** ignore a specific platform requirement(`php`,
`hhvm`, `lib-*` and `ext-*`) and force the installation even if the local machine
does not fulfill it.
does not fulfill it. Multiple requirements can be ignored via wildcard.
* **--prefer-stable:** Prefer stable versions of dependencies.
* **--prefer-lowest:** Prefer lowest versions of dependencies. Useful for testing minimal
versions of requirements, generally used with `--prefer-stable`.
@ -303,7 +303,7 @@ uninstalled.
See also the [`platform`](06-config.md#platform) config option.
* **--ignore-platform-req:** ignore a specific platform requirement(`php`,
`hhvm`, `lib-*` and `ext-*`) and force the installation even if the local machine
does not fulfill it.
does not fulfill it. Multiple requirements can be ignored via wildcard.
* **--optimize-autoloader (-o):** Convert PSR-0/4 autoloading to classmap to
get a faster autoloader. This is recommended especially for production, but
can take a bit of time to run so it is currently not done by default.
@ -358,7 +358,7 @@ php composer.phar reinstall "acme/*"
reinstall command.
* **--ignore-platform-req:** ignore a specific platform requirement. This only
has an effect in the context of the autoloader generation for the
reinstall command.
reinstall command. Multiple requirements can be ignored via wildcard.
## check-platform-reqs
@ -839,7 +839,7 @@ By default the command checks for the packages on packagist.org.
See also the [`platform`](06-config.md#platform) config option.
* **--ignore-platform-req:** ignore a specific platform requirement(`php`,
`hhvm`, `lib-*` and `ext-*`) and force the installation even if the local machine
does not fulfill it.
does not fulfill it. Multiple requirements can be ignored via wildcard.
* **--ask:** Ask user to provide target directory for new project.
## dump-autoload (dumpautoload)
@ -874,6 +874,7 @@ performance.
See also the [`platform`](06-config.md#platform) config option.
* **--ignore-platform-req:** ignore a specific platform requirement (`php`, `hhvm`,
`lib-*` and `ext-*`) and skip the [platform check](07-runtime.md#platform-check) for it.
Multiple requirements can be ignored via wildcard.
## clear-cache / clearcache / cc

View File

@ -2,21 +2,22 @@
namespace Composer\Filter\PlatformRequirementFilter;
use Composer\Package\BasePackage;
use Composer\Repository\PlatformRepository;
final class IgnoreListPlatformRequirementFilter implements PlatformRequirementFilterInterface
{
/**
* @var string[]
* @var string
*/
private $reqList;
private $regexp;
/**
* @param string[] $reqList
*/
public function __construct(array $reqList)
{
$this->reqList = $reqList;
$this->regexp = BasePackage::packageNamesToRegexp($reqList);
}
/**
@ -29,6 +30,6 @@ final class IgnoreListPlatformRequirementFilter implements PlatformRequirementFi
return false;
}
return in_array($req, $this->reqList, true);
return 1 === preg_match($this->regexp, $req);
}
}

View File

@ -263,4 +263,23 @@ abstract class BasePackage implements PackageInterface
return sprintf($wrap, $cleanedAllowPattern);
}
/**
* Build a regexp from package names, expanding * globs as required
*
* @param string[] $packageNames
* @param string $wrap
* @return string
*/
public static function packageNamesToRegexp(array $packageNames, $wrap = '{^(?:%s)$}iD')
{
$packageNames = array_map(
function ($packageName) {
return BasePackage::packageNameToRegexp($packageName, '%s');
},
$packageNames
);
return sprintf($wrap, implode('|', $packageNames));
}
}

View File

@ -40,17 +40,13 @@ class FilterRepository implements RepositoryInterface
if (!is_array($options['only'])) {
throw new \InvalidArgumentException('"only" key for repository '.$repo->getRepoName().' should be an array');
}
$this->only = '{^(?:'.implode('|', array_map(function ($val) {
return BasePackage::packageNameToRegexp($val, '%s');
}, $options['only'])) .')$}iD';
$this->only = BasePackage::packageNamesToRegexp($options['only']);
}
if (isset($options['exclude'])) {
if (!is_array($options['exclude'])) {
throw new \InvalidArgumentException('"exclude" key for repository '.$repo->getRepoName().' should be an array');
}
$this->exclude = '{^(?:'.implode('|', array_map(function ($val) {
return BasePackage::packageNameToRegexp($val, '%s');
}, $options['exclude'])) .')$}iD';
$this->exclude = BasePackage::packageNamesToRegexp($options['exclude']);
}
if ($this->exclude && $this->only) {
throw new \InvalidArgumentException('Only one of "only" and "exclude" can be specified for repository '.$repo->getRepoName());

View File

@ -1808,6 +1808,20 @@ EOF;
array(),
array('php', 'ext-pdo'),
),
'Via wildcard ignored platform requirements are not checked for' => array(
array(
new Link('a', 'php', $versionParser->parseConstraints('^7.2.8')),
new Link('a', 'ext-xml', $versionParser->parseConstraints('*')),
new Link('a', 'ext-json', $versionParser->parseConstraints('*')),
new Link('a', 'ext-fileinfo', $versionParser->parseConstraints('*')),
new Link('a', 'ext-filesystem', $versionParser->parseConstraints('*')),
new Link('a', 'ext-filter', $versionParser->parseConstraints('*')),
),
'no_php_required',
array(),
array(),
array('php', 'ext-fil*'),
),
'No extensions required' => array(
array(
new Link('a', 'php', $versionParser->parseConstraints('^7.2')),

View File

@ -30,6 +30,14 @@ final class IgnoreListPlatformRequirementFilterTest extends TestCase
'ext-json is ignored if listed' => array(array('ext-json', 'monolog/monolog'), 'ext-json', true),
'php is not ignored if not listed' => array(array('ext-json', 'monolog/monolog'), 'php', false),
'monolog/monolog is not ignored even if listed' => array(array('ext-json', 'monolog/monolog'), 'monolog/monolog', false),
'ext-json is ignored if ext-* is listed' => array(array('ext-*'), 'ext-json', true),
'php is ignored if php* is listed' => array(array('ext-*', 'php*'), 'php', true),
'ext-json is ignored if * is listed' => array(array('foo', '*'), 'ext-json', true),
'php is ignored if * is listed' => array(array('*', 'foo'), 'php', true),
'monolog/monolog is not ignored even if * or monolog/* are listed' => array(array('*', 'monolog/*'), 'monolog/monolog', false),
'empty list entry does not ignore' => array(array(''), 'ext-foo', false),
'empty array does not ignore' => array(array(), 'ext-foo', false),
'list entries are not completing each other' => array(array('ext-', 'foo'), 'ext-foo', false),
);
}
}

View File

@ -0,0 +1,22 @@
--TEST--
Install with ignore-platform-req list
--COMPOSER--
{
"repositories": [
{
"type": "package",
"package": [
{ "name": "a/a", "version": "1.0.0", "require": { "ext-foo-bar": "*", "php": "98" } }
]
}
],
"require": {
"a/a": "1.0.0",
"php": "99.9",
"ext-foo-baz": "*"
}
}
--RUN--
install --ignore-platform-req=php --ignore-platform-req=ext-foo-bar --ignore-platform-req=ext-foo-baz
--EXPECT--
Installing a/a (1.0.0)

View File

@ -0,0 +1,22 @@
--TEST--
Install with ignore-platform-req wildcard
--COMPOSER--
{
"repositories": [
{
"type": "package",
"package": [
{ "name": "a/a", "version": "1.0.0", "require": { "ext-foo-bar": "*", "php": "98" } }
]
}
],
"require": {
"a/a": "1.0.0",
"php": "99.9",
"ext-foo-baz": "*"
}
}
--RUN--
install --ignore-platform-req=php --ignore-platform-req=ext-foo-*
--EXPECT--
Installing a/a (1.0.0)

View File

@ -0,0 +1,26 @@
--TEST--
Update with ignore-platform-req list
--COMPOSER--
{
"repositories": [
{
"type": "package",
"package": [
{ "name": "a/a", "version": "1.0.1", "require": { "ext-foo-bar": "*" } }
]
}
],
"require": {
"a/a": "1.0.*",
"php": "99.9",
"ext-foo-baz": "9"
}
}
--INSTALLED--
[
{ "name": "a/a", "version": "1.0.0" }
]
--RUN--
update --ignore-platform-req=php --ignore-platform-req=ext-foo-bar --ignore-platform-req=ext-foo-baz
--EXPECT--
Upgrading a/a (1.0.0 => 1.0.1)

View File

@ -0,0 +1,26 @@
--TEST--
Update with ignore-platform-req wildcard
--COMPOSER--
{
"repositories": [
{
"type": "package",
"package": [
{ "name": "a/a", "version": "1.0.1", "require": { "ext-foo-bar": "*" } }
]
}
],
"require": {
"a/a": "1.0.*",
"php": "99.9",
"ext-foo-baz": "9"
}
}
--INSTALLED--
[
{ "name": "a/a", "version": "1.0.0" }
]
--RUN--
update --ignore-platform-req=php --ignore-platform-req=ext-foo-*
--EXPECT--
Upgrading a/a (1.0.0 => 1.0.1)

View File

@ -92,4 +92,33 @@ class BasePackageTest extends TestCase
return array_map($createPackage, $data);
}
/**
* @param string[] $packageNames
* @param string $wrap
* @param string $expectedRegexp
*
* @dataProvider dataPackageNamesToRegexp
*/
public function testPackageNamesToRegexp(array $packageNames, $wrap, $expectedRegexp)
{
$regexp = BasePackage::packageNamesToRegexp($packageNames, $wrap);
$this->assertSame($expectedRegexp, $regexp);
}
/**
* @return mixed[][]
*/
public function dataPackageNamesToRegexp()
{
return array(
array(
array('ext-*', 'monolog/monolog'), '{^%s$}i', '{^ext\-.*|monolog/monolog$}i',
array('php'), '{^%s$}i', '{^php$}i',
array('*'), '{^%s$}i', '{^.*$}i',
array('foo', 'bar'), '§%s§', '§foo|bar§',
)
);
}
}