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

Deduplicate solver problems which list problems for dev-master AND 9999999-dev

Jordi Boggiano пре 5 година
родитељ
комит
8945936dbd

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

@@ -96,7 +96,7 @@ class Problem
             $messages[] = $rule->getPrettyString($repositorySet, $request, $pool, $installedMap, $learnedPool);
         }
 
-        return "\n    - ".implode("\n    - ", $messages);
+        return "\n    - ".implode("\n    - ", array_unique($messages));
     }
 
     public function isCausedByLock()

+ 14 - 4
src/Composer/DependencyResolver/Rule.php

@@ -15,6 +15,7 @@ namespace Composer\DependencyResolver;
 use Composer\Package\CompletePackage;
 use Composer\Package\Link;
 use Composer\Package\PackageInterface;
+use Composer\Package\AliasPackage;
 use Composer\Repository\RepositorySet;
 
 /**
@@ -153,7 +154,7 @@ abstract class Rule
                 return 'Root composer.json requires '.$packageName.($constraint ? ' '.$constraint->getPrettyString() : '').' -> satisfiable by '.$this->formatPackagesUnique($pool, $packages).'.';
 
             case self::RULE_FIXED:
-                $package = $this->reasonData['package'];
+                $package = $this->deduplicateMasterAlias($this->reasonData['package']);
                 if ($this->reasonData['lockable']) {
                     return $package->getPrettyName().' is locked to version '.$package->getPrettyVersion().' and an update of this package was not requested.';
                 }
@@ -161,14 +162,14 @@ abstract class Rule
                 return $package->getPrettyName().' is present at version '.$package->getPrettyVersion() . ' and cannot be modified by Composer';
 
             case self::RULE_PACKAGE_CONFLICT:
-                $package1 = $pool->literalToPackage($literals[0]);
-                $package2 = $pool->literalToPackage($literals[1]);
+                $package1 = $this->deduplicateMasterAlias($pool->literalToPackage($literals[0]));
+                $package2 = $this->deduplicateMasterAlias($pool->literalToPackage($literals[1]));
 
                 return $package2->getPrettyString().' conflicts with '.$package1->getPrettyString().'.';
 
             case self::RULE_PACKAGE_REQUIRES:
                 $sourceLiteral = array_shift($literals);
-                $sourcePackage = $pool->literalToPackage($sourceLiteral);
+                $sourcePackage = $this->deduplicateMasterAlias($pool->literalToPackage($sourceLiteral));
 
                 $requires = array();
                 foreach ($literals as $literal) {
@@ -279,4 +280,13 @@ abstract class Rule
 
         return $names;
     }
+
+    private function deduplicateMasterAlias(PackageInterface $package)
+    {
+        if ($package instanceof AliasPackage && $package->getPrettyVersion() === '9999999-dev') {
+            $package = $package->getAliasOf();
+        }
+
+        return $package;
+    }
 }

+ 10 - 3
src/Composer/DependencyResolver/SolverProblemsException.php

@@ -34,11 +34,12 @@ class SolverProblemsException extends \RuntimeException
     public function getPrettyString(RepositorySet $repositorySet, Request $request, Pool $pool, $isDevExtraction = false)
     {
         $installedMap = $request->getPresentMap(true);
-        $text = "\n";
         $hasExtensionProblems = false;
         $isCausedByLock = false;
-        foreach ($this->problems as $i => $problem) {
-            $text .= "  Problem ".($i + 1).$problem->getPrettyString($repositorySet, $request, $pool, $installedMap, $this->learnedPool)."\n";
+
+        $problems = array();
+        foreach ($this->problems as $problem) {
+            $problems[] = $problem->getPrettyString($repositorySet, $request, $pool, $installedMap, $this->learnedPool)."\n";
 
             if (!$hasExtensionProblems && $this->hasExtensionProblems($problem->getReasons())) {
                 $hasExtensionProblems = true;
@@ -47,6 +48,12 @@ class SolverProblemsException extends \RuntimeException
             $isCausedByLock |= $problem->isCausedByLock();
         }
 
+        $i = 1;
+        $text = "\n";
+        foreach (array_unique($problems) as $problem) {
+            $text .= "  Problem ".($i++).$problem;
+        }
+
         if (!$isDevExtraction && (strpos($text, 'could not be found') || strpos($text, 'no matching package found'))) {
             $text .= "\nPotential causes:\n - A typo in the package name\n - The package is not available in a stable-enough version according to your minimum-stability setting\n   see <https://getcomposer.org/doc/04-schema.md#minimum-stability> for more details.\n - It's a private package and you forgot to add a custom repository to find it\n\nRead <https://getcomposer.org/doc/articles/troubleshooting.md> for further common problems.";
         }

+ 57 - 0
tests/Composer/Test/Fixtures/installer/alias-solver-problems.test

@@ -0,0 +1,57 @@
+--TEST--
+Test the error output of solver problems with dev-master aliases.
+--COMPOSER--
+{
+    "repositories": [
+        {
+            "type": "package",
+            "package": [
+                {"name": "a/a", "version": "dev-master", "require": {"d/d": "1.0.0"}},
+                {"name": "b/b", "version": "dev-master", "require": {"d/d": "2.0.0"}},
+                {"name": "d/d", "version": "1.0.0"},
+                {"name": "d/d", "version": "2.0.0"}
+            ]
+        }
+    ],
+    "require": {
+        "a/a": "*@dev",
+        "b/b": "*@dev"
+    }
+}
+
+--LOCK--
+{
+    "packages": [
+    ],
+    "packages-dev": [],
+    "aliases": [],
+    "minimum-stability": "dev",
+    "stability-flags": [],
+    "prefer-stable": false,
+    "prefer-lowest": false,
+    "platform": [],
+    "platform-dev": []
+}
+
+--RUN--
+update a/a b/b
+
+--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 b/b *@dev -> satisfiable by b/b[dev-master].
+    - a/a dev-master requires d/d 1.0.0 -> satisfiable by d/d[1.0.0].
+    - You can only install one version of a package, so only one of these can be installed: d/d[2.0.0, 1.0.0].
+    - Conclusion: install d/d 2.0.0, learned rules:
+        - Root composer.json requires b/b *@dev -> satisfiable by b/b[dev-master].
+        - b/b dev-master requires d/d 2.0.0 -> satisfiable by d/d[2.0.0].
+    - Root composer.json requires a/a *@dev -> satisfiable by a/a[dev-master].
+
+--EXPECT--
+

+ 54 - 0
tests/Composer/Test/Fixtures/installer/alias-solver-problems2.test

@@ -0,0 +1,54 @@
+--TEST--
+Test the error output of solver problems with dev-master aliases.
+--COMPOSER--
+{
+    "repositories": [
+        {
+            "type": "package",
+            "package": [
+                { "name": "locked/pkg", "version": "dev-master", "require": {"locked/dependency": "1.0.0"} }
+            ]
+        }
+    ],
+    "require": {
+        "locked/pkg": "*@dev"
+    }
+}
+
+--LOCK--
+{
+    "packages": [
+        { "name": "locked/pkg", "version": "dev-master", "require": {"locked/dependency": "1.0.0"} },
+        { "name": "locked/dependency", "version": "1.0.0" }
+    ],
+    "packages-dev": [],
+    "aliases": [],
+    "minimum-stability": "dev",
+    "stability-flags": [],
+    "prefer-stable": false,
+    "prefer-lowest": false,
+    "platform": [],
+    "platform-dev": []
+}
+
+--RUN--
+update locked/dependency
+
+--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
+    - locked/pkg is locked to version dev-master and an update of this package was not requested.
+    - locked/pkg dev-master requires locked/dependency 1.0.0 -> found locked/dependency[1.0.0] but it conflicts with another require.
+  Problem 2
+    - locked/pkg dev-master requires locked/dependency 1.0.0 -> found locked/dependency[1.0.0] but it conflicts with another require.
+    - Root composer.json requires locked/pkg *@dev -> satisfiable by locked/pkg[dev-master].
+
+Use the option --with-all-dependencies to allow updates and removals for packages currently locked to specific versions.
+--EXPECT--
+