function InstallationManager::downloadAndExecuteBatch
@phpstan-param array<callable(): ?PromiseInterface<void|null>> $cleanupPromises
Parameters
OperationInterface[] $operations List of operations to execute in this batch:
OperationInterface[] $allOperations Complete list of operations to be executed in the install job, used for event listeners:
1 call to InstallationManager::downloadAndExecuteBatch()
- InstallationManager::execute in vendor/
composer/ composer/ src/ Composer/ Installer/ InstallationManager.php - Executes solver operation.
File
-
vendor/
composer/ composer/ src/ Composer/ Installer/ InstallationManager.php, line 246
Class
- InstallationManager
- Package operation manager.
Namespace
Composer\InstallerCode
private function downloadAndExecuteBatch(InstalledRepositoryInterface $repo, array $operations, array &$cleanupPromises, bool $devMode, bool $runScripts, bool $downloadOnly, array $allOperations) : void {
$promises = [];
foreach ($operations as $index => $operation) {
$opType = $operation->getOperationType();
// ignoring alias ops as they don't need to execute anything at this stage
if (!in_array($opType, [
'update',
'install',
'uninstall',
], true)) {
continue;
}
if ($opType === 'update') {
/** @var UpdateOperation $operation */
$package = $operation->getTargetPackage();
$initialPackage = $operation->getInitialPackage();
}
else {
/** @var InstallOperation|MarkAliasInstalledOperation|MarkAliasUninstalledOperation|UninstallOperation $operation */
$package = $operation->getPackage();
$initialPackage = null;
}
$installer = $this->getInstaller($package->getType());
$cleanupPromises[$index] = static function () use ($opType, $installer, $package, $initialPackage) : ?PromiseInterface {
// avoid calling cleanup if the download was not even initialized for a package
// as without installation source configured nothing will work
if (null === $package->getInstallationSource()) {
return \React\Promise\resolve(null);
}
return $installer->cleanup($opType, $package, $initialPackage);
};
if ($opType !== 'uninstall') {
$promise = $installer->download($package, $initialPackage);
if (null !== $promise) {
$promises[] = $promise;
}
}
}
// execute all downloads first
if (count($promises) > 0) {
$this->waitOnPromises($promises);
}
if ($downloadOnly) {
$this->runCleanup($cleanupPromises);
return;
}
// execute operations in batches to make sure every plugin is installed in the
// right order and activated before the packages depending on it are installed
$batches = [];
$batch = [];
foreach ($operations as $index => $operation) {
if ($operation instanceof InstallOperation || $operation instanceof UpdateOperation) {
$package = $operation instanceof UpdateOperation ? $operation->getTargetPackage() : $operation->getPackage();
if ($package->getType() === 'composer-plugin' || $package->getType() === 'composer-installer') {
if (count($batch) > 0) {
$batches[] = $batch;
}
$batches[] = [
$index => $operation,
];
$batch = [];
continue;
}
}
$batch[$index] = $operation;
}
if (count($batch) > 0) {
$batches[] = $batch;
}
foreach ($batches as $batchToExecute) {
$this->executeBatch($repo, $batchToExecute, $cleanupPromises, $devMode, $runScripts, $allOperations);
}
}