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);
|
$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
|
// No need to run this recursively at the moment
|
||||||
// because the current optimizations cannot provide
|
// because the current optimizations cannot provide
|
||||||
|
@ -183,16 +187,13 @@ class PoolOptimizer
|
||||||
|
|
||||||
$optimizedPool = new Pool($packages, $pool->getUnacceptableFixedOrLockedPackages(), $removedVersions, $this->removedVersionsByPackage);
|
$optimizedPool = new Pool($packages, $pool->getUnacceptableFixedOrLockedPackages(), $removedVersions, $this->removedVersionsByPackage);
|
||||||
|
|
||||||
// Reset package removals
|
|
||||||
$this->packagesToRemove = array();
|
|
||||||
|
|
||||||
return $optimizedPool;
|
return $optimizedPool;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Pool
|
* @return void
|
||||||
*/
|
*/
|
||||||
private function optimizeByIdenticalDependencies(Pool $pool)
|
private function optimizeByIdenticalDependencies(Request $request, Pool $pool)
|
||||||
{
|
{
|
||||||
$identicalDefinitionsPerPackage = array();
|
$identicalDefinitionsPerPackage = array();
|
||||||
$packageIdenticalDefinitionLookup = 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",
|
"symlinked/path-pkg-2.0.0.0",
|
||||||
"root/update-1.0.4.0",
|
"root/update-1.0.4.0",
|
||||||
"symlinked/transitive2-2.0.4.0",
|
"symlinked/transitive2-2.0.4.0",
|
||||||
"mirrored/transitive2-1.0.7.0",
|
"mirrored/transitive2-1.0.7.0"
|
||||||
"mirrored/transitive2-2.0.8.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)",
|
"root/req2-1.0.0.0 (locked)",
|
||||||
"dep/pkg2-1.0.0.0",
|
"dep/pkg2-1.0.0.0",
|
||||||
"dep/pkg2-1.2.0.0",
|
"dep/pkg2-1.2.0.0",
|
||||||
"dep/pkg1-1.0.1.0",
|
"dep/pkg1-1.0.1.0"
|
||||||
"dep/pkg1-2.0.0.0"
|
|
||||||
]
|
]
|
||||||
|
|
Loading…
Reference in New Issue