A package providing a name should not conflict with a package replacing it
Simplified whatProvides, mustMatchName is unused, removed unused function from policypull/8567/head
parent
2b86df4003
commit
4e3d989978
|
@ -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;
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in New Issue