Browse Source

Try to load packages from lock file only and avoid loading other versions for pinned packages

Jordi Boggiano 5 years ago
parent
commit
e50f78043a

+ 11 - 30
src/Composer/DependencyResolver/PoolBuilder.php

@@ -16,8 +16,6 @@ use Composer\Package\AliasPackage;
 use Composer\Package\BasePackage;
 use Composer\Package\Package;
 use Composer\Package\PackageInterface;
-use Composer\Repository\ComposerRepository;
-use Composer\Repository\InstalledRepositoryInterface;
 use Composer\Repository\PlatformRepository;
 use Composer\Semver\Constraint\Constraint;
 use Composer\Semver\Constraint\MultiConstraint;
@@ -54,13 +52,17 @@ class PoolBuilder
         // TODO do we really want the request here? kind of want a root requirements thingy instead
         $loadNames = array();
         foreach ($request->getFixedPackages() as $package) {
-            // TODO can actually use very specific constraint
-            $loadNames[$package->getName()] = null;
+            $this->loadedNames[$package->getName()] = true;
+            unset($loadNames[$package->getName()]);
+            $loadNames += $this->loadPackage($request, $package);
         }
 
         foreach ($request->getJobs() as $job) {
             switch ($job['cmd']) {
                 case 'install':
+                    if (isset($this->loadedNames[$job['packageName']])) {
+                        continue 2;
+                    }
                     // TODO currently lock above is always NULL if we adjust that, this needs to merge constraints
                     // TODO does it really make sense that we can have install requests for the same package that is actively locked with non-matching constraints?
                     // also see the solver-problems.test test case
@@ -71,27 +73,16 @@ class PoolBuilder
             }
         }
 
-        // packages from the locked repository only get loaded if they are explicitly fixed
-        foreach ($repositories as $key => $repository) {
-            if ($repository === $request->getLockedRepository()) {
-                foreach ($repository->getPackages() as $lockedPackage) {
-                    foreach ($request->getFixedPackages() as $package) {
-                        if ($package === $lockedPackage) {
-                            $loadNames += $this->loadPackage($request, $package, $key);
-                        }
-                    }
-                }
-            }
-        }
-
         while (!empty($loadNames)) {
             foreach ($loadNames as $name => $void) {
                 $this->loadedNames[$name] = true;
             }
 
             $newLoadNames = array();
-            foreach ($repositories as $key => $repository) {
-                if ($repository instanceof PlatformRepository || $repository instanceof InstalledRepositoryInterface || $repository === $request->getLockedRepository()) {
+            foreach ($repositories as $repository) {
+                // these repos have their packages fixed if they need to be loaded so we
+                // never need to load anything else from them
+                if ($repository instanceof PlatformRepository || $repository === $request->getLockedRepository()) {
                     continue;
                 }
 
@@ -103,9 +94,8 @@ class PoolBuilder
                     unset($loadNames[$name]);
                 }
                 foreach ($result['packages'] as $package) {
-
                     if (call_user_func($this->isPackageAcceptableCallable, $package->getNames(), $package->getStability())) {
-                        $newLoadNames += $this->loadPackage($request, $package, $key);
+                        $newLoadNames += $this->loadPackage($request, $package);
                     }
                 }
             }
@@ -139,15 +129,6 @@ class PoolBuilder
             }
         }
 
-        foreach ($repositories as $key => $repository) {
-            if ($repository instanceof PlatformRepository ||
-                $repository instanceof InstalledRepositoryInterface) {
-                foreach ($repository->getPackages() as $package) {
-                    $this->loadPackage($request, $package, $key);
-                }
-            }
-        }
-
         $pool->setPackages($this->packages);
 
         unset($this->aliasMap);

+ 2 - 1
src/Composer/Installer.php

@@ -50,6 +50,7 @@ use Composer\Package\PackageInterface;
 use Composer\Package\RootPackageInterface;
 use Composer\Repository\CompositeRepository;
 use Composer\Repository\InstalledArrayRepository;
+use Composer\Repository\RootPackageRepository;
 use Composer\Repository\PlatformRepository;
 use Composer\Repository\RepositoryInterface;
 use Composer\Repository\RepositoryManager;
@@ -735,7 +736,7 @@ class Installer
         $this->fixedRootPackage->setDevRequires(array());
 
         $repositorySet = new RepositorySet($rootAliases, $this->package->getReferences(), $minimumStability, $stabilityFlags, $rootRequires);
-        $repositorySet->addRepository(new InstalledArrayRepository(array($this->fixedRootPackage)));
+        $repositorySet->addRepository(new RootPackageRepository(array($this->fixedRootPackage)));
         $repositorySet->addRepository($platformRepo);
         if ($this->additionalFixedRepository) {
             $repositorySet->addRepository($this->additionalFixedRepository);

+ 1 - 1
src/Composer/Repository/InstalledArrayRepository.php

@@ -15,7 +15,7 @@ namespace Composer\Repository;
 /**
  * Installed array repository.
  *
- * This is used for serving the RootPackage inside an in-memory InstalledRepository
+ * This is used as an in-memory InstalledRepository mostly for testing purposes
  *
  * @author Jordi Boggiano <j.boggiano@seld.be>
  */

+ 7 - 0
src/Composer/Repository/RepositorySet.php

@@ -20,6 +20,7 @@ use Composer\Package\Version\VersionParser;
 use Composer\Repository\CompositeRepository;
 use Composer\Repository\PlatformRepository;
 use Composer\Repository\LockArrayRepository;
+use Composer\Repository\InstalledRepositoryInterface;
 use Composer\Semver\Constraint\ConstraintInterface;
 use Composer\Test\DependencyResolver\PoolTest;
 
@@ -147,6 +148,12 @@ class RepositorySet
     {
         $poolBuilder = new PoolBuilder(array($this, 'isPackageAcceptable'), $this->rootRequires);
 
+        foreach ($this->repositories as $repo) {
+            if ($repo instanceof InstalledRepositoryInterface) {
+                throw new \LogicException('The pool can not accept packages from an installed repository');
+            }
+        }
+
         return $this->pool = $poolBuilder->buildPool($this->repositories, $this->rootAliases, $this->rootReferences, $request);
     }
 

+ 24 - 0
src/Composer/Repository/RootPackageRepository.php

@@ -0,0 +1,24 @@
+<?php
+
+/*
+ * This file is part of Composer.
+ *
+ * (c) Nils Adermann <naderman@naderman.de>
+ *     Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Composer\Repository;
+
+/**
+ * Root package repository.
+ *
+ * This is used for serving the RootPackage inside an in-memory InstalledRepository
+ *
+ * @author Jordi Boggiano <j.boggiano@seld.be>
+ */
+class RootPackageRepository extends ArrayRepository
+{
+}