From 902cb290e792fdc3a4ff6a7af23ce7fea54b7acc Mon Sep 17 00:00:00 2001 From: Nils Adermann Date: Wed, 12 Sep 2018 16:32:14 +0200 Subject: [PATCH] Only load package versions which fit the root composer.json constraints --- .../DependencyResolver/PoolBuilder.php | 4 ++-- src/Composer/Repository/BaseRepository.php | 20 ++++++++++++++++--- .../Repository/ComposerRepository.php | 19 ++++++++++++++---- .../Fixtures/installer/solver-problems.test | 8 +++++--- 4 files changed, 39 insertions(+), 12 deletions(-) diff --git a/src/Composer/DependencyResolver/PoolBuilder.php b/src/Composer/DependencyResolver/PoolBuilder.php index e51fce4eb..2fd3c8230 100644 --- a/src/Composer/DependencyResolver/PoolBuilder.php +++ b/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; } } diff --git a/src/Composer/Repository/BaseRepository.php b/src/Composer/Repository/BaseRepository.php index 172fe16b8..d835d55fd 100644 --- a/src/Composer/Repository/BaseRepository.php +++ b/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; + } } } diff --git a/src/Composer/Repository/ComposerRepository.php b/src/Composer/Repository/ComposerRepository.php index c26ab8a62..09e2179d8 100644 --- a/src/Composer/Repository/ComposerRepository.php +++ b/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); diff --git a/tests/Composer/Test/Fixtures/installer/solver-problems.test b/tests/Composer/Test/Fixtures/installer/solver-problems.test index e0359a151..ce3c57ebb 100644 --- a/tests/Composer/Test/Fixtures/installer/solver-problems.test +++ b/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