function InstallationManager::executeBatch
@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::executeBatch()
- InstallationManager::downloadAndExecuteBatch in vendor/
composer/ composer/ src/ Composer/ Installer/ InstallationManager.php - @phpstan-param array<callable(): ?PromiseInterface<void|null>> $cleanupPromises
File
-
vendor/
composer/ composer/ src/ Composer/ Installer/ InstallationManager.php, line 331
Class
- InstallationManager
- Package operation manager.
Namespace
Composer\InstallerCode
private function executeBatch(InstalledRepositoryInterface $repo, array $operations, array $cleanupPromises, bool $devMode, bool $runScripts, array $allOperations) : void {
$promises = [];
$postExecCallbacks = [];
foreach ($operations as $index => $operation) {
$opType = $operation->getOperationType();
// ignoring alias ops as they don't need to execute anything
if (!in_array($opType, [
'update',
'install',
'uninstall',
], true)) {
// output alias ops in debug verbosity as they have no output otherwise
if ($this->io
->isDebug()) {
$this->io
->writeError(' - ' . $operation->show(false));
}
$this->{$opType}($repo, $operation);
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());
$eventName = [
'install' => PackageEvents::PRE_PACKAGE_INSTALL,
'update' => PackageEvents::PRE_PACKAGE_UPDATE,
'uninstall' => PackageEvents::PRE_PACKAGE_UNINSTALL,
][$opType];
if ($runScripts && $this->eventDispatcher !== null) {
$this->eventDispatcher
->dispatchPackageEvent($eventName, $devMode, $repo, $allOperations, $operation);
}
$dispatcher = $this->eventDispatcher;
$io = $this->io;
$promise = $installer->prepare($opType, $package, $initialPackage);
if (!$promise instanceof PromiseInterface) {
$promise = \React\Promise\resolve(null);
}
$promise = $promise->then(function () use ($opType, $repo, $operation) {
return $this->{$opType}($repo, $operation);
})
->then($cleanupPromises[$index])
->then(function () use ($devMode, $repo) : void {
$repo->write($devMode, $this);
}, static function ($e) use ($opType, $package, $io) : void {
$io->writeError(' <error>' . ucfirst($opType) . ' of ' . $package->getPrettyName() . ' failed</error>');
throw $e;
});
$eventName = [
'install' => PackageEvents::POST_PACKAGE_INSTALL,
'update' => PackageEvents::POST_PACKAGE_UPDATE,
'uninstall' => PackageEvents::POST_PACKAGE_UNINSTALL,
][$opType];
if ($runScripts && $dispatcher !== null) {
$postExecCallbacks[] = static function () use ($dispatcher, $eventName, $devMode, $repo, $allOperations, $operation) : void {
$dispatcher->dispatchPackageEvent($eventName, $devMode, $repo, $allOperations, $operation);
};
}
$promises[] = $promise;
}
// execute all prepare => installs/updates/removes => cleanup steps
if (count($promises) > 0) {
$this->waitOnPromises($promises);
}
Platform::workaroundFilesystemIssues();
foreach ($postExecCallbacks as $cb) {
$cb();
}
}