Make sure operations are executed in batches, including downloads, when a plugin is present which modifies downloads, fixes #9333
parent
e090274db0
commit
dc88236c07
|
@ -180,7 +180,6 @@ class InstallationManager
|
|||
*/
|
||||
public function execute(RepositoryInterface $repo, array $operations, $devMode = true, $runScripts = true)
|
||||
{
|
||||
$promises = array();
|
||||
$cleanupPromises = array();
|
||||
|
||||
$loop = $this->loop;
|
||||
|
@ -234,6 +233,67 @@ class InstallationManager
|
|||
}
|
||||
|
||||
try {
|
||||
// execute operations in batches to make sure download-modifying-plugins are installed
|
||||
// before the other packages get downloaded
|
||||
$batches = array();
|
||||
$batch = array();
|
||||
foreach ($operations as $index => $operation) {
|
||||
if (in_array($operation->getOperationType(), array('update', 'install'), true)) {
|
||||
$package = $operation->getOperationType() === 'update' ? $operation->getTargetPackage() : $operation->getPackage();
|
||||
if ($package->getType() === 'composer-plugin' && $extra = $package->getExtra() && isset($extra['plugin-modifies-downloads']) && $extra['plugin-modifies-downloads'] === true) {
|
||||
if ($batch) {
|
||||
$batches[] = $batch;
|
||||
}
|
||||
$batches[] = array($index => $operation);
|
||||
$batch = array();
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
$batch[$index] = $operation;
|
||||
}
|
||||
|
||||
if ($batch) {
|
||||
$batches[] = $batch;
|
||||
}
|
||||
|
||||
foreach ($batches as $batch) {
|
||||
$this->downloadAndExecuteBatch($repo, $batch, $cleanupPromises, $devMode, $runScripts, $operations);
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
$runCleanup();
|
||||
|
||||
if ($handleInterruptsUnix) {
|
||||
pcntl_signal(SIGINT, $prevHandler);
|
||||
}
|
||||
if ($handleInterruptsWindows) {
|
||||
sapi_windows_set_ctrl_handler($prevHandler, false);
|
||||
}
|
||||
|
||||
throw $e;
|
||||
}
|
||||
|
||||
if ($handleInterruptsUnix) {
|
||||
pcntl_signal(SIGINT, $prevHandler);
|
||||
}
|
||||
if ($handleInterruptsWindows) {
|
||||
sapi_windows_set_ctrl_handler($prevHandler, false);
|
||||
}
|
||||
|
||||
// do a last write so that we write the repository even if nothing changed
|
||||
// as that can trigger an update of some files like InstalledVersions.php if
|
||||
// running a new composer version
|
||||
$repo->write($devMode, $this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $operations List of operations to execute in this batch
|
||||
* @param array $allOperations Complete list of operations to be executed in the install job, used for event listeners
|
||||
*/
|
||||
private function downloadAndExecuteBatch(RepositoryInterface $repo, array $operations, array &$cleanupPromises, $devMode, $runScripts, array $allOperations)
|
||||
{
|
||||
$promises = array();
|
||||
|
||||
foreach ($operations as $index => $operation) {
|
||||
$opType = $operation->getOperationType();
|
||||
|
||||
|
@ -270,15 +330,8 @@ class InstallationManager
|
|||
}
|
||||
|
||||
// execute all downloads first
|
||||
if (!empty($promises)) {
|
||||
$progress = null;
|
||||
if ($this->outputProgress && $this->io instanceof ConsoleIO && !$this->io->isDebug() && count($promises) > 1) {
|
||||
$progress = $this->io->getProgressBar();
|
||||
}
|
||||
$this->loop->wait($promises, $progress);
|
||||
if ($progress) {
|
||||
$progress->clear();
|
||||
}
|
||||
if (count($promises)) {
|
||||
$this->waitOnPromises($promises);
|
||||
}
|
||||
|
||||
// execute operations in batches to make sure every plugin is installed in the
|
||||
|
@ -306,32 +359,8 @@ class InstallationManager
|
|||
}
|
||||
|
||||
foreach ($batches as $batch) {
|
||||
$this->executeBatch($repo, $batch, $cleanupPromises, $devMode, $runScripts, $operations);
|
||||
$this->executeBatch($repo, $batch, $cleanupPromises, $devMode, $runScripts, $allOperations);
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
$runCleanup();
|
||||
|
||||
if ($handleInterruptsUnix) {
|
||||
pcntl_signal(SIGINT, $prevHandler);
|
||||
}
|
||||
if ($handleInterruptsWindows) {
|
||||
sapi_windows_set_ctrl_handler($prevHandler, false);
|
||||
}
|
||||
|
||||
throw $e;
|
||||
}
|
||||
|
||||
if ($handleInterruptsUnix) {
|
||||
pcntl_signal(SIGINT, $prevHandler);
|
||||
}
|
||||
if ($handleInterruptsWindows) {
|
||||
sapi_windows_set_ctrl_handler($prevHandler, false);
|
||||
}
|
||||
|
||||
// do a last write so that we write the repository even if nothing changed
|
||||
// as that can trigger an update of some files like InstalledVersions.php if
|
||||
// running a new composer version
|
||||
$repo->write($devMode, $this);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -340,6 +369,8 @@ class InstallationManager
|
|||
*/
|
||||
private function executeBatch(RepositoryInterface $repo, array $operations, array $cleanupPromises, $devMode, $runScripts, array $allOperations)
|
||||
{
|
||||
$promises = array();
|
||||
|
||||
foreach ($operations as $index => $operation) {
|
||||
$opType = $operation->getOperationType();
|
||||
|
||||
|
@ -397,7 +428,13 @@ class InstallationManager
|
|||
}
|
||||
|
||||
// execute all prepare => installs/updates/removes => cleanup steps
|
||||
if (!empty($promises)) {
|
||||
if (count($promises)) {
|
||||
$this->waitOnPromises($promises);
|
||||
}
|
||||
}
|
||||
|
||||
private function waitOnPromises(array $promises)
|
||||
{
|
||||
$progress = null;
|
||||
if ($this->outputProgress && $this->io instanceof ConsoleIO && !$this->io->isDebug() && count($promises) > 1) {
|
||||
$progress = $this->io->getProgressBar();
|
||||
|
@ -407,7 +444,6 @@ class InstallationManager
|
|||
$progress->clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes install operation.
|
||||
|
|
Loading…
Reference in New Issue