Filter impossible packages from the pool (#9620)
Adds a new pass to the PoolOptimizer Co-authored-by: Jordi Boggiano <j.boggiano@seld.be>pull/10347/head
parent
a3e91b5be6
commit
8c8d9efd87
|
@ -75,7 +75,11 @@ class PoolOptimizer
|
|||
{
|
||||
$this->prepare($request, $pool);
|
||||
|
||||
$optimizedPool = $this->optimizeByIdenticalDependencies($pool);
|
||||
$this->optimizeByIdenticalDependencies($request, $pool);
|
||||
|
||||
$this->optimizeImpossiblePackagesAway($request, $pool);
|
||||
|
||||
$optimizedPool = $this->applyRemovalsToPool($pool);
|
||||
|
||||
// No need to run this recursively at the moment
|
||||
// because the current optimizations cannot provide
|
||||
|
@ -183,16 +187,13 @@ class PoolOptimizer
|
|||
|
||||
$optimizedPool = new Pool($packages, $pool->getUnacceptableFixedOrLockedPackages(), $removedVersions, $this->removedVersionsByPackage);
|
||||
|
||||
// Reset package removals
|
||||
$this->packagesToRemove = array();
|
||||
|
||||
return $optimizedPool;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Pool
|
||||
* @return void
|
||||
*/
|
||||
private function optimizeByIdenticalDependencies(Pool $pool)
|
||||
private function optimizeByIdenticalDependencies(Request $request, Pool $pool)
|
||||
{
|
||||
$identicalDefinitionsPerPackage = array();
|
||||
$packageIdenticalDefinitionLookup = array();
|
||||
|
@ -273,8 +274,6 @@ class PoolOptimizer
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this->applyRemovalsToPool($pool);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -383,4 +382,56 @@ class PoolOptimizer
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Use the list of locked packages to constrain the loaded packages
|
||||
* This will reduce packages with significant numbers of historical versions to a smaller number
|
||||
* and reduce the resulting rule set that is generated
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function optimizeImpossiblePackagesAway(Request $request, Pool $pool)
|
||||
{
|
||||
if (count($request->getLockedPackages()) === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
$packageIndex = array();
|
||||
|
||||
foreach ($pool->getPackages() as $package) {
|
||||
$id = $package->id;
|
||||
|
||||
// Do not remove irremovable packages
|
||||
if (isset($this->irremovablePackages[$id])) {
|
||||
continue;
|
||||
}
|
||||
// Do not remove a package aliased by another package, nor aliases
|
||||
if (isset($this->aliasesPerPackage[$id]) || $package instanceof AliasPackage) {
|
||||
continue;
|
||||
}
|
||||
// Do not remove locked packages
|
||||
if ($request->isFixedPackage($package) || $request->isLockedPackage($package)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$packageIndex[$package->getName()][$package->id] = $package;
|
||||
}
|
||||
|
||||
foreach ($request->getLockedPackages() as $package) {
|
||||
foreach ($package->getRequires() as $link) {
|
||||
$require = $link->getTarget();
|
||||
if (!isset($packageIndex[$require])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$linkConstraint = $link->getConstraint();
|
||||
foreach ($packageIndex[$require] as $id => $requiredPkg) {
|
||||
if (false === CompilingMatcher::match($linkConstraint, Constraint::OP_EQ, $requiredPkg->getVersion())) {
|
||||
$this->markPackageForRemoval($id);
|
||||
unset($packageIndex[$require][$id]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
--TEST--
|
||||
Do not load packages into the pool that cannot meet the fixed/locked requirements, when a loose requirement is encountered during update
|
||||
|
||||
--REQUEST--
|
||||
{
|
||||
"require": {
|
||||
"some/pkg": "*",
|
||||
"root/req": "*"
|
||||
},
|
||||
"locked": [
|
||||
{"name": "some/pkg", "version": "1.0.3", "require": {"dep/dep": "*"}, "id": 1},
|
||||
{"name": "root/req", "version": "1.0.0", "require": {"dep/dep": "2.*"}, "id": 2},
|
||||
{"name": "dep/dep", "version": "2.0.0", "id": 3}
|
||||
],
|
||||
"allowList": [
|
||||
"some/pkg"
|
||||
],
|
||||
"allowTransitiveDeps": true
|
||||
}
|
||||
|
||||
--FIXED--
|
||||
[
|
||||
]
|
||||
|
||||
--PACKAGE-REPOS--
|
||||
[
|
||||
[
|
||||
{"name": "some/pkg", "version": "1.0.4", "require": {"dep/dep": "*"}},
|
||||
{"name": "root/req", "version": "1.0.0", "require": {"dep/dep": "2.*"}},
|
||||
{"name": "dep/dep", "version": "1.0.0", "provide": {"other/pkg": "*"}},
|
||||
{"name": "dep/dep", "version": "1.0.1", "provide": {"other/pkg": "*"}},
|
||||
{"name": "dep/dep", "version": "1.0.2", "provide": {"other/pkg": "*"}},
|
||||
{"name": "dep/dep", "version": "2.0.0"},
|
||||
{"name": "dep/dep", "version": "2.0.1"}
|
||||
]
|
||||
]
|
||||
|
||||
--EXPECT--
|
||||
[
|
||||
2,
|
||||
"some/pkg-1.0.4.0",
|
||||
"dep/dep-1.0.0.0",
|
||||
"dep/dep-1.0.1.0",
|
||||
"dep/dep-1.0.2.0",
|
||||
"dep/dep-2.0.0.0",
|
||||
"dep/dep-2.0.1.0"
|
||||
]
|
||||
|
||||
--EXPECT-OPTIMIZED--
|
||||
[
|
||||
2,
|
||||
"some/pkg-1.0.4.0",
|
||||
"dep/dep-2.0.1.0"
|
||||
]
|
|
@ -86,6 +86,5 @@ Partially updating one root requirement with transitive deps fully updates trans
|
|||
"symlinked/path-pkg-2.0.0.0",
|
||||
"root/update-1.0.4.0",
|
||||
"symlinked/transitive2-2.0.4.0",
|
||||
"mirrored/transitive2-1.0.7.0",
|
||||
"mirrored/transitive2-2.0.8.0"
|
||||
"mirrored/transitive2-1.0.7.0"
|
||||
]
|
||||
|
|
|
@ -55,6 +55,5 @@ locked packages still need to be taking into account for loading all necessary v
|
|||
"root/req2-1.0.0.0 (locked)",
|
||||
"dep/pkg2-1.0.0.0",
|
||||
"dep/pkg2-1.2.0.0",
|
||||
"dep/pkg1-1.0.1.0",
|
||||
"dep/pkg1-2.0.0.0"
|
||||
"dep/pkg1-1.0.1.0"
|
||||
]
|
||||
|
|
Loading…
Reference in New Issue