Przeglądaj źródła

Fix replacers being picked if whatProvide was called before building the package whitelist, fixes #2991, fixes #2962

Jordi Boggiano 11 lat temu
rodzic
commit
e23665be59

+ 1 - 0
src/Composer/DependencyResolver/Pool.php

@@ -70,6 +70,7 @@ class Pool
     public function setWhitelist($whitelist)
     {
         $this->whitelist = $whitelist;
+        $this->providerCache = array();
     }
 
     /**

+ 1 - 1
src/Composer/DependencyResolver/RuleSetGenerator.php

@@ -332,7 +332,7 @@ class RuleSetGenerator
         $this->rules = new RuleSet;
         $this->installedMap = $installedMap;
 
-        $this->whitelistedNames = array();
+        $this->whitelistedMap = array();
         foreach ($this->installedMap as $package) {
             $this->whitelistFromPackage($package);
             $this->whitelistFromUpdatePackages($package);

+ 5 - 3
src/Composer/DependencyResolver/Solver.php

@@ -127,7 +127,10 @@ class Solver
         foreach ($this->installed->getPackages() as $package) {
             $this->installedMap[$package->getId()] = $package;
         }
+    }
 
+    protected function checkForRootRequireProblems()
+    {
         foreach ($this->jobs as $job) {
             switch ($job['cmd']) {
                 case 'update':
@@ -161,10 +164,9 @@ class Solver
         $this->jobs = $request->getJobs();
 
         $this->setupInstalledMap();
-
-        $this->decisions = new Decisions($this->pool);
-
         $this->rules = $this->ruleSetGenerator->getRulesFor($this->jobs, $this->installedMap);
+        $this->checkForRootRequireProblems();
+        $this->decisions = new Decisions($this->pool);
         $this->watchGraph = new RuleWatchGraph;
 
         foreach ($this->rules as $rule) {

+ 1 - 1
src/Composer/Installer.php

@@ -534,7 +534,7 @@ class Installer
                 if ($reason instanceof Rule) {
                     switch ($reason->getReason()) {
                         case Rule::RULE_JOB_INSTALL:
-                            $this->io->write('    REASON: Required by root: '.$reason->getRequiredPackage());
+                            $this->io->write('    REASON: Required by root: '.$reason->getPrettyString());
                             $this->io->write('');
                             break;
                         case Rule::RULE_PACKAGE_REQUIRES:

+ 17 - 0
tests/Composer/Test/Fixtures/installer/broken-deps-do-not-replace.test

@@ -20,6 +20,23 @@ Broken dependencies should not lead to a replacer being installed which is not m
 }
 --RUN--
 install
+--EXPECT-OUTPUT--
+<info>Loading composer repositories with package information</info>
+<info>Installing dependencies (including require-dev)</info>
+<error>Your requirements could not be resolved to an installable set of packages.</error>
+
+  Problem 1
+    - c/c 1.0.0 requires x/x 1.0 -> no matching package found.
+    - b/b 1.0.0 requires c/c 1.* -> satisfiable by c/c[1.0.0].
+    - Installation request for b/b 1.* -> satisfiable by b/b[1.0.0].
+
+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://groups.google.com/d/topic/composer-dev/_g3ASeIFlrc/discussion> for more details.
+
+Read <http://getcomposer.org/doc/articles/troubleshooting.md> for further common problems.
+
 --EXPECT-EXIT-CODE--
 2
 --EXPECT--

+ 5 - 2
tests/Composer/Test/Fixtures/installer/replace-priorities.test

@@ -1,5 +1,5 @@
 --TEST--
-Replace takes precedence only in higher priority repositories
+Replace takes precedence only in higher priority repositories and if explicitly required
 --COMPOSER--
 {
     "repositories": [
@@ -14,13 +14,15 @@ Replace takes precedence only in higher priority repositories
             "package": [
                 { "name": "package", "version": "1.0.0" },
                 { "name": "package2", "version": "1.0.0" },
+                { "name": "package3", "version": "1.0.0", "require": { "forked": "*" } },
                 { "name": "hijacker", "version": "1.1.0", "replace": { "package": "1.1.0" } }
             ]
         }
     ],
     "require": {
         "package": "1.*",
-        "package2": "1.*"
+        "package2": "1.*",
+        "package3": "1.*"
     }
 }
 --RUN--
@@ -28,3 +30,4 @@ install
 --EXPECT--
 Installing package (1.0.0)
 Installing forked (1.1.0)
+Installing package3 (1.0.0)

+ 0 - 21
tests/Composer/Test/Fixtures/installer/replace-vendor-priorities.test

@@ -1,21 +0,0 @@
---TEST--
-Replacer of the same vendor takes precedence if same prio repo
---COMPOSER--
-{
-    "repositories": [
-        {
-            "type": "package",
-            "package": [
-                { "name": "b/replacer", "version": "1.1.0", "replace": { "a/package": "1.1.0" } },
-                { "name": "a/replacer", "version": "1.1.0", "replace": { "a/package": "1.1.0" } }
-            ]
-        }
-    ],
-    "require": {
-        "a/package": "1.*"
-    }
-}
---RUN--
-install
---EXPECT--
-Installing a/replacer (1.1.0)

+ 2 - 2
tests/Composer/Test/Fixtures/installer/suggest-replaced.test

@@ -6,7 +6,7 @@ Suggestions are not displayed for packages if they are replaced
         {
             "type": "package",
             "package": [
-                { "name": "a/a", "version": "1.0.0", "suggest": { "b/b": "an obscure reason" } },
+                { "name": "a/a", "version": "1.0.0", "suggest": { "b/b": "an obscure reason" }, "require": { "c/c": "*" } },
                 { "name": "c/c", "version": "1.0.0", "replace": { "b/b": "1.0.0" } }
             ]
         }
@@ -25,5 +25,5 @@ install
 <info>Generating autoload files</info>
 
 --EXPECT--
-Installing a/a (1.0.0)
 Installing c/c (1.0.0)
+Installing a/a (1.0.0)