diff --git a/src/Composer/DependencyResolver/PoolOptimizer.php b/src/Composer/DependencyResolver/PoolOptimizer.php index 4aa6ffe324d8..841a2e9c63fe 100644 --- a/src/Composer/DependencyResolver/PoolOptimizer.php +++ b/src/Composer/DependencyResolver/PoolOptimizer.php @@ -420,14 +420,15 @@ private function optimizeImpossiblePackagesAway(Request $request, Pool $pool) foreach ($request->getLockedPackages() as $package) { // If this locked package is no longer required by root or anything in the pool, it may get uninstalled so do not apply its requirements // In a case where a requirement WERE to appear in the pool by a package that would not be used, it would've been unlocked and so not filtered still - $ignoreUnusedPackage = false; + $isUnusedPackage = true; foreach ($package->getNames(false) as $packageName) { - if (!isset($this->requireConstraintsPerPackage[$packageName])) { - $ignoreUnusedPackage = true; + if (isset($this->requireConstraintsPerPackage[$packageName])) { + $isUnusedPackage = false; + break; } } - if ($ignoreUnusedPackage) { + if ($isUnusedPackage) { continue; } diff --git a/tests/Composer/Test/DependencyResolver/Fixtures/poolbuilder/filter-impossible-packages-locked-replacer.test b/tests/Composer/Test/DependencyResolver/Fixtures/poolbuilder/filter-impossible-packages-locked-replacer.test new file mode 100644 index 000000000000..cfec2e2f01c9 --- /dev/null +++ b/tests/Composer/Test/DependencyResolver/Fixtures/poolbuilder/filter-impossible-packages-locked-replacer.test @@ -0,0 +1,60 @@ +--TEST-- +Do not load packages into the pool that cannot meet the fixed/locked requirements, when a loose requirement is encountered during update +(The locked replacer/pkg should restrict dependencies) + +--REQUEST-- +{ + "require": { + "first/pkg": "*", + "second/pkg": "*", + "replacer/dep": "*" + }, + "locked": [ + {"name": "first/pkg", "version": "1.0.0", "require": {"replaced/pkg": "1.0.0"}}, + {"name": "second/pkg", "version": "1.0.0"}, + {"name": "replacer/pkg", "version": "1.0.0", "replace": {"replaced/pkg": "1.0.0"}, "require": {"replacer/dep": "1.*"}}, + {"name": "replacer/dep", "version": "1.0.0"} + ], + "allowList": [ + "second/pkg", + "replacer/dep" + ], + "allowTransitiveDeps": true +} + +--FIXED-- +[ +] + +--PACKAGE-REPOS-- +[ + [ + {"name": "first/pkg", "version": "1.0.0", "require": {"replaced/pkg": "1.0.0"}}, + {"name": "first/pkg", "version": "1.1.0", "require": {"replaced/pkg": "2.0.0"}}, + {"name": "second/pkg", "version": "1.0.0"}, + {"name": "replacer/pkg", "version": "1.0.0", "replace": {"replaced/pkg": "1.0.0"}, "require": {"replacer/dep": "1.*"}}, + {"name": "replacer/pkg", "version": "1.1.0", "replace": {"replaced/pkg": "2.0.0"}, "require": {"replacer/dep": "1.*"}}, + {"name": "replacer/pkg", "version": "1.2.0", "replace": {"replaced/pkg": "3.0.0"}, "require": {"replacer/dep": "1.*"}}, + {"name": "replacer/dep", "version": "1.0.0"}, + {"name": "replacer/dep", "version": "1.0.1"}, + {"name": "replacer/dep", "version": "2.0.0"} + ] +] + +--EXPECT-- +[ + "first/pkg-1.0.0.0 (locked)", + "replacer/pkg-1.0.0.0 (locked)", + "second/pkg-1.0.0.0", + "replacer/dep-1.0.0.0", + "replacer/dep-1.0.1.0", + "replacer/dep-2.0.0.0" +] + +--EXPECT-OPTIMIZED-- +[ + "first/pkg-1.0.0.0 (locked)", + "replacer/pkg-1.0.0.0 (locked)", + "second/pkg-1.0.0.0", + "replacer/dep-1.0.1.0" +]