From f2befc46c9f68524bf2321b20a44e5cfa42a82a0 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Fri, 5 Jun 2020 17:13:39 +0200 Subject: [PATCH] Avoid storing duplicate packages when loading the same package twice --- .../DependencyResolver/PoolBuilder.php | 20 ++++++++----------- ...t-expansion-works-with-exact-versions.test | 2 +- ...-not-loaded-if-not-required-expansion.test | 2 +- 3 files changed, 10 insertions(+), 14 deletions(-) diff --git a/src/Composer/DependencyResolver/PoolBuilder.php b/src/Composer/DependencyResolver/PoolBuilder.php index 8b602b1aa..9f8f4280e 100644 --- a/src/Composer/DependencyResolver/PoolBuilder.php +++ b/src/Composer/DependencyResolver/PoolBuilder.php @@ -209,17 +209,6 @@ class PoolBuilder $this->unacceptableFixedPackages = $prePoolCreateEvent->getUnacceptableFixedPackages(); } - // Filter duplicate packages - // TODO: can we optimize this so that we don't even end up having dupes here? - $presentPackages = array(); - foreach ($this->packages as $i => $package) { - if (isset($presentPackages[$package->getUniqueName()])) { - unset($this->packages[$i]); - } else { - $presentPackages[$package->getUniqueName()] = true; - } - } - $pool = new Pool($this->packages, $this->unacceptableFixedPackages); $this->aliasMap = array(); @@ -235,7 +224,7 @@ class PoolBuilder { // Maybe it was already marked before but not loaded yet. In that case // we have to extend the constraint (we don't check if they match because - // MultiConstraint::create() will optimize anyway + // MultiConstraint::create() will optimize anyway) if (isset($this->packagesToLoad[$name]) && !Intervals::isSubsetOf($constraint, $this->packagesToLoad[$name])) { $constraint = MultiConstraint::create(array($this->packagesToLoad[$name], $constraint), false); } @@ -256,6 +245,13 @@ class PoolBuilder // yet so we get the required package versions $this->packagesToLoad[$name] = MultiConstraint::create(array($this->loadedPackages[$name], $constraint), false); unset($this->loadedPackages[$name]); + + // remove all already-loaded packages matching those to be loaded to avoid duplicates + foreach ($this->packages as $index => $pkg) { + if ($pkg->getName() === $name) { + unset($this->packages[$index]); + } + } } private function loadPackagesMarkedForLoading(Request $request, $repositories) diff --git a/tests/Composer/Test/DependencyResolver/Fixtures/poolbuilder/constraint-expansion-works-with-exact-versions.test b/tests/Composer/Test/DependencyResolver/Fixtures/poolbuilder/constraint-expansion-works-with-exact-versions.test index 7a3046ae0..fdabd9c8f 100644 --- a/tests/Composer/Test/DependencyResolver/Fixtures/poolbuilder/constraint-expansion-works-with-exact-versions.test +++ b/tests/Composer/Test/DependencyResolver/Fixtures/poolbuilder/constraint-expansion-works-with-exact-versions.test @@ -23,7 +23,7 @@ Tests if version constraint is expanded. If not, dep/dep 3.0.0 would not be load --EXPECT-- [ "root/req-1.0.0.0", - "dep/dep-2.3.4.0", "dep/dep2-2.3.4.0", + "dep/dep-2.3.4.0", "dep/dep-2.3.5.0" ] diff --git a/tests/Composer/Test/DependencyResolver/Fixtures/poolbuilder/package-versions-are-not-loaded-if-not-required-expansion.test b/tests/Composer/Test/DependencyResolver/Fixtures/poolbuilder/package-versions-are-not-loaded-if-not-required-expansion.test index 198df20a4..53795c761 100644 --- a/tests/Composer/Test/DependencyResolver/Fixtures/poolbuilder/package-versions-are-not-loaded-if-not-required-expansion.test +++ b/tests/Composer/Test/DependencyResolver/Fixtures/poolbuilder/package-versions-are-not-loaded-if-not-required-expansion.test @@ -25,8 +25,8 @@ Tests if version constraint is expanded. If not, dep/dep 3.0.0 would not be load --EXPECT-- [ "root/req-1.0.0.0", + "dep/dep2-2.3.4.0", "dep/dep-2.3.4.0", "dep/dep-2.3.5.0", - "dep/dep2-2.3.4.0", "dep/dep-3.0.0.0" ]