Browse Source

Merge pull request #7631 from naderman/filter-versions-on-load

Only load package versions which fit the root composer.json constraints
Nils Adermann 6 years ago
parent
commit
3d5a6e84d3

+ 2 - 2
src/Composer/DependencyResolver/PoolBuilder.php

@@ -51,7 +51,7 @@ class PoolBuilder
         foreach ($request->getJobs() as $job) {
             switch ($job['cmd']) {
                 case 'install':
-                    $loadNames[$job['packageName']] = true;
+                    $loadNames[$job['packageName']] = $job['constraint'];
                     break;
             }
         }
@@ -129,7 +129,7 @@ class PoolBuilder
         foreach ($package->getRequires() as $link) {
             $require = $link->getTarget();
             if (!isset($this->loadedNames[$require])) {
-                $loadNames[$require] = true;
+                $loadNames[$require] = null;
             }
         }
 

+ 17 - 3
src/Composer/Repository/BaseRepository.php

@@ -12,6 +12,7 @@
 
 namespace Composer\Repository;
 
+use Composer\Package\AliasPackage;
 use Composer\Package\RootPackageInterface;
 use Composer\Semver\Constraint\ConstraintInterface;
 use Composer\Semver\Constraint\Constraint;
@@ -25,14 +26,27 @@ use Composer\Package\Link;
 abstract class BaseRepository implements RepositoryInterface
 {
     // TODO should this stay here? some repos need a better implementation
-    public function loadPackages(array $packageNameMap, $isPackageAcceptableCallable)
+    public function loadPackages(array $packageMap, $isPackageAcceptableCallable)
     {
         $packages = $this->getPackages();
 
         $result = array();
         foreach ($packages as $package) {
-            if (isset($packageNameMap[$package->getName()]) && call_user_func($isPackageAcceptableCallable, $package->getNames(), $package->getStability())) {
-                $result[] = $package;
+            if (array_key_exists($package->getName(), $packageMap) &&
+                (!$packageMap[$package->getName()] || $packageMap[$package->getName()]->matches(new Constraint('==', $package->getVersion()))) &&
+                call_user_func($isPackageAcceptableCallable, $package->getNames(), $package->getStability())) {
+                $result[spl_object_hash($package)] = $package;
+                if ($package instanceof AliasPackage && !isset($result[spl_object_hash($package->getAliasOf())])) {
+                    $result[spl_object_hash($package->getAliasOf())] = $package->getAliasOf();
+                }
+            }
+        }
+
+        foreach ($packages as $package) {
+            if ($package instanceof AliasPackage) {
+                if (isset($result[spl_object_hash($package->getAliasOf())])) {
+                    $result[spl_object_hash($package)] = $package;
+                }
             }
         }
 

+ 15 - 4
src/Composer/Repository/ComposerRepository.php

@@ -202,11 +202,22 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
         }
 
         $packages = array();
-        foreach ($packageNameMap as $name => $void) {
+        foreach ($packageNameMap as $name => $constraint) {
             $matches = array();
-            foreach ($this->whatProvides($name, false, $isPackageAcceptableCallable) as $match) {
-                if ($match->getName() === $name) {
-                    $matches[] = $match;
+            $candidates = $this->whatProvides($name, false, $isPackageAcceptableCallable);
+            foreach ($candidates as $candidate) {
+                if ($candidate->getName() === $name && (!$constraint || $constraint->matches(new Constraint('==', $candidate->getVersion())))) {
+                    $matches[spl_object_hash($candidate)] = $candidate;
+                    if ($candidate instanceof AliasPackage && !isset($matches[spl_object_hash($candidate->getAliasOf())])) {
+                        $matches[spl_object_hash($candidate->getAliasOf())] = $candidate->getAliasOf();
+                    }
+                }
+            }
+            foreach ($candidates as $candidate) {
+                if ($candidate instanceof AliasPackage) {
+                    if (isset($result[spl_object_hash($candidate->getAliasOf())])) {
+                        $matches[spl_object_hash($candidate)] = $candidate;
+                    }
                 }
             }
             $packages = array_merge($packages, $matches);

+ 5 - 3
tests/Composer/Test/Fixtures/installer/solver-problems.test

@@ -42,14 +42,16 @@ Updating dependencies (including require-dev)
 Your requirements could not be resolved to an installable set of packages.
 
   Problem 1
-    - The requested package unstable/package 2.* exists as unstable/package[1.0.0] but these are rejected by your constraint.
+    - The requested package unstable/package could not be found in any version, there may be a typo in the package name.
   Problem 2
     - The requested package bogus could not be found in any version, there may be a typo in the package name.
   Problem 3
-    - The requested package stable-requiree-excluded (installed at 1.0.0, required as 1.0.1) is satisfiable by stable-requiree-excluded[1.0.0] but these conflict with your requirements or minimum-stability.
+    - The requested package stable-requiree-excluded 1.0.1 exists as stable-requiree-excluded[1.0.0] but these are rejected by your constraint.
   Problem 4
+    - The requested package stable-requiree-excluded (installed at 1.0.0, required as 1.0.1) is satisfiable by stable-requiree-excluded[1.0.0] but these conflict with your requirements or minimum-stability.
+  Problem 5
     - Installation request for requirer 1.* -> satisfiable by requirer[1.0.0].
-    - requirer 1.0.0 requires dependency 1.0.0 -> satisfiable by dependency[1.0.0] but these conflict with your requirements or minimum-stability.
+    - requirer 1.0.0 requires dependency 1.0.0 -> no matching package found.
 
 Potential causes:
  - A typo in the package name