function PoolBuilder::buildPool
Parameters
RepositoryInterface[] $repositories:
File
-
vendor/
composer/ composer/ src/ Composer/ DependencyResolver/ PoolBuilder.php, line 200
Class
- PoolBuilder
- @author Nils Adermann <naderman@naderman.de>
Namespace
Composer\DependencyResolverCode
public function buildPool(array $repositories, Request $request) : Pool {
$this->restrictedPackagesList = $request->getRestrictedPackages() !== null ? array_flip($request->getRestrictedPackages()) : null;
if (\count($request->getUpdateAllowList()) > 0) {
$this->updateAllowList = $request->getUpdateAllowList();
$this->warnAboutNonMatchingUpdateAllowList($request);
if (null === $request->getLockedRepository()) {
throw new \LogicException('No lock repo present and yet a partial update was requested.');
}
foreach ($request->getLockedRepository()
->getPackages() as $lockedPackage) {
if (!$this->isUpdateAllowed($lockedPackage)) {
// remember which packages we skipped loading remote content for in this partial update
$this->skippedLoad[$lockedPackage->getName()][] = $lockedPackage;
foreach ($lockedPackage->getReplaces() as $link) {
$this->skippedLoad[$link->getTarget()][] = $lockedPackage;
}
// Path repo packages are never loaded from lock, to force them to always remain in sync
// unless symlinking is disabled in which case we probably should rather treat them like
// regular packages. We mark them specially so they can be reloaded fully including update propagation
// if they do get unlocked, but by default they are unlocked without update propagation.
if ($lockedPackage->getDistType() === 'path') {
$transportOptions = $lockedPackage->getTransportOptions();
if (!isset($transportOptions['symlink']) || $transportOptions['symlink'] !== false) {
$this->pathRepoUnlocked[$lockedPackage->getName()] = true;
continue;
}
}
$request->lockPackage($lockedPackage);
}
}
}
foreach ($request->getFixedOrLockedPackages() as $package) {
// using MatchAllConstraint here because fixed packages do not need to retrigger
// loading any packages
$this->loadedPackages[$package->getName()] = new MatchAllConstraint();
// 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->loadedPackages[$link->getTarget()] = new MatchAllConstraint();
}
// 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 || StabilityFilter::isPackageAcceptable($this->acceptableStabilities, $this->stabilityFlags, $package->getNames(), $package->getStability())) {
$this->loadPackage($request, $repositories, $package, false);
}
else {
$this->unacceptableFixedOrLockedPackages[] = $package;
}
}
foreach ($request->getRequires() as $packageName => $constraint) {
// fixed and locked packages have already been added, so if a root require needs one of them, no need to do anything
if (isset($this->loadedPackages[$packageName])) {
continue;
}
$this->packagesToLoad[$packageName] = $constraint;
$this->maxExtendedReqs[$packageName] = true;
}
// clean up packagesToLoad for anything we manually marked loaded above
foreach ($this->packagesToLoad as $name => $constraint) {
if (isset($this->loadedPackages[$name])) {
unset($this->packagesToLoad[$name]);
}
}
while (\count($this->packagesToLoad) > 0) {
$this->loadPackagesMarkedForLoading($request, $repositories);
}
if (\count($this->temporaryConstraints) > 0) {
foreach ($this->packages as $i => $package) {
// we check all alias related packages at once, so no need to check individual aliases
if (!isset($this->temporaryConstraints[$package->getName()]) || $package instanceof AliasPackage) {
continue;
}
$constraint = $this->temporaryConstraints[$package->getName()];
$packageAndAliases = [
$i => $package,
];
if (isset($this->aliasMap[spl_object_hash($package)])) {
$packageAndAliases += $this->aliasMap[spl_object_hash($package)];
}
$found = false;
foreach ($packageAndAliases as $packageOrAlias) {
if (CompilingMatcher::match($constraint, Constraint::OP_EQ, $packageOrAlias->getVersion())) {
$found = true;
}
}
if (!$found) {
foreach ($packageAndAliases as $index => $packageOrAlias) {
unset($this->packages[$index]);
}
}
}
}
if ($this->eventDispatcher !== null) {
$prePoolCreateEvent = new PrePoolCreateEvent(PluginEvents::PRE_POOL_CREATE, $repositories, $request, $this->acceptableStabilities, $this->stabilityFlags, $this->rootAliases, $this->rootReferences, $this->packages, $this->unacceptableFixedOrLockedPackages);
$this->eventDispatcher
->dispatch($prePoolCreateEvent->getName(), $prePoolCreateEvent);
$this->packages = $prePoolCreateEvent->getPackages();
$this->unacceptableFixedOrLockedPackages = $prePoolCreateEvent->getUnacceptableFixedPackages();
}
$pool = new Pool($this->packages, $this->unacceptableFixedOrLockedPackages);
$this->aliasMap = [];
$this->packagesToLoad = [];
$this->loadedPackages = [];
$this->loadedPerRepo = [];
$this->packages = [];
$this->unacceptableFixedOrLockedPackages = [];
$this->maxExtendedReqs = [];
$this->skippedLoad = [];
$this->indexCounter = 0;
$this->io
->debug('Built pool.');
$pool = $this->runOptimizer($request, $pool);
Intervals::clear();
return $pool;
}