Browse Source

Keep track of unacceptable fixed packages for later to use in error reporting and make sure the pool state is consistent

Jordi Boggiano 5 years ago
parent
commit
1d31190472

+ 12 - 5
src/Composer/DependencyResolver/Pool.php

@@ -38,24 +38,26 @@ class Pool implements \Countable
     protected $packageByExactName = array();
     protected $versionParser;
     protected $providerCache = array();
+    protected $unacceptableFixedPackages;
 
-    public function __construct()
+    public function __construct(array $packages = array(), array $unacceptableFixedPackages = array())
     {
         $this->versionParser = new VersionParser;
+        $this->setPackages($packages);
+        $this->unacceptableFixedPackages = $unacceptableFixedPackages;
     }
 
-    public function setPackages(array $packages)
+    private function setPackages(array $packages)
     {
         $id = 1;
 
-        foreach ($packages as $i => $package) {
+        foreach ($packages as $package) {
             $this->packages[] = $package;
 
             $package->id = $id++;
-            $names = $package->getNames();
             $this->packageByExactName[$package->getName()][$package->id] = $package;
 
-            foreach ($names as $provided) {
+            foreach ($package->getNames() as $provided) {
                 $this->packageByName[$provided][] = $package;
             }
         }
@@ -227,4 +229,9 @@ class Pool implements \Countable
 
         return self::MATCH_NONE;
     }
+
+    public function isUnacceptableFixedPackage(PackageInterface $package)
+    {
+        return in_array($package, $this->unacceptableFixedPackages, true);
+    }
 }

+ 9 - 6
src/Composer/DependencyResolver/PoolBuilder.php

@@ -35,10 +35,9 @@ class PoolBuilder
 
     private $aliasMap = array();
     private $nameConstraints = array();
-
     private $loadedNames = array();
-
     private $packages = array();
+    private $unacceptableFixedPackages = array();
 
     public function __construct(array $acceptableStabilities, array $stabilityFlags, array $rootAliases, array $rootReferences, array $rootRequires = array())
     {
@@ -65,6 +64,8 @@ class PoolBuilder
                 || StabilityFilter::isPackageAcceptable($this->acceptableStabilities, $this->stabilityFlags, $package->getNames(), $package->getStability())
             ) {
                 $loadNames += $this->loadPackage($request, $package);
+            } else {
+                $this->unacceptableFixedPackages[] = $package;
             }
         }
 
@@ -137,11 +138,13 @@ class PoolBuilder
             }
         }
 
-        $pool->setPackages($this->packages);
+        $pool = new Pool($this->packages, $this->unacceptableFixedPackages);
 
-        unset($this->aliasMap);
-        unset($this->loadedNames);
-        unset($this->nameConstraints);
+        $this->aliasMap = array();
+        $this->nameConstraints = array();
+        $this->loadedNames = array();
+        $this->packages = array();
+        $this->unacceptableFixedPackages = array();
 
         return $pool;
     }

+ 7 - 2
src/Composer/DependencyResolver/RuleSetGenerator.php

@@ -290,9 +290,14 @@ class RuleSetGenerator
         $unlockableMap = $request->getUnlockableMap();
 
         foreach ($request->getFixedPackages() as $package) {
-            // fixed package was not added to the pool which must mean it did not pass the stability requirements
             if ($package->id == -1) {
-                continue;
+                // fixed package was not added to the pool as it did not pass the stability requirements, this is fine
+                if ($this->pool->isUnacceptableFixedPackage($package)) {
+                    continue;
+                }
+
+                // otherwise, looks like a bug
+                throw new \LogicException("Fixed package ".$package->getName()." ".$package->getVersion().($package instanceof AliasPackage ? " (alias)" : "")." was not added to solver pool.");
             }
 
             $this->addRulesForPackage($package, $ignorePlatformReqs);

+ 5 - 8
tests/Composer/Test/DependencyResolver/PoolTest.php

@@ -21,10 +21,9 @@ class PoolTest extends TestCase
 {
     public function testPool()
     {
-        $pool = $this->createPool();
         $package = $this->getPackage('foo', '1');
 
-        $pool->setPackages(array($package));
+        $pool = $this->createPool(array($package));
 
         $this->assertEquals(array($package), $pool->whatProvides('foo'));
         $this->assertEquals(array($package), $pool->whatProvides('foo'));
@@ -32,12 +31,11 @@ class PoolTest extends TestCase
 
     public function testWhatProvidesPackageWithConstraint()
     {
-        $pool = $this->createPool();
 
         $firstPackage = $this->getPackage('foo', '1');
         $secondPackage = $this->getPackage('foo', '2');
 
-        $pool->setPackages(array(
+        $pool = $this->createPool(array(
             $firstPackage,
             $secondPackage,
         ));
@@ -48,10 +46,9 @@ class PoolTest extends TestCase
 
     public function testPackageById()
     {
-        $pool = $this->createPool();
         $package = $this->getPackage('foo', '1');
 
-        $pool->setPackages(array($package));
+        $pool = $this->createPool(array($package));
 
         $this->assertSame($package, $pool->packageById(1));
     }
@@ -63,8 +60,8 @@ class PoolTest extends TestCase
         $this->assertEquals(array(), $pool->whatProvides('foo'));
     }
 
-    protected function createPool()
+    protected function createPool(array $packages = array())
     {
-        return new Pool();
+        return new Pool($packages);
     }
 }

+ 1 - 2
tests/Composer/Test/DependencyResolver/RuleSetTest.php

@@ -139,8 +139,7 @@ class RuleSetTest extends TestCase
 
     public function testPrettyString()
     {
-        $pool = new Pool();
-        $pool->setPackages(array(
+        $pool = new Pool(array(
             $p = $this->getPackage('foo', '2.1'),
         ));
 

+ 1 - 2
tests/Composer/Test/DependencyResolver/RuleTest.php

@@ -93,8 +93,7 @@ class RuleTest extends TestCase
 
     public function testPrettyString()
     {
-        $pool = new Pool();
-        $pool->setPackages(array(
+        $pool = new Pool(array(
             $p1 = $this->getPackage('foo', '2.1'),
             $p2 = $this->getPackage('baz', '1.1'),
         ));