diff --git a/src/Composer/DependencyResolver/Pool.php b/src/Composer/DependencyResolver/Pool.php index 1e1100b15..7088b3d50 100644 --- a/src/Composer/DependencyResolver/Pool.php +++ b/src/Composer/DependencyResolver/Pool.php @@ -34,7 +34,6 @@ class Pool implements \Countable protected $packages = array(); protected $packageByName = array(); - protected $packageByExactName = array(); protected $versionParser; protected $providerCache = array(); protected $unacceptableFixedPackages; @@ -54,7 +53,6 @@ class Pool implements \Countable $this->packages[] = $package; $package->id = $id++; - $this->packageByExactName[$package->getName()][$package->id] = $package; foreach ($package->getNames() as $provided) { $this->packageByName[$provided][] = $package; @@ -87,44 +85,41 @@ class Pool implements \Countable * @param string $name The package name to be searched for * @param ConstraintInterface $constraint A constraint that all returned * 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 */ - 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])) { 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 */ - private function computeWhatProvides($name, $constraint, $mustMatchName = false) + private function computeWhatProvides($name, $constraint, $allowProvide = true) { - $candidates = array(); - - if ($mustMatchName) { - if (isset($this->packageByExactName[$name])) { - $candidates = $this->packageByExactName[$name]; - } - } elseif (isset($this->packageByName[$name])) { - $candidates = $this->packageByName[$name]; + if (!isset($this->packageByName[$name])) { + return array(); } $matches = array(); - foreach ($candidates as $candidate) { + foreach ($this->packageByName[$name] as $candidate) { switch ($this->match($candidate, $name, $constraint)) { case self::MATCH_NONE: break; - case self::MATCH: case self::MATCH_PROVIDE: + if ($allowProvide) { + $matches[] = $candidate; + } + break; + + case self::MATCH: case self::MATCH_REPLACE: $matches[] = $candidate; break; diff --git a/src/Composer/DependencyResolver/RuleSetGenerator.php b/src/Composer/DependencyResolver/RuleSetGenerator.php index 717a69d20..ca10702a2 100644 --- a/src/Composer/DependencyResolver/RuleSetGenerator.php +++ b/src/Composer/DependencyResolver/RuleSetGenerator.php @@ -160,7 +160,7 @@ class RuleSetGenerator $this->addedMap[$package->id] = true; $this->addedPackages[] = $package; - foreach ($package->getNames() as $name) { + foreach ($package->getNames(false) as $name) { $this->addedPackagesByNames[$name][] = $package; } @@ -179,7 +179,7 @@ class RuleSetGenerator } $packageName = $package->getName(); - $obsoleteProviders = $this->pool->whatProvides($packageName, null); + $obsoleteProviders = $this->pool->whatProvides($packageName, null, false); foreach ($obsoleteProviders as $provider) { if ($provider === $package) { diff --git a/src/Composer/Package/BasePackage.php b/src/Composer/Package/BasePackage.php index 9ecbcb332..74cf3516e 100644 --- a/src/Composer/Package/BasePackage.php +++ b/src/Composer/Package/BasePackage.php @@ -89,14 +89,16 @@ abstract class BasePackage implements PackageInterface /** * {@inheritDoc} */ - public function getNames() + public function getNames($provides = true) { $names = array( $this->getName() => true, ); - foreach ($this->getProvides() as $link) { - $names[$link->getTarget()] = true; + if ($provides) { + foreach ($this->getProvides() as $link) { + $names[$link->getTarget()] = true; + } } foreach ($this->getReplaces() as $link) { diff --git a/src/Composer/Package/PackageInterface.php b/src/Composer/Package/PackageInterface.php index 9db188358..8f8087134 100644 --- a/src/Composer/Package/PackageInterface.php +++ b/src/Composer/Package/PackageInterface.php @@ -45,9 +45,11 @@ interface PackageInterface * 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. * + * @param bool $provides Whether provided names should be included + * * @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. diff --git a/tests/Composer/Test/Fixtures/installer/provider-conflicts2.test b/tests/Composer/Test/Fixtures/installer/provider-conflicts2.test index 343dab537..912d6c86e 100644 --- a/tests/Composer/Test/Fixtures/installer/provider-conflicts2.test +++ b/tests/Composer/Test/Fixtures/installer/provider-conflicts2.test @@ -1,5 +1,5 @@ --TEST-- -Test that names provided by two dependents cause a conflict +Providers of a replaced name should be installable --COMPOSER-- { "repositories": [ @@ -28,18 +28,6 @@ Test that names provided by two dependents cause a conflict --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 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-- - +Installing provider/pkg (1.0.0) +Installing replacer/pkg (1.0.0)