Преглед изворни кода

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

Simplified whatProvides, mustMatchName is unused, removed unused
function from policy
Nils Adermann пре 5 година
родитељ
комит
4e3d989978

+ 13 - 18
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;

+ 2 - 2
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) {

+ 5 - 3
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) {

+ 3 - 1
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.

+ 3 - 15
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)