1
0
Fork 0

Merge pull request #5038 from nicolas-grekas/zip-native

Prefer ZipArchive over unzip, add 7z on Windows
pull/5049/head
Jordi Boggiano 2016-03-11 10:30:26 +00:00
commit 1dce6442ed
2 changed files with 20 additions and 28 deletions

View File

@ -346,13 +346,9 @@ composer update
See also https://github.com/composer/composer/issues/4180 for more information. See also https://github.com/composer/composer/issues/4180 for more information.
## Zip archives are being reported as corrupted or not unpacked correctly. ## Zip archives are not unpacked correctly.
Composer can unpack zipballs using either a system-provided `unzip` utility or PHP's Composer can unpack zipballs using either a system-provided `unzip` utility or PHP's
native `ZipArchiver` class, preferring the first. The `ZipArchiver` class however is native `ZipArchiver` class. The `ZipArchiver` class is preferred on Windows. On other
known to occassionally report valid zip files as corrupted, and does not support certain OSes where ZIP files can contain permissions and symlinks, the `unzip` utility is
advanced features with permissions and symlinks. preferred. You're advised to install it if you need these features.
If you have issues with zip files you should install a native implementation of unzip
and verify whether the problem persists. If so it is likely a real issue in the file
itself and you should contact the provider.

View File

@ -48,7 +48,18 @@ class ZipDownloader extends ArchiveDownloader
} }
if (!class_exists('ZipArchive') && !self::$hasSystemUnzip) { if (!class_exists('ZipArchive') && !self::$hasSystemUnzip) {
throw new \RuntimeException('The zip extension and unzip command are both missing, skipping'); // php.ini path is added to the error message to help users find the correct file
$iniPath = php_ini_loaded_file();
if ($iniPath) {
$iniMessage = 'The php.ini used by your command-line PHP is: ' . $iniPath;
} else {
$iniMessage = 'A php.ini file does not exist. You will have to create one.';
}
$error = "The zip extension and unzip command are both missing, skipping.\n" . $iniMessage;
throw new \RuntimeException($error);
} }
return parent::download($package, $path); return parent::download($package, $path);
@ -58,7 +69,7 @@ class ZipDownloader extends ArchiveDownloader
{ {
$processError = null; $processError = null;
if (self::$hasSystemUnzip) { if (self::$hasSystemUnzip && !(class_exists('ZipArchive') && Platform::isWindows())) {
$command = 'unzip '.ProcessExecutor::escape($file).' -d '.ProcessExecutor::escape($path); $command = 'unzip '.ProcessExecutor::escape($file).' -d '.ProcessExecutor::escape($path);
if (!Platform::isWindows()) { if (!Platform::isWindows()) {
$command .= ' && chmod -R u+w ' . ProcessExecutor::escape($path); $command .= ' && chmod -R u+w ' . ProcessExecutor::escape($path);
@ -73,22 +84,10 @@ class ZipDownloader extends ArchiveDownloader
} catch (\Exception $e) { } catch (\Exception $e) {
$processError = 'Failed to execute ' . $command . "\n\n" . $e->getMessage(); $processError = 'Failed to execute ' . $command . "\n\n" . $e->getMessage();
} }
}
if (!class_exists('ZipArchive')) { if (!class_exists('ZipArchive')) {
// php.ini path is added to the error message to help users find the correct file throw new \RuntimeException($processError);
$iniPath = php_ini_loaded_file();
if ($iniPath) {
$iniMessage = 'The php.ini used by your command-line PHP is: ' . $iniPath;
} else {
$iniMessage = 'A php.ini file does not exist. You will have to create one.';
} }
$error = "Could not decompress the archive, enable the PHP zip extension or install unzip.\n"
. $iniMessage . ($processError ? "\n" . $processError : '');
throw new \RuntimeException($error);
} }
$zipArchive = new ZipArchive(); $zipArchive = new ZipArchive();
@ -98,10 +97,7 @@ class ZipDownloader extends ArchiveDownloader
} }
if (true !== $zipArchive->extractTo($path)) { if (true !== $zipArchive->extractTo($path)) {
$this->io->writeError("<warn>As there is no 'unzip' command installed zip files are being unpacked using the PHP zip extension.</warn>"); throw new \RuntimeException(rtrim("There was an error extracting the ZIP file, it is either corrupted or using an invalid format.\n".$processError));
$this->io->writeError("<warn>This may cause invalid reports of corrupted archives. Installing 'unzip' may remediate them.</warn>");
throw new \RuntimeException("There was an error extracting the ZIP file, it is either corrupted or using an invalid format");
} }
$zipArchive->close(); $zipArchive->close();