Browse Source

Allow providers which are selected to be installed in place of existing packages which do not satisfy requirements, fixes #6753

Jordi Boggiano 5 years ago
parent
commit
8a41f1a5ca

+ 3 - 21
src/Composer/DependencyResolver/Pool.php

@@ -27,7 +27,6 @@ use Composer\Package\PackageInterface;
  */
 class Pool implements \Countable
 {
-    const MATCH_NAME = -1;
     const MATCH_NONE = 0;
     const MATCH = 1;
     const MATCH_PROVIDE = 2;
@@ -117,27 +116,15 @@ class Pool implements \Countable
             $candidates = $this->packageByName[$name];
         }
 
-        $matches = $provideMatches = array();
-        $nameMatch = false;
+        $matches = array();
 
         foreach ($candidates as $candidate) {
             switch ($this->match($candidate, $name, $constraint)) {
                 case self::MATCH_NONE:
                     break;
 
-                case self::MATCH_NAME:
-                    $nameMatch = true;
-                    break;
-
                 case self::MATCH:
-                    $nameMatch = true;
-                    $matches[] = $candidate;
-                    break;
-
                 case self::MATCH_PROVIDE:
-                    $provideMatches[] = $candidate;
-                    break;
-
                 case self::MATCH_REPLACE:
                     $matches[] = $candidate;
                     break;
@@ -147,12 +134,7 @@ class Pool implements \Countable
             }
         }
 
-        // if a package with the required name exists, we ignore providers
-        if ($nameMatch) {
-            return $matches;
-        }
-
-        return array_merge($matches, $provideMatches);
+        return $matches;
     }
 
     public function literalToPackage($literal)
@@ -196,7 +178,7 @@ class Pool implements \Countable
                 return self::MATCH;
             }
 
-            return self::MATCH_NAME;
+            return self::MATCH_NONE;
         }
 
         $provides = $candidate->getProvides();

+ 36 - 0
tests/Composer/Test/Fixtures/installer/provider-packages-can-be-installed-if-selected.test

@@ -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)

+ 34 - 0
tests/Composer/Test/Fixtures/installer/provider-packages-can-be-installed-together-with-provided-if-both-installable.json

@@ -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)

+ 55 - 0
tests/Composer/Test/Fixtures/installer/provider-packages-can-not-be-installed-unless-selected.test

@@ -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--
+