From 59bc957e760b21e0987dfb87ecb6d995f6596c62 Mon Sep 17 00:00:00 2001 From: Nils Adermann Date: Wed, 29 Jan 2020 17:57:45 +0100 Subject: [PATCH] Simplify loading of fixed and root require packages in pool builder additionally mark all packages replaced by fixed packages as loaded as there is no need to load those names at all, since the fixed package will provide them --- .../DependencyResolver/PoolBuilder.php | 38 ++++++++++--------- .../Fixtures/installer/solver-problems.test | 2 + 2 files changed, 23 insertions(+), 17 deletions(-) diff --git a/src/Composer/DependencyResolver/PoolBuilder.php b/src/Composer/DependencyResolver/PoolBuilder.php index 1abaa4113..dad0da6ba 100644 --- a/src/Composer/DependencyResolver/PoolBuilder.php +++ b/src/Composer/DependencyResolver/PoolBuilder.php @@ -53,14 +53,21 @@ class PoolBuilder public function buildPool(array $repositories, Request $request) { - $pool = new Pool(); - - // TODO do we really want the request here? kind of want a root requirements thingy instead $loadNames = array(); foreach ($request->getFixedPackages() as $package) { + // TODO do we need to add this to nameConstraints at all? $this->nameConstraints[$package->getName()] = null; $this->loadedNames[$package->getName()] = true; - unset($loadNames[$package->getName()]); + + // replace means conflict, so if a fixed package replaces a name, no need to load that one, packages would conflict anyways + foreach ($package->getReplaces() as $link) { + $this->nameConstraints[$package->getName()] = null; + $this->loadedNames[$link->getTarget()] = true; + } + + // TODO in how far can we do the above for conflicts? It's more tricky cause conflicts can be limited to + // specific versions while replace is a conflict with all versions of the name + if ( $package->getRepository() instanceof RootPackageRepository || $package->getRepository() instanceof PlatformRepository @@ -72,24 +79,14 @@ class PoolBuilder } } - // TODO make sure if a fixed package replaces X packages they are not loaded again in loadNames - // perhaps loadPackage needs to mark them as loadedNames when loading a fixed package? - foreach ($request->getRequires() as $packageName => $constraint) { - // fixed packages do not need to get filtered as they are pinned already + // fixed packages have already been added, so if a root require needs one of them, no need to do anything if (isset($this->loadedNames[$packageName])) { continue; } - $loadNames[$packageName] = null; - if ($constraint) { - if (!array_key_exists($packageName, $this->nameConstraints)) { - $this->nameConstraints[$packageName] = new MultiConstraint(array($constraint), false); - } elseif ($this->nameConstraints[$packageName]) { - // TODO addConstraint function? - $this->nameConstraints[$packageName] = new MultiConstraint(array_merge(array($constraint), $this->nameConstraints[$packageName]->getConstraints()), false); - } - } + $loadNames[$packageName] = $constraint; + $this->nameConstraints[$packageName] = $constraint ? new MultiConstraint(array($constraint), false) : null; } // all the merged constraints from install requests + fixed packages can be applied @@ -101,6 +98,13 @@ class PoolBuilder } } + // clean up loadNames for anything we manually marked loaded above + foreach ($loadNames as $name => $void) { + if (isset($this->loadedNames[$name])) { + unset($loadNames[$name]); + } + } + while (!empty($loadNames)) { foreach ($loadNames as $name => $void) { $this->loadedNames[$name] = true; diff --git a/tests/Composer/Test/Fixtures/installer/solver-problems.test b/tests/Composer/Test/Fixtures/installer/solver-problems.test index 005047127..11aede917 100644 --- a/tests/Composer/Test/Fixtures/installer/solver-problems.test +++ b/tests/Composer/Test/Fixtures/installer/solver-problems.test @@ -116,6 +116,8 @@ Your requirements could not be resolved to an installable set of packages. - Root composer.json requires unstable/package 2.*, found unstable/package[2.0.0-alpha] but it does not match your minimum-stability. Problem 3 - Root composer.json requires non-existent/pkg, it could not be found in any version, there may be a typo in the package name. + Problem 4 + - The requested package dependency/pkg could not be found in any version, there may be a typo in the package name. Problem 4 - Root composer.json requires stable-requiree-excluded/pkg 1.0.1, found stable-requiree-excluded/pkg[1.0.1] but the package is fixed to 1.0.0 (lock file version) by a partial update and that version does not match. Make sure you whitelist it for update. Problem 5