commit
6d1d307f7b
|
@ -24,6 +24,7 @@ use Composer\Util\IniHelper;
|
||||||
use Composer\Util\ProcessExecutor;
|
use Composer\Util\ProcessExecutor;
|
||||||
use Composer\Util\HttpDownloader;
|
use Composer\Util\HttpDownloader;
|
||||||
use Composer\Util\StreamContextFactory;
|
use Composer\Util\StreamContextFactory;
|
||||||
|
use Composer\Util\Platform;
|
||||||
use Composer\SelfUpdate\Keys;
|
use Composer\SelfUpdate\Keys;
|
||||||
use Composer\SelfUpdate\Versions;
|
use Composer\SelfUpdate\Versions;
|
||||||
use Composer\IO\NullIO;
|
use Composer\IO\NullIO;
|
||||||
|
@ -176,9 +177,17 @@ EOT
|
||||||
|
|
||||||
$finder = new ExecutableFinder;
|
$finder = new ExecutableFinder;
|
||||||
$hasSystemUnzip = (bool) $finder->find('unzip');
|
$hasSystemUnzip = (bool) $finder->find('unzip');
|
||||||
|
if (Platform::isWindows()) {
|
||||||
|
$hasSystem7zip = (bool) $finder->find('7z', null, array('C:\Program Files\7-Zip'));
|
||||||
|
$windows7z = ', ' . ($hasSystem7zip ? '<comment>7-Zip present</comment>' : '<comment>7-Zip not available</comment>');
|
||||||
|
} else {
|
||||||
|
$windows7z = '';
|
||||||
|
}
|
||||||
|
|
||||||
$io->write(
|
$io->write(
|
||||||
'zip: ' . (extension_loaded('zip') ? '<comment>extension present</comment>' : '<comment>extension not loaded</comment>')
|
'zip: ' . (extension_loaded('zip') ? '<comment>extension present</comment>' : '<comment>extension not loaded</comment>')
|
||||||
. ', ' . ($hasSystemUnzip ? '<comment>unzip present</comment>' : '<comment>unzip not available</comment>')
|
. ', ' . ($hasSystemUnzip ? '<comment>unzip present</comment>' : '<comment>unzip not available</comment>')
|
||||||
|
. $windows7z
|
||||||
);
|
);
|
||||||
|
|
||||||
return $this->exitCode;
|
return $this->exitCode;
|
||||||
|
|
|
@ -137,7 +137,7 @@ abstract class ArchiveDownloader extends FileDownloader
|
||||||
};
|
};
|
||||||
|
|
||||||
$renameAsOne = false;
|
$renameAsOne = false;
|
||||||
if (!file_exists($path) || ($filesystem->isDirEmpty($path) && $filesystem->removeDirectory($path))) {
|
if (!file_exists($path) || ($filesystem->isDirEmpty($path) && $filesystem->removeDirectoryPhp($path))) {
|
||||||
$renameAsOne = true;
|
$renameAsOne = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -306,7 +306,7 @@ class FileDownloader implements DownloaderInterface, ChangeReportInterface
|
||||||
|
|
||||||
foreach ($dirsToCleanUp as $dir) {
|
foreach ($dirsToCleanUp as $dir) {
|
||||||
if (is_dir($dir) && $this->filesystem->isDirEmpty($dir) && realpath($dir) !== getcwd()) {
|
if (is_dir($dir) && $this->filesystem->isDirEmpty($dir) && realpath($dir) !== getcwd()) {
|
||||||
$this->filesystem->removeDirectory($dir);
|
$this->filesystem->removeDirectoryPhp($dir);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@ use ZipArchive;
|
||||||
*/
|
*/
|
||||||
class ZipDownloader extends ArchiveDownloader
|
class ZipDownloader extends ArchiveDownloader
|
||||||
{
|
{
|
||||||
protected static $hasSystemUnzip;
|
private static $unzipCommands;
|
||||||
private static $hasZipArchive;
|
private static $hasZipArchive;
|
||||||
private static $isWindows;
|
private static $isWindows;
|
||||||
|
|
||||||
|
@ -37,19 +37,25 @@ class ZipDownloader extends ArchiveDownloader
|
||||||
*/
|
*/
|
||||||
public function download(PackageInterface $package, $path, PackageInterface $prevPackage = null, $output = true)
|
public function download(PackageInterface $package, $path, PackageInterface $prevPackage = null, $output = true)
|
||||||
{
|
{
|
||||||
if (null === self::$hasSystemUnzip) {
|
if (null === self::$unzipCommands) {
|
||||||
|
self::$unzipCommands = array();
|
||||||
$finder = new ExecutableFinder;
|
$finder = new ExecutableFinder;
|
||||||
self::$hasSystemUnzip = (bool) $finder->find('unzip');
|
if (Platform::isWindows() && ($cmd = $finder->find('7z', null, array('C:\Program Files\7-Zip')))) {
|
||||||
|
self::$unzipCommands[] = array('7z', ProcessExecutor::escape($cmd).' x -bb0 -y %s -o%s');
|
||||||
|
}
|
||||||
|
if ($cmd = $finder->find('unzip')) {
|
||||||
|
self::$unzipCommands[] = array('unzip', ProcessExecutor::escape($cmd).' -qq %s -d %s');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (null === self::$hasZipArchive) {
|
if (null === self::$hasZipArchive) {
|
||||||
self::$hasZipArchive = class_exists('ZipArchive');
|
self::$hasZipArchive = class_exists('ZipArchive');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!self::$hasZipArchive && !self::$hasSystemUnzip) {
|
if (!self::$hasZipArchive && !self::$unzipCommands) {
|
||||||
// php.ini path is added to the error message to help users find the correct file
|
// php.ini path is added to the error message to help users find the correct file
|
||||||
$iniMessage = IniHelper::getMessage();
|
$iniMessage = IniHelper::getMessage();
|
||||||
$error = "The zip extension and unzip command are both missing, skipping.\n" . $iniMessage;
|
$error = "The zip extension and unzip/7z commands are both missing, skipping.\n" . $iniMessage;
|
||||||
|
|
||||||
throw new \RuntimeException($error);
|
throw new \RuntimeException($error);
|
||||||
}
|
}
|
||||||
|
@ -57,10 +63,10 @@ class ZipDownloader extends ArchiveDownloader
|
||||||
if (null === self::$isWindows) {
|
if (null === self::$isWindows) {
|
||||||
self::$isWindows = Platform::isWindows();
|
self::$isWindows = Platform::isWindows();
|
||||||
|
|
||||||
if (!self::$isWindows && !self::$hasSystemUnzip) {
|
if (!self::$isWindows && !self::$unzipCommands) {
|
||||||
$this->io->writeError("<warning>As there is no 'unzip' command installed zip files are being unpacked using the PHP zip extension.</warning>");
|
$this->io->writeError("<warning>As there is no 'unzip' nor '7z' command installed zip files are being unpacked using the PHP zip extension.</warning>");
|
||||||
$this->io->writeError("<warning>This may cause invalid reports of corrupted archives. Besides, any UNIX permissions (e.g. executable) defined in the archives will be lost.</warning>");
|
$this->io->writeError("<warning>This may cause invalid reports of corrupted archives. Besides, any UNIX permissions (e.g. executable) defined in the archives will be lost.</warning>");
|
||||||
$this->io->writeError("<warning>Installing 'unzip' may remediate them.</warning>");
|
$this->io->writeError("<warning>Installing 'unzip' or '7z' may remediate them.</warning>");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,85 +78,59 @@ class ZipDownloader extends ArchiveDownloader
|
||||||
*
|
*
|
||||||
* @param string $file File to extract
|
* @param string $file File to extract
|
||||||
* @param string $path Path where to extract file
|
* @param string $path Path where to extract file
|
||||||
* @param bool $isLastChance If true it is called as a fallback and should throw an exception
|
|
||||||
* @return PromiseInterface
|
* @return PromiseInterface
|
||||||
*/
|
*/
|
||||||
private function extractWithSystemUnzip(PackageInterface $package, $file, $path, $isLastChance, $async = false)
|
private function extractWithSystemUnzip(PackageInterface $package, $file, $path)
|
||||||
{
|
{
|
||||||
if (!self::$hasZipArchive) {
|
// Force Exception throwing if the other alternative extraction method is not available
|
||||||
// Force Exception throwing if the Other alternative is not available
|
$isLastChance = !self::$hasZipArchive;
|
||||||
$isLastChance = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!self::$hasSystemUnzip && !$isLastChance) {
|
if (!self::$unzipCommands) {
|
||||||
// This was call as the favorite extract way, but is not available
|
// This was call as the favorite extract way, but is not available
|
||||||
// We switch to the alternative
|
// We switch to the alternative
|
||||||
return $this->extractWithZipArchive($package, $file, $path, true);
|
return $this->extractWithZipArchive($package, $file, $path);
|
||||||
}
|
}
|
||||||
|
|
||||||
// When called after a ZipArchive failed, perhaps there is some files to overwrite
|
$commandSpec = reset(self::$unzipCommands);
|
||||||
$overwrite = $isLastChance ? '-o' : '';
|
$command = sprintf($commandSpec[1], ProcessExecutor::escape($file), ProcessExecutor::escape($path));
|
||||||
$command = 'unzip -qq '.$overwrite.' '.ProcessExecutor::escape($file).' -d '.ProcessExecutor::escape($path);
|
$executable = $commandSpec[0];
|
||||||
|
|
||||||
if ($async) {
|
$self = $this;
|
||||||
$self = $this;
|
$io = $this->io;
|
||||||
$io = $this->io;
|
$tryFallback = function ($processError) use ($isLastChance, $io, $self, $file, $path, $package, $executable) {
|
||||||
$tryFallback = function ($processError) use ($isLastChance, $io, $self, $file, $path, $package) {
|
if ($isLastChance) {
|
||||||
if ($isLastChance) {
|
throw $processError;
|
||||||
throw $processError;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!is_file($file)) {
|
|
||||||
$io->writeError(' <warning>'.$processError->getMessage().'</warning>');
|
|
||||||
$io->writeError(' <warning>This most likely is due to a custom installer plugin not handling the returned Promise from the downloader</warning>');
|
|
||||||
$io->writeError(' <warning>See https://github.com/composer/installers/commit/5006d0c28730ade233a8f42ec31ac68fb1c5c9bb for an example fix</warning>');
|
|
||||||
} else {
|
|
||||||
$io->writeError(' <warning>'.$processError->getMessage().'</warning>');
|
|
||||||
$io->writeError(' The archive may contain identical file names with different capitalization (which fails on case insensitive filesystems)');
|
|
||||||
$io->writeError(' Unzip with unzip command failed, falling back to ZipArchive class');
|
|
||||||
}
|
|
||||||
|
|
||||||
return $self->extractWithZipArchive($package, $file, $path, true);
|
|
||||||
};
|
|
||||||
|
|
||||||
try {
|
|
||||||
$promise = $this->process->executeAsync($command);
|
|
||||||
|
|
||||||
return $promise->then(function ($process) use ($tryFallback, $command, $package, $file) {
|
|
||||||
if (!$process->isSuccessful()) {
|
|
||||||
$output = $process->getErrorOutput();
|
|
||||||
$output = str_replace(', '.$file.'.zip or '.$file.'.ZIP', '', $output);
|
|
||||||
|
|
||||||
return $tryFallback(new \RuntimeException('Failed to extract '.$package->getName().': ('.$process->getExitCode().') '.$command."\n\n".$output));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} catch (\Exception $e) {
|
|
||||||
return $tryFallback($e);
|
|
||||||
} catch (\Throwable $e) {
|
|
||||||
return $tryFallback($e);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
$processError = null;
|
if (!is_file($file)) {
|
||||||
|
$io->writeError(' <warning>'.$processError->getMessage().'</warning>');
|
||||||
|
$io->writeError(' <warning>This most likely is due to a custom installer plugin not handling the returned Promise from the downloader</warning>');
|
||||||
|
$io->writeError(' <warning>See https://github.com/composer/installers/commit/5006d0c28730ade233a8f42ec31ac68fb1c5c9bb for an example fix</warning>');
|
||||||
|
} else {
|
||||||
|
$io->writeError(' <warning>'.$processError->getMessage().'</warning>');
|
||||||
|
$io->writeError(' The archive may contain identical file names with different capitalization (which fails on case insensitive filesystems)');
|
||||||
|
$io->writeError(' Unzip with '.$executable.' command failed, falling back to ZipArchive class');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $self->extractWithZipArchive($package, $file, $path);
|
||||||
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (0 === $exitCode = $this->process->execute($command, $ignoredOutput)) {
|
$promise = $this->process->executeAsync($command);
|
||||||
return \React\Promise\resolve();
|
|
||||||
}
|
|
||||||
|
|
||||||
$processError = new \RuntimeException('Failed to execute ('.$exitCode.') '.$command."\n\n".$this->process->getErrorOutput());
|
return $promise->then(function ($process) use ($tryFallback, $command, $package, $file) {
|
||||||
|
if (!$process->isSuccessful()) {
|
||||||
|
$output = $process->getErrorOutput();
|
||||||
|
$output = str_replace(', '.$file.'.zip or '.$file.'.ZIP', '', $output);
|
||||||
|
|
||||||
|
return $tryFallback(new \RuntimeException('Failed to extract '.$package->getName().': ('.$process->getExitCode().') '.$command."\n\n".$output));
|
||||||
|
}
|
||||||
|
});
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
$processError = $e;
|
return $tryFallback($e);
|
||||||
|
} catch (\Throwable $e) {
|
||||||
|
return $tryFallback($e);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($isLastChance) {
|
|
||||||
throw $processError;
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->io->writeError(' <warning>'.$processError->getMessage().'</warning>');
|
|
||||||
$this->io->writeError(' The archive may contain identical file names with different capitalization (which fails on case insensitive filesystems)');
|
|
||||||
$this->io->writeError(' Unzip with unzip command failed, falling back to ZipArchive class');
|
|
||||||
|
|
||||||
return $this->extractWithZipArchive($package, $file, $path, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -158,25 +138,13 @@ class ZipDownloader extends ArchiveDownloader
|
||||||
*
|
*
|
||||||
* @param string $file File to extract
|
* @param string $file File to extract
|
||||||
* @param string $path Path where to extract file
|
* @param string $path Path where to extract file
|
||||||
* @param bool $isLastChance If true it is called as a fallback and should throw an exception
|
|
||||||
* @return PromiseInterface
|
* @return PromiseInterface
|
||||||
*
|
*
|
||||||
* TODO v3 should make this private once we can drop PHP 5.3 support
|
* TODO v3 should make this private once we can drop PHP 5.3 support
|
||||||
* @protected
|
* @protected
|
||||||
*/
|
*/
|
||||||
public function extractWithZipArchive(PackageInterface $package, $file, $path, $isLastChance)
|
public function extractWithZipArchive(PackageInterface $package, $file, $path)
|
||||||
{
|
{
|
||||||
if (!self::$hasSystemUnzip) {
|
|
||||||
// Force Exception throwing if the Other alternative is not available
|
|
||||||
$isLastChance = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!self::$hasZipArchive && !$isLastChance) {
|
|
||||||
// This was call as the favorite extract way, but is not available
|
|
||||||
// We switch to the alternative
|
|
||||||
return $this->extractWithSystemUnzip($package, $file, $path, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
$processError = null;
|
$processError = null;
|
||||||
$zipArchive = $this->zipArchiveObject ?: new ZipArchive();
|
$zipArchive = $this->zipArchiveObject ?: new ZipArchive();
|
||||||
|
|
||||||
|
@ -202,14 +170,7 @@ class ZipDownloader extends ArchiveDownloader
|
||||||
$processError = $e;
|
$processError = $e;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($isLastChance) {
|
throw $processError;
|
||||||
throw $processError;
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->io->writeError(' <warning>'.$processError->getMessage().'</warning>');
|
|
||||||
$this->io->writeError(' Unzip with ZipArchive class failed, falling back to unzip command');
|
|
||||||
|
|
||||||
return $this->extractWithSystemUnzip($package, $file, $path, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -224,12 +185,7 @@ class ZipDownloader extends ArchiveDownloader
|
||||||
*/
|
*/
|
||||||
public function extract(PackageInterface $package, $file, $path)
|
public function extract(PackageInterface $package, $file, $path)
|
||||||
{
|
{
|
||||||
// Each extract calls its alternative if not available or fails
|
return $this->extractWithSystemUnzip($package, $file, $path);
|
||||||
if (self::$isWindows) {
|
|
||||||
return $this->extractWithZipArchive($package, $file, $path, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->extractWithSystemUnzip($package, $file, $path, false, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -44,7 +44,6 @@ class ZipDownloaderTest extends TestCase
|
||||||
{
|
{
|
||||||
$fs = new Filesystem;
|
$fs = new Filesystem;
|
||||||
$fs->removeDirectory($this->testDir);
|
$fs->removeDirectory($this->testDir);
|
||||||
$this->setPrivateProperty('hasSystemUnzip', null);
|
|
||||||
$this->setPrivateProperty('hasZipArchive', null);
|
$this->setPrivateProperty('hasZipArchive', null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,7 +85,6 @@ class ZipDownloaderTest extends TestCase
|
||||||
|
|
||||||
$downloader = new ZipDownloader($this->io, $this->config, $this->httpDownloader);
|
$downloader = new ZipDownloader($this->io, $this->config, $this->httpDownloader);
|
||||||
|
|
||||||
$this->setPrivateProperty('hasSystemUnzip', false);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$loop = new Loop($this->httpDownloader);
|
$loop = new Loop($this->httpDownloader);
|
||||||
|
@ -107,7 +105,6 @@ class ZipDownloaderTest extends TestCase
|
||||||
$this->markTestSkipped('zip extension missing');
|
$this->markTestSkipped('zip extension missing');
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->setPrivateProperty('hasSystemUnzip', false);
|
|
||||||
$this->setPrivateProperty('hasZipArchive', true);
|
$this->setPrivateProperty('hasZipArchive', true);
|
||||||
$downloader = new MockedZipDownloader($this->io, $this->config, $this->httpDownloader);
|
$downloader = new MockedZipDownloader($this->io, $this->config, $this->httpDownloader);
|
||||||
$zipArchive = $this->getMockBuilder('ZipArchive')->getMock();
|
$zipArchive = $this->getMockBuilder('ZipArchive')->getMock();
|
||||||
|
@ -130,7 +127,6 @@ class ZipDownloaderTest extends TestCase
|
||||||
$this->markTestSkipped('zip extension missing');
|
$this->markTestSkipped('zip extension missing');
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->setPrivateProperty('hasSystemUnzip', false);
|
|
||||||
$this->setPrivateProperty('hasZipArchive', true);
|
$this->setPrivateProperty('hasZipArchive', true);
|
||||||
$downloader = new MockedZipDownloader($this->io, $this->config, $this->httpDownloader);
|
$downloader = new MockedZipDownloader($this->io, $this->config, $this->httpDownloader);
|
||||||
$zipArchive = $this->getMockBuilder('ZipArchive')->getMock();
|
$zipArchive = $this->getMockBuilder('ZipArchive')->getMock();
|
||||||
|
@ -152,7 +148,6 @@ class ZipDownloaderTest extends TestCase
|
||||||
$this->markTestSkipped('zip extension missing');
|
$this->markTestSkipped('zip extension missing');
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->setPrivateProperty('hasSystemUnzip', false);
|
|
||||||
$this->setPrivateProperty('hasZipArchive', true);
|
$this->setPrivateProperty('hasZipArchive', true);
|
||||||
$downloader = new MockedZipDownloader($this->io, $this->config, $this->httpDownloader);
|
$downloader = new MockedZipDownloader($this->io, $this->config, $this->httpDownloader);
|
||||||
$zipArchive = $this->getMockBuilder('ZipArchive')->getMock();
|
$zipArchive = $this->getMockBuilder('ZipArchive')->getMock();
|
||||||
|
@ -172,8 +167,8 @@ class ZipDownloaderTest extends TestCase
|
||||||
{
|
{
|
||||||
$this->setExpectedException('Exception', 'Failed to extract : (1) unzip');
|
$this->setExpectedException('Exception', 'Failed to extract : (1) unzip');
|
||||||
$this->setPrivateProperty('isWindows', false);
|
$this->setPrivateProperty('isWindows', false);
|
||||||
$this->setPrivateProperty('hasSystemUnzip', true);
|
|
||||||
$this->setPrivateProperty('hasZipArchive', false);
|
$this->setPrivateProperty('hasZipArchive', false);
|
||||||
|
$this->setPrivateProperty('unzipCommands', array(array('unzip', 'unzip -qq %s -d %s')));
|
||||||
|
|
||||||
$procMock = $this->getMockBuilder('Symfony\Component\Process\Process')->disableOriginalConstructor()->getMock();
|
$procMock = $this->getMockBuilder('Symfony\Component\Process\Process')->disableOriginalConstructor()->getMock();
|
||||||
$procMock->expects($this->any())
|
$procMock->expects($this->any())
|
||||||
|
@ -199,8 +194,8 @@ class ZipDownloaderTest extends TestCase
|
||||||
public function testSystemUnzipOnlyGood()
|
public function testSystemUnzipOnlyGood()
|
||||||
{
|
{
|
||||||
$this->setPrivateProperty('isWindows', false);
|
$this->setPrivateProperty('isWindows', false);
|
||||||
$this->setPrivateProperty('hasSystemUnzip', true);
|
|
||||||
$this->setPrivateProperty('hasZipArchive', false);
|
$this->setPrivateProperty('hasZipArchive', false);
|
||||||
|
$this->setPrivateProperty('unzipCommands', array(array('unzip', 'unzip -qq %s -d %s')));
|
||||||
|
|
||||||
$procMock = $this->getMockBuilder('Symfony\Component\Process\Process')->disableOriginalConstructor()->getMock();
|
$procMock = $this->getMockBuilder('Symfony\Component\Process\Process')->disableOriginalConstructor()->getMock();
|
||||||
$procMock->expects($this->any())
|
$procMock->expects($this->any())
|
||||||
|
@ -230,7 +225,6 @@ class ZipDownloaderTest extends TestCase
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->setPrivateProperty('isWindows', false);
|
$this->setPrivateProperty('isWindows', false);
|
||||||
$this->setPrivateProperty('hasSystemUnzip', true);
|
|
||||||
$this->setPrivateProperty('hasZipArchive', true);
|
$this->setPrivateProperty('hasZipArchive', true);
|
||||||
|
|
||||||
$procMock = $this->getMockBuilder('Symfony\Component\Process\Process')->disableOriginalConstructor()->getMock();
|
$procMock = $this->getMockBuilder('Symfony\Component\Process\Process')->disableOriginalConstructor()->getMock();
|
||||||
|
@ -271,7 +265,6 @@ class ZipDownloaderTest extends TestCase
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->setPrivateProperty('isWindows', false);
|
$this->setPrivateProperty('isWindows', false);
|
||||||
$this->setPrivateProperty('hasSystemUnzip', true);
|
|
||||||
$this->setPrivateProperty('hasZipArchive', true);
|
$this->setPrivateProperty('hasZipArchive', true);
|
||||||
|
|
||||||
$procMock = $this->getMockBuilder('Symfony\Component\Process\Process')->disableOriginalConstructor()->getMock();
|
$procMock = $this->getMockBuilder('Symfony\Component\Process\Process')->disableOriginalConstructor()->getMock();
|
||||||
|
@ -304,65 +297,6 @@ class ZipDownloaderTest extends TestCase
|
||||||
$this->wait($promise);
|
$this->wait($promise);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testWindowsFallbackGood()
|
|
||||||
{
|
|
||||||
if (!class_exists('ZipArchive')) {
|
|
||||||
$this->markTestSkipped('zip extension missing');
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->setPrivateProperty('isWindows', true);
|
|
||||||
$this->setPrivateProperty('hasSystemUnzip', true);
|
|
||||||
$this->setPrivateProperty('hasZipArchive', true);
|
|
||||||
|
|
||||||
$processExecutor = $this->getMockBuilder('Composer\Util\ProcessExecutor')->getMock();
|
|
||||||
$processExecutor->expects($this->atLeastOnce())
|
|
||||||
->method('execute')
|
|
||||||
->will($this->returnValue(0));
|
|
||||||
|
|
||||||
$zipArchive = $this->getMockBuilder('ZipArchive')->getMock();
|
|
||||||
$zipArchive->expects($this->at(0))
|
|
||||||
->method('open')
|
|
||||||
->will($this->returnValue(true));
|
|
||||||
$zipArchive->expects($this->at(1))
|
|
||||||
->method('extractTo')
|
|
||||||
->will($this->returnValue(false));
|
|
||||||
|
|
||||||
$downloader = new MockedZipDownloader($this->io, $this->config, $this->httpDownloader, null, null, null, $processExecutor);
|
|
||||||
$this->setPrivateProperty('zipArchiveObject', $zipArchive, $downloader);
|
|
||||||
$promise = $downloader->extract($this->package, 'testfile.zip', 'vendor/dir');
|
|
||||||
$this->wait($promise);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testWindowsFallbackFailed()
|
|
||||||
{
|
|
||||||
$this->setExpectedException('Exception', 'Failed to execute (1) unzip');
|
|
||||||
if (!class_exists('ZipArchive')) {
|
|
||||||
$this->markTestSkipped('zip extension missing');
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->setPrivateProperty('isWindows', true);
|
|
||||||
$this->setPrivateProperty('hasSystemUnzip', true);
|
|
||||||
$this->setPrivateProperty('hasZipArchive', true);
|
|
||||||
|
|
||||||
$processExecutor = $this->getMockBuilder('Composer\Util\ProcessExecutor')->getMock();
|
|
||||||
$processExecutor->expects($this->atLeastOnce())
|
|
||||||
->method('execute')
|
|
||||||
->will($this->returnValue(1));
|
|
||||||
|
|
||||||
$zipArchive = $this->getMockBuilder('ZipArchive')->getMock();
|
|
||||||
$zipArchive->expects($this->at(0))
|
|
||||||
->method('open')
|
|
||||||
->will($this->returnValue(true));
|
|
||||||
$zipArchive->expects($this->at(1))
|
|
||||||
->method('extractTo')
|
|
||||||
->will($this->returnValue(false));
|
|
||||||
|
|
||||||
$downloader = new MockedZipDownloader($this->io, $this->config, $this->httpDownloader, null, null, null, $processExecutor);
|
|
||||||
$this->setPrivateProperty('zipArchiveObject', $zipArchive, $downloader);
|
|
||||||
$promise = $downloader->extract($this->package, 'testfile.zip', 'vendor/dir');
|
|
||||||
$this->wait($promise);
|
|
||||||
}
|
|
||||||
|
|
||||||
private function wait($promise)
|
private function wait($promise)
|
||||||
{
|
{
|
||||||
if (null === $promise) {
|
if (null === $promise) {
|
||||||
|
|
|
@ -21,7 +21,7 @@ Lock file operations: 6 installs, 0 updates, 0 removals
|
||||||
- Locking symfony/process (12345.1.2)
|
- Locking symfony/process (12345.1.2)
|
||||||
Writing lock file
|
Writing lock file
|
||||||
Installing dependencies from lock file (including require-dev)
|
Installing dependencies from lock file (including require-dev)
|
||||||
Package operations: 6 installs, 0 updates, 0 removals%(\nAs there is no 'unzip' command installed zip files are being unpacked using the PHP zip extension.\nThis may cause invalid reports of corrupted archives. Besides, any UNIX permissions \(e.g. executable\) defined in the archives will be lost.\nInstalling 'unzip' may remediate them.)?%
|
Package operations: 6 installs, 0 updates, 0 removals%(\nAs there is no 'unzip' nor '7z' command installed zip files are being unpacked using the PHP zip extension.\nThis may cause invalid reports of corrupted archives. Besides, any UNIX permissions \(e.g. executable\) defined in the archives will be lost.\nInstalling 'unzip' or '7z' may remediate them.)?%
|
||||||
- Downloading symfony/polyfill-ctype (%v?[1-8]\.\d+\.\d+%)
|
- Downloading symfony/polyfill-ctype (%v?[1-8]\.\d+\.\d+%)
|
||||||
- Downloading symfony/filesystem (%v?[2-8]\.\d+\.\d+%)
|
- Downloading symfony/filesystem (%v?[2-8]\.\d+\.\d+%)
|
||||||
- Installing symfony/console (99999.1.2): Symlinking from symfony-console
|
- Installing symfony/console (99999.1.2): Symlinking from symfony-console
|
||||||
|
|
|
@ -26,7 +26,7 @@ Lock file operations: 0 installs, 5 updates, 0 removals
|
||||||
- Upgrading symfony/process (12345.1.2 => 12345.1.3)
|
- Upgrading symfony/process (12345.1.2 => 12345.1.3)
|
||||||
Writing lock file
|
Writing lock file
|
||||||
Installing dependencies from lock file (including require-dev)
|
Installing dependencies from lock file (including require-dev)
|
||||||
Package operations: 0 installs, 5 updates, 0 removals%(\nAs there is no 'unzip' command installed zip files are being unpacked using the PHP zip extension.\nThis may cause invalid reports of corrupted archives. Besides, any UNIX permissions \(e.g. executable\) defined in the archives will be lost.\nInstalling 'unzip' may remediate them.)?%
|
Package operations: 0 installs, 5 updates, 0 removals%(\nAs there is no 'unzip' nor '7z' command installed zip files are being unpacked using the PHP zip extension.\nThis may cause invalid reports of corrupted archives. Besides, any UNIX permissions \(e.g. executable\) defined in the archives will be lost.\nInstalling 'unzip' or '7z' may remediate them.)?%
|
||||||
- Downloading symfony/filesystem (%v?[2-8]\.\d+\.\d+%)
|
- Downloading symfony/filesystem (%v?[2-8]\.\d+\.\d+%)
|
||||||
- Upgrading symfony/console (99999.1.2 => 99999.1.3): Mirroring from symfony-console
|
- Upgrading symfony/console (99999.1.2 => 99999.1.3): Mirroring from symfony-console
|
||||||
- Upgrading plugin/a (1.1.1 => 1.1.2): Mirroring from plugin-a
|
- Upgrading plugin/a (1.1.1 => 1.1.2): Mirroring from plugin-a
|
||||||
|
|
Loading…
Reference in New Issue