diff --git a/src/Composer/Downloader/ArchiveDownloader.php b/src/Composer/Downloader/ArchiveDownloader.php index f3e444d59..8b72f3518 100644 --- a/src/Composer/Downloader/ArchiveDownloader.php +++ b/src/Composer/Downloader/ArchiveDownloader.php @@ -26,6 +26,26 @@ use Composer\DependencyResolver\Operation\InstallOperation; */ abstract class ArchiveDownloader extends FileDownloader { + /** + * @var array + * @protected + */ + public $cleanupExecuted = array(); + + public function prepare($type, PackageInterface $package, $path, PackageInterface $prevPackage = null) + { + unset($this->cleanupExecuted[$package->getName()]); + + return parent::prepare($type, $package, $path, $prevPackage); + } + + public function cleanup($type, PackageInterface $package, $path, PackageInterface $prevPackage = null) + { + $this->cleanupExecuted[$package->getName()] = true; + + return parent::cleanup($type, $package, $path, $prevPackage); + } + /** * {@inheritDoc} * @throws \RuntimeException diff --git a/src/Composer/Downloader/ZipDownloader.php b/src/Composer/Downloader/ZipDownloader.php index 2a93c9f9c..6055f8745 100644 --- a/src/Composer/Downloader/ZipDownloader.php +++ b/src/Composer/Downloader/ZipDownloader.php @@ -149,8 +149,12 @@ class ZipDownloader extends ArchiveDownloader try { $promise = $this->process->executeAsync($command); - return $promise->then(function ($process) use ($tryFallback, $command, $package, $file) { + return $promise->then(function ($process) use ($tryFallback, $command, $package, $file, $self) { if (!$process->isSuccessful()) { + if (isset($self->cleanupExecuted[$package->getName()])) { + throw new \RuntimeException('Failed to extract '.$package->getName().' as the installation was aborted by another package operation.'); + } + $output = $process->getErrorOutput(); $output = str_replace(', '.$file.'.zip or '.$file.'.ZIP', '', $output);