1
0
Fork 0

Fail early if an archive extraction is going to fail at install/update stage to avoid leaving the vendor dir in a half up to date state

pull/8948/head
Jordi Boggiano 2020-06-03 15:19:02 +02:00
parent 396ad87fd0
commit 02059d96e7
No known key found for this signature in database
GPG Key ID: 7BBD42C429EC80BC
2 changed files with 14 additions and 2 deletions

View File

@ -15,6 +15,7 @@ namespace Composer\Downloader;
use Composer\Package\PackageInterface; use Composer\Package\PackageInterface;
use Symfony\Component\Finder\Finder; use Symfony\Component\Finder\Finder;
use Composer\IO\IOInterface; use Composer\IO\IOInterface;
use Composer\Exception\IrrecoverableDownloadException;
/** /**
* Base downloader for archives * Base downloader for archives
@ -25,6 +26,16 @@ use Composer\IO\IOInterface;
*/ */
abstract class ArchiveDownloader extends FileDownloader abstract class ArchiveDownloader extends FileDownloader
{ {
public function download(PackageInterface $package, $path, PackageInterface $prevPackage = null, $output = true)
{
$res = parent::download($package, $path, $prevPackage, $output);
if (is_dir($path) && !$this->filesystem->isDirEmpty($path)) {
throw new IrrecoverableDownloadException('Expected empty path to extract '.$package.' into but directory exists: '.$path);
}
return $res;
}
/** /**
* {@inheritDoc} * {@inheritDoc}
* @throws \RuntimeException * @throws \RuntimeException
@ -40,7 +51,7 @@ abstract class ArchiveDownloader extends FileDownloader
$this->filesystem->ensureDirectoryExists($path); $this->filesystem->ensureDirectoryExists($path);
if (!$this->filesystem->isDirEmpty($path)) { if (!$this->filesystem->isDirEmpty($path)) {
throw new \RuntimeException('Expected empty path to extract '.$package.' into but directory exists: '.$path); throw new \UnexpectedValueException('Expected empty path to extract '.$package.' into but directory exists: '.$path);
} }
do { do {

View File

@ -15,6 +15,7 @@ namespace Composer\Downloader;
use Composer\Package\PackageInterface; use Composer\Package\PackageInterface;
use Composer\IO\IOInterface; use Composer\IO\IOInterface;
use Composer\Util\Filesystem; use Composer\Util\Filesystem;
use Composer\Exception\IrrecoverableDownloadException;
use React\Promise\PromiseInterface; use React\Promise\PromiseInterface;
/** /**
@ -195,7 +196,7 @@ class DownloadManager
} }
$handleError = function ($e) use ($sources, $source, $package, $io, $download) { $handleError = function ($e) use ($sources, $source, $package, $io, $download) {
if ($e instanceof \RuntimeException) { if ($e instanceof \RuntimeException && !$e instanceof IrrecoverableDownloadException) {
if (!$sources) { if (!$sources) {
throw $e; throw $e;
} }