From b945fc4d8389674eb0d5adabbe04ec7ebdfd31ea Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Thu, 25 Feb 2016 13:05:26 +0000 Subject: [PATCH] Add unzip support on windows and fail earlier if unzipping is impossible, fixes #4943 --- src/Composer/Downloader/ZipDownloader.php | 28 ++++++++++++++++++----- 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/src/Composer/Downloader/ZipDownloader.php b/src/Composer/Downloader/ZipDownloader.php index 5f483975c..ffc517f3e 100644 --- a/src/Composer/Downloader/ZipDownloader.php +++ b/src/Composer/Downloader/ZipDownloader.php @@ -15,10 +15,12 @@ namespace Composer\Downloader; use Composer\Config; use Composer\Cache; use Composer\EventDispatcher\EventDispatcher; +use Composer\Package\PackageInterface; use Composer\Util\Platform; use Composer\Util\ProcessExecutor; use Composer\Util\RemoteFilesystem; use Composer\IO\IOInterface; +use Symfony\Component\Process\ExecutableFinder; use ZipArchive; /** @@ -27,6 +29,7 @@ use ZipArchive; class ZipDownloader extends ArchiveDownloader { protected $process; + protected static $hasSystemZip; public function __construct(IOInterface $io, Config $config, EventDispatcher $eventDispatcher = null, Cache $cache = null, ProcessExecutor $process = null, RemoteFilesystem $rfs = null) { @@ -34,12 +37,29 @@ class ZipDownloader extends ArchiveDownloader parent::__construct($io, $config, $eventDispatcher, $cache, $rfs); } + /** + * {@inheritDoc} + */ + public function download(PackageInterface $package, $path) + { + if (null === self::$hasSystemZip) { + $finder = new ExecutableFinder; + self::$hasSystemZip = (bool) $finder->find('unzip'); + } + + if (!class_exists('ZipArchive') && !self::$hasSystemZip) { + throw new \RuntimeException('The zip extension and unzip command are both missing, skipping'); + } + + return parent::download($package, $path); + } + protected function extract($file, $path) { $processError = null; // try to use unzip on *nix - if (!Platform::isWindows()) { + if (self::$hasSystemZip) { $command = 'unzip '.ProcessExecutor::escape($file).' -d '.ProcessExecutor::escape($path) . ' && chmod -R u+w ' . ProcessExecutor::escape($path); try { if (0 === $this->process->execute($command, $ignoredOutput)) { @@ -63,11 +83,7 @@ class ZipDownloader extends ArchiveDownloader } $error = "Could not decompress the archive, enable the PHP zip extension or install unzip.\n" - . $iniMessage . "\n" . $processError; - - if (!Platform::isWindows()) { - $error = "Could not decompress the archive, enable the PHP zip extension.\n" . $iniMessage; - } + . $iniMessage . ($processError ? "\n" . $processError : ''); throw new \RuntimeException($error); }