Allow providers which are selected to be installed in place of existing packages which do not satisfy requirements, fixes #6753
parent
2901995fc8
commit
8a41f1a5ca
|
@ -27,7 +27,6 @@ use Composer\Package\PackageInterface;
|
||||||
*/
|
*/
|
||||||
class Pool implements \Countable
|
class Pool implements \Countable
|
||||||
{
|
{
|
||||||
const MATCH_NAME = -1;
|
|
||||||
const MATCH_NONE = 0;
|
const MATCH_NONE = 0;
|
||||||
const MATCH = 1;
|
const MATCH = 1;
|
||||||
const MATCH_PROVIDE = 2;
|
const MATCH_PROVIDE = 2;
|
||||||
|
@ -117,27 +116,15 @@ class Pool implements \Countable
|
||||||
$candidates = $this->packageByName[$name];
|
$candidates = $this->packageByName[$name];
|
||||||
}
|
}
|
||||||
|
|
||||||
$matches = $provideMatches = array();
|
$matches = array();
|
||||||
$nameMatch = false;
|
|
||||||
|
|
||||||
foreach ($candidates as $candidate) {
|
foreach ($candidates as $candidate) {
|
||||||
switch ($this->match($candidate, $name, $constraint)) {
|
switch ($this->match($candidate, $name, $constraint)) {
|
||||||
case self::MATCH_NONE:
|
case self::MATCH_NONE:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case self::MATCH_NAME:
|
|
||||||
$nameMatch = true;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case self::MATCH:
|
case self::MATCH:
|
||||||
$nameMatch = true;
|
|
||||||
$matches[] = $candidate;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case self::MATCH_PROVIDE:
|
case self::MATCH_PROVIDE:
|
||||||
$provideMatches[] = $candidate;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case self::MATCH_REPLACE:
|
case self::MATCH_REPLACE:
|
||||||
$matches[] = $candidate;
|
$matches[] = $candidate;
|
||||||
break;
|
break;
|
||||||
|
@ -147,12 +134,7 @@ class Pool implements \Countable
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// if a package with the required name exists, we ignore providers
|
return $matches;
|
||||||
if ($nameMatch) {
|
|
||||||
return $matches;
|
|
||||||
}
|
|
||||||
|
|
||||||
return array_merge($matches, $provideMatches);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function literalToPackage($literal)
|
public function literalToPackage($literal)
|
||||||
|
@ -196,7 +178,7 @@ class Pool implements \Countable
|
||||||
return self::MATCH;
|
return self::MATCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
return self::MATCH_NAME;
|
return self::MATCH_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
$provides = $candidate->getProvides();
|
$provides = $candidate->getProvides();
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
--TEST--
|
||||||
|
Test that providers can be installed if they are selected and the package they provide is not installable
|
||||||
|
--COMPOSER--
|
||||||
|
{
|
||||||
|
"repositories": [
|
||||||
|
{
|
||||||
|
"type": "package",
|
||||||
|
"package": [
|
||||||
|
{
|
||||||
|
"name": "foo/polyfill",
|
||||||
|
"provide": {
|
||||||
|
"foo/standard": "1.0.0"
|
||||||
|
},
|
||||||
|
"version": "1.0.0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "foo/standard",
|
||||||
|
"require": {
|
||||||
|
"foo/does-not-exist": "1.0.0"
|
||||||
|
},
|
||||||
|
"version": "1.0.0"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"require": {
|
||||||
|
"foo/standard": "1.0.0",
|
||||||
|
"foo/polyfill": "1.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
--RUN--
|
||||||
|
update
|
||||||
|
|
||||||
|
--EXPECT--
|
||||||
|
Installing foo/polyfill (1.0.0)
|
|
@ -0,0 +1,34 @@
|
||||||
|
--TEST--
|
||||||
|
Test that providers can be installed in conjunction with the package they provide if they are selected and the package they provide is also installable
|
||||||
|
--COMPOSER--
|
||||||
|
{
|
||||||
|
"repositories": [
|
||||||
|
{
|
||||||
|
"type": "package",
|
||||||
|
"package": [
|
||||||
|
{
|
||||||
|
"name": "foo/polyfill",
|
||||||
|
"provide": {
|
||||||
|
"foo/standard": "1.0.0"
|
||||||
|
},
|
||||||
|
"version": "1.0.0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "foo/standard",
|
||||||
|
"version": "1.0.0"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"require": {
|
||||||
|
"foo/standard": "1.0.0",
|
||||||
|
"foo/polyfill": "1.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
--RUN--
|
||||||
|
update
|
||||||
|
|
||||||
|
--EXPECT--
|
||||||
|
Installing foo/standard (1.0.0)
|
||||||
|
Installing foo/polyfill (1.0.0)
|
|
@ -0,0 +1,55 @@
|
||||||
|
--TEST--
|
||||||
|
Test that providers can not be installed if they are not selected
|
||||||
|
--COMPOSER--
|
||||||
|
{
|
||||||
|
"repositories": [
|
||||||
|
{
|
||||||
|
"type": "package",
|
||||||
|
"package": [
|
||||||
|
{
|
||||||
|
"name": "foo/polyfill",
|
||||||
|
"provide": {
|
||||||
|
"foo/standard": "1.0.0"
|
||||||
|
},
|
||||||
|
"version": "1.0.0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "foo/standard",
|
||||||
|
"require": {
|
||||||
|
"foo/does-not-exist": "1.0.0"
|
||||||
|
},
|
||||||
|
"version": "1.0.0"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"require": {
|
||||||
|
"foo/standard": "1.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
--RUN--
|
||||||
|
update
|
||||||
|
|
||||||
|
--EXPECT-EXIT-CODE--
|
||||||
|
2
|
||||||
|
|
||||||
|
--EXPECT-OUTPUT--
|
||||||
|
Loading composer repositories with package information
|
||||||
|
Updating dependencies
|
||||||
|
Your requirements could not be resolved to an installable set of packages.
|
||||||
|
|
||||||
|
Problem 1
|
||||||
|
- Root composer.json requires foo/standard 1.0.0 -> satisfiable by foo/standard[1.0.0].
|
||||||
|
- foo/standard 1.0.0 requires foo/does-not-exist 1.0.0 -> no matching package found.
|
||||||
|
|
||||||
|
Potential causes:
|
||||||
|
- A typo in the package name
|
||||||
|
- The package is not available in a stable-enough version according to your minimum-stability setting
|
||||||
|
see <https://getcomposer.org/doc/04-schema.md#minimum-stability> for more details.
|
||||||
|
- It's a private package and you forgot to add a custom repository to find it
|
||||||
|
|
||||||
|
Read <https://getcomposer.org/doc/articles/troubleshooting.md> for further common problems.
|
||||||
|
|
||||||
|
--EXPECT--
|
||||||
|
|
Loading…
Reference in New Issue