From 3811fe7d8b30c21ffcb401eb1bc9e1d2749cb794 Mon Sep 17 00:00:00 2001 From: Pavel Puchkin Date: Wed, 26 Feb 2014 21:23:15 +1100 Subject: [PATCH 1/6] Resolves #2521. First and simple attempt to make a gzip downloader --- src/Composer/Downloader/GzipDownloader.php | 53 ++++++++++++++++++++++ src/Composer/Factory.php | 1 + 2 files changed, 54 insertions(+) create mode 100644 src/Composer/Downloader/GzipDownloader.php diff --git a/src/Composer/Downloader/GzipDownloader.php b/src/Composer/Downloader/GzipDownloader.php new file mode 100644 index 000000000..6736c9cc1 --- /dev/null +++ b/src/Composer/Downloader/GzipDownloader.php @@ -0,0 +1,53 @@ + + * Jordi Boggiano + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Composer\Downloader; + +use Composer\Config; +use Composer\Cache; +use Composer\EventDispatcher\EventDispatcher; +use Composer\Util\ProcessExecutor; +use Composer\IO\IOInterface; + +/** + * GZip archive downloader. + * + * @author Pavel Puchkin + */ +class GzipDownloader extends ArchiveDownloader +{ + protected $process; + + public function __construct(IOInterface $io, Config $config, EventDispatcher $eventDispatcher = null, Cache $cache = null, ProcessExecutor $process = null) + { + $this->process = $process ?: new ProcessExecutor($io); + parent::__construct($io, $config, $eventDispatcher, $cache); + } + + protected function extract($file, $path) + { + $processError = null; + + // Try to use gunzip on *nix + if (!defined('PHP_WINDOWS_VERSION_BUILD')) { + $targetDirectory = $path . DIRECTORY_SEPARATOR . basename($file); + $command = 'gzip -d < ' . escapeshellarg($file) . ' > ' . escapeshellarg($targetDirectory); + + if (0 === $this->process->execute($command, $ignoredOutput)) { + return; + } + + $processError = 'Failed to execute ' . $command . "\n\n" . $this->process->getErrorOutput(); + } + } +} + diff --git a/src/Composer/Factory.php b/src/Composer/Factory.php index 27f83dd87..d0cd68b79 100644 --- a/src/Composer/Factory.php +++ b/src/Composer/Factory.php @@ -365,6 +365,7 @@ class Factory $dm->setDownloader('zip', new Downloader\ZipDownloader($io, $config, $eventDispatcher, $cache)); $dm->setDownloader('rar', new Downloader\RarDownloader($io, $config, $eventDispatcher, $cache)); $dm->setDownloader('tar', new Downloader\TarDownloader($io, $config, $eventDispatcher, $cache)); + $dm->setDownloader('gzip', new Downloader\GzipDownloader($io, $config, $eventDispatcher, $cache)); $dm->setDownloader('phar', new Downloader\PharDownloader($io, $config, $eventDispatcher, $cache)); $dm->setDownloader('file', new Downloader\FileDownloader($io, $config, $eventDispatcher, $cache)); From a2878846195dd0eba742099fabc2a1bda8e10a71 Mon Sep 17 00:00:00 2001 From: Pavel Puchkin Date: Wed, 26 Feb 2014 22:52:47 +1100 Subject: [PATCH 2/6] There is no need in DIRECTORY_SEPARATOR since it Unix --- src/Composer/Downloader/GzipDownloader.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Composer/Downloader/GzipDownloader.php b/src/Composer/Downloader/GzipDownloader.php index 6736c9cc1..e14b7de02 100644 --- a/src/Composer/Downloader/GzipDownloader.php +++ b/src/Composer/Downloader/GzipDownloader.php @@ -39,7 +39,7 @@ class GzipDownloader extends ArchiveDownloader // Try to use gunzip on *nix if (!defined('PHP_WINDOWS_VERSION_BUILD')) { - $targetDirectory = $path . DIRECTORY_SEPARATOR . basename($file); + $targetDirectory = $path . '/' . basename($file); $command = 'gzip -d < ' . escapeshellarg($file) . ' > ' . escapeshellarg($targetDirectory); if (0 === $this->process->execute($command, $ignoredOutput)) { From ba56ac362a8ee0a953c8340410723568a4a282b6 Mon Sep 17 00:00:00 2001 From: Pavel Puchkin Date: Wed, 26 Feb 2014 23:49:53 +1100 Subject: [PATCH 3/6] Final fix. Preserve initial file name --- src/Composer/Downloader/GzipDownloader.php | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/Composer/Downloader/GzipDownloader.php b/src/Composer/Downloader/GzipDownloader.php index e14b7de02..11e1b8ba6 100644 --- a/src/Composer/Downloader/GzipDownloader.php +++ b/src/Composer/Downloader/GzipDownloader.php @@ -15,6 +15,7 @@ namespace Composer\Downloader; use Composer\Config; use Composer\Cache; use Composer\EventDispatcher\EventDispatcher; +use Composer\Package\PackageInterface; use Composer\Util\ProcessExecutor; use Composer\IO\IOInterface; @@ -39,15 +40,24 @@ class GzipDownloader extends ArchiveDownloader // Try to use gunzip on *nix if (!defined('PHP_WINDOWS_VERSION_BUILD')) { - $targetDirectory = $path . '/' . basename($file); - $command = 'gzip -d < ' . escapeshellarg($file) . ' > ' . escapeshellarg($targetDirectory); + $targetFile = $path . '/' . basename(substr($file, 0, -3)); + $command = 'gzip -cd ' . escapeshellarg($file) . ' > ' . escapeshellarg($targetFile); if (0 === $this->process->execute($command, $ignoredOutput)) { return; } $processError = 'Failed to execute ' . $command . "\n\n" . $this->process->getErrorOutput(); + throw new \RuntimeException($processError); } } + + /** + * {@inheritdoc} + */ + protected function getFileName(PackageInterface $package, $path) + { + return $path.'/'.pathinfo(parse_url($package->getDistUrl(), PHP_URL_PATH), PATHINFO_BASENAME); + } } From c598fdb0f50542c6963ae01839bb6f8c04e164e2 Mon Sep 17 00:00:00 2001 From: Pavel Puchkin Date: Thu, 27 Feb 2014 00:01:11 +1100 Subject: [PATCH 4/6] Since there is no solution for non-unix (for now), remove the condition --- src/Composer/Downloader/GzipDownloader.php | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/src/Composer/Downloader/GzipDownloader.php b/src/Composer/Downloader/GzipDownloader.php index 11e1b8ba6..61f92caf9 100644 --- a/src/Composer/Downloader/GzipDownloader.php +++ b/src/Composer/Downloader/GzipDownloader.php @@ -36,20 +36,15 @@ class GzipDownloader extends ArchiveDownloader protected function extract($file, $path) { - $processError = null; + $targetFile = $path . '/' . basename(substr($file, 0, -3)); + $command = 'gzip -cd ' . escapeshellarg($file) . ' > ' . escapeshellarg($targetFile); - // Try to use gunzip on *nix - if (!defined('PHP_WINDOWS_VERSION_BUILD')) { - $targetFile = $path . '/' . basename(substr($file, 0, -3)); - $command = 'gzip -cd ' . escapeshellarg($file) . ' > ' . escapeshellarg($targetFile); - - if (0 === $this->process->execute($command, $ignoredOutput)) { - return; - } - - $processError = 'Failed to execute ' . $command . "\n\n" . $this->process->getErrorOutput(); - throw new \RuntimeException($processError); + if (0 === $this->process->execute($command, $ignoredOutput)) { + return; } + + $processError = 'Failed to execute ' . $command . "\n\n" . $this->process->getErrorOutput(); + throw new \RuntimeException($processError); } /** From 7ccb91667f8c4c3f95d8705f5986f86f5a2e350e Mon Sep 17 00:00:00 2001 From: Pavel Puchkin Date: Fri, 28 Feb 2014 10:30:12 +1100 Subject: [PATCH 5/6] Fallback to gzip functions when on Windows --- src/Composer/Downloader/GzipDownloader.php | 25 ++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/src/Composer/Downloader/GzipDownloader.php b/src/Composer/Downloader/GzipDownloader.php index 61f92caf9..4444db369 100644 --- a/src/Composer/Downloader/GzipDownloader.php +++ b/src/Composer/Downloader/GzipDownloader.php @@ -36,15 +36,28 @@ class GzipDownloader extends ArchiveDownloader protected function extract($file, $path) { - $targetFile = $path . '/' . basename(substr($file, 0, -3)); - $command = 'gzip -cd ' . escapeshellarg($file) . ' > ' . escapeshellarg($targetFile); + $targetFilepath = $path . DIRECTORY_SEPARATOR . basename(substr($file, 0, -3)); - if (0 === $this->process->execute($command, $ignoredOutput)) { - return; + // Try to use gunzip on *nix + if (!defined('PHP_WINDOWS_VERSION_BUILD')) { + $command = 'gzip -cd ' . escapeshellarg($file) . ' > ' . escapeshellarg($targetFilepath); + + if (0 === $this->process->execute($command, $ignoredOutput)) { + return; + } + + $processError = 'Failed to execute ' . $command . "\n\n" . $this->process->getErrorOutput(); + throw new \RuntimeException($processError); } - $processError = 'Failed to execute ' . $command . "\n\n" . $this->process->getErrorOutput(); - throw new \RuntimeException($processError); + // Gzip version of PHP has built-in support of gzip functions + $archiveFile = gzopen($file, 'rb'); + $targetFile = fopen($targetFilepath, 'wb'); + while ($string = gzread($archiveFile, 4096)) { + fwrite($targetFile, $string, strlen($string)); + } + gzclose($archiveFile); + fclose($targetFile); } /** From 9fda8cdc84cc488c5d3bb651db5f388bf3dd90c2 Mon Sep 17 00:00:00 2001 From: Pavel Puchkin Date: Wed, 5 Mar 2014 11:25:58 +1000 Subject: [PATCH 6/6] Type in comment --- src/Composer/Downloader/GzipDownloader.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Composer/Downloader/GzipDownloader.php b/src/Composer/Downloader/GzipDownloader.php index 4444db369..fb4bce89d 100644 --- a/src/Composer/Downloader/GzipDownloader.php +++ b/src/Composer/Downloader/GzipDownloader.php @@ -50,7 +50,7 @@ class GzipDownloader extends ArchiveDownloader throw new \RuntimeException($processError); } - // Gzip version of PHP has built-in support of gzip functions + // Windows version of PHP has built-in support of gzip functions $archiveFile = gzopen($file, 'rb'); $targetFile = fopen($targetFilepath, 'wb'); while ($string = gzread($archiveFile, 4096)) {