1
0
Fork 0

A package providing a name should not conflict with a package replacing it

Simplified whatProvides, mustMatchName is unused, removed unused
function from policy
pull/8567/head
Nils Adermann 2020-01-30 21:46:58 +01:00
parent 2b86df4003
commit 4e3d989978
5 changed files with 26 additions and 39 deletions

View File

@ -34,7 +34,6 @@ class Pool implements \Countable
protected $packages = array(); protected $packages = array();
protected $packageByName = array(); protected $packageByName = array();
protected $packageByExactName = array();
protected $versionParser; protected $versionParser;
protected $providerCache = array(); protected $providerCache = array();
protected $unacceptableFixedPackages; protected $unacceptableFixedPackages;
@ -54,7 +53,6 @@ class Pool implements \Countable
$this->packages[] = $package; $this->packages[] = $package;
$package->id = $id++; $package->id = $id++;
$this->packageByExactName[$package->getName()][$package->id] = $package;
foreach ($package->getNames() as $provided) { foreach ($package->getNames() as $provided) {
$this->packageByName[$provided][] = $package; $this->packageByName[$provided][] = $package;
@ -87,44 +85,41 @@ class Pool implements \Countable
* @param string $name The package name to be searched for * @param string $name The package name to be searched for
* @param ConstraintInterface $constraint A constraint that all returned * @param ConstraintInterface $constraint A constraint that all returned
* packages must match or null to return all * packages must match or null to return all
* @param bool $mustMatchName Whether the name of returned packages
* must match the given name
* @return PackageInterface[] A set of packages * @return PackageInterface[] A set of packages
*/ */
public function whatProvides($name, ConstraintInterface $constraint = null, $mustMatchName = false) public function whatProvides($name, ConstraintInterface $constraint = null, $allowProvide = true)
{ {
$key = ((int) $mustMatchName).$constraint; $key = ((int) $allowProvide).$constraint;
if (isset($this->providerCache[$name][$key])) { if (isset($this->providerCache[$name][$key])) {
return $this->providerCache[$name][$key]; return $this->providerCache[$name][$key];
} }
return $this->providerCache[$name][$key] = $this->computeWhatProvides($name, $constraint, $mustMatchName); return $this->providerCache[$name][$key] = $this->computeWhatProvides($name, $constraint, $allowProvide);
} }
/** /**
* @see whatProvides * @see whatProvides
*/ */
private function computeWhatProvides($name, $constraint, $mustMatchName = false) private function computeWhatProvides($name, $constraint, $allowProvide = true)
{ {
$candidates = array(); if (!isset($this->packageByName[$name])) {
return array();
if ($mustMatchName) {
if (isset($this->packageByExactName[$name])) {
$candidates = $this->packageByExactName[$name];
}
} elseif (isset($this->packageByName[$name])) {
$candidates = $this->packageByName[$name];
} }
$matches = array(); $matches = array();
foreach ($candidates as $candidate) { foreach ($this->packageByName[$name] 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:
case self::MATCH_PROVIDE: case self::MATCH_PROVIDE:
if ($allowProvide) {
$matches[] = $candidate;
}
break;
case self::MATCH:
case self::MATCH_REPLACE: case self::MATCH_REPLACE:
$matches[] = $candidate; $matches[] = $candidate;
break; break;

View File

@ -160,7 +160,7 @@ class RuleSetGenerator
$this->addedMap[$package->id] = true; $this->addedMap[$package->id] = true;
$this->addedPackages[] = $package; $this->addedPackages[] = $package;
foreach ($package->getNames() as $name) { foreach ($package->getNames(false) as $name) {
$this->addedPackagesByNames[$name][] = $package; $this->addedPackagesByNames[$name][] = $package;
} }
@ -179,7 +179,7 @@ class RuleSetGenerator
} }
$packageName = $package->getName(); $packageName = $package->getName();
$obsoleteProviders = $this->pool->whatProvides($packageName, null); $obsoleteProviders = $this->pool->whatProvides($packageName, null, false);
foreach ($obsoleteProviders as $provider) { foreach ($obsoleteProviders as $provider) {
if ($provider === $package) { if ($provider === $package) {

View File

@ -89,14 +89,16 @@ abstract class BasePackage implements PackageInterface
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public function getNames() public function getNames($provides = true)
{ {
$names = array( $names = array(
$this->getName() => true, $this->getName() => true,
); );
foreach ($this->getProvides() as $link) { if ($provides) {
$names[$link->getTarget()] = true; foreach ($this->getProvides() as $link) {
$names[$link->getTarget()] = true;
}
} }
foreach ($this->getReplaces() as $link) { foreach ($this->getReplaces() as $link) {

View File

@ -45,9 +45,11 @@ interface PackageInterface
* No version or release type information should be included in any of the * No version or release type information should be included in any of the
* names. Provided or replaced package names need to be returned as well. * names. Provided or replaced package names need to be returned as well.
* *
* @param bool $provides Whether provided names should be included
*
* @return array An array of strings referring to this package * @return array An array of strings referring to this package
*/ */
public function getNames(); public function getNames($provides = true);
/** /**
* Allows the solver to set an id for this package to refer to it. * Allows the solver to set an id for this package to refer to it.

View File

@ -1,5 +1,5 @@
--TEST-- --TEST--
Test that names provided by two dependents cause a conflict Providers of a replaced name should be installable
--COMPOSER-- --COMPOSER--
{ {
"repositories": [ "repositories": [
@ -28,18 +28,6 @@ Test that names provided by two dependents cause a conflict
--RUN-- --RUN--
update 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 provider/pkg * -> satisfiable by provider/pkg[1.0.0].
- Only one of these can be installed: replacer/pkg 1.0.0, provider/pkg 1.0.0.
- Root composer.json requires replacer/pkg * -> satisfiable by replacer/pkg[1.0.0].
--EXPECT-- --EXPECT--
Installing provider/pkg (1.0.0)
Installing replacer/pkg (1.0.0)