From 184623af9621f2996c27facc900046ae53449924 Mon Sep 17 00:00:00 2001 From: Jan Kunzmann Date: Fri, 12 Jun 2015 13:04:12 +0200 Subject: [PATCH 01/10] ClassLoader: Generalized findFileWithExtension to work with multiple extensions --- src/Composer/Autoload/ClassLoader.php | 76 +++++++++++++++++---------- 1 file changed, 48 insertions(+), 28 deletions(-) diff --git a/src/Composer/Autoload/ClassLoader.php b/src/Composer/Autoload/ClassLoader.php index 4e05d3b15834..f3afbdaa4aba 100644 --- a/src/Composer/Autoload/ClassLoader.php +++ b/src/Composer/Autoload/ClassLoader.php @@ -326,13 +326,14 @@ public function findFile($class) return false; } - $file = $this->findFileWithExtension($class, '.php'); - + $exts = ['.php']; // Search for Hack files if we are running on HHVM - if ($file === null && defined('HHVM_VERSION')) { - $file = $this->findFileWithExtension($class, '.hh'); + if (defined('HHVM_VERSION')) { + $exts[] = '.hh'; } + $file = $this->findFileWithExtensions($class, $exts); + if ($file === null) { // Remember that this class does not exist. return $this->classMap[$class] = false; @@ -341,18 +342,22 @@ public function findFile($class) return $file; } - private function findFileWithExtension($class, $ext) + private function findFileWithExtensions($class, array $exts) { - // PSR-4 lookup - $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext; - + $psr4ClassPath = strtr($class, '\\', DIRECTORY_SEPARATOR); $first = $class[0]; - if (isset($this->prefixLengthsPsr4[$first])) { - foreach ($this->prefixLengthsPsr4[$first] as $prefix => $length) { - if (0 === strpos($class, $prefix)) { - foreach ($this->prefixDirsPsr4[$prefix] as $dir) { - if (is_file($file = $dir . DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $length))) { - return $file; + + foreach ($exts as $ext) { + // PSR-4 lookup + $logicalPathPsr4 = $psr4ClassPath . $ext; + + if (isset($this->prefixLengthsPsr4[$first])) { + foreach ($this->prefixLengthsPsr4[$first] as $prefix => $length) { + if (0 === strpos($class, $prefix)) { + foreach ($this->prefixDirsPsr4[$prefix] as $dir) { + if (is_file($file = $dir . DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $length))) { + return $file; + } } } } @@ -360,28 +365,35 @@ private function findFileWithExtension($class, $ext) } // PSR-4 fallback dirs - foreach ($this->fallbackDirsPsr4 as $dir) { - if (is_file($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) { - return $file; + if (count($this->fallbackDirsPsr4) > 0) { + foreach ($exts as $ext) { + $logicalPathPsr4 = $psr4ClassPath . $ext; + foreach ($this->fallbackDirsPsr4 as $dir) { + if (is_file($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) { + return $file; + } + } } } // PSR-0 lookup if (false !== $pos = strrpos($class, '\\')) { // namespaced class name - $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1) - . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR); + $psr0ClassPath = substr($psr4ClassPath, 0, $pos + 1) + . strtr(substr($psr4ClassPath, $pos + 1), '_', DIRECTORY_SEPARATOR); } else { // PEAR-like class name - $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext; + $psr0ClassPath = strtr($class, '_', DIRECTORY_SEPARATOR); } if (isset($this->prefixesPsr0[$first])) { foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) { if (0 === strpos($class, $prefix)) { - foreach ($dirs as $dir) { - if (is_file($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { - return $file; + foreach ($exts as $ext) { + foreach ($dirs as $dir) { + if (is_file($file = $dir . DIRECTORY_SEPARATOR . $psr0ClassPath . $ext)) { + return $file; + } } } } @@ -389,15 +401,23 @@ private function findFileWithExtension($class, $ext) } // PSR-0 fallback dirs - foreach ($this->fallbackDirsPsr0 as $dir) { - if (is_file($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { - return $file; + if (count($this->fallbackDirsPsr0) > 0) { + foreach ($exts as $ext) { + foreach ($this->fallbackDirsPsr0 as $dir) { + if (is_file($file = $dir . DIRECTORY_SEPARATOR . $psr0ClassPath . $ext)) { + return $file; + } + } } } // PSR-0 include paths. - if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) { - return $file; + if ($this->useIncludePath) { + foreach ($exts as $ext) { + if ($file = stream_resolve_include_path($psr0ClassPath . $ext)) { + return $file; + } + } } } } From 2dce97d1d80f27e3298ef829db7f700358c51677 Mon Sep 17 00:00:00 2001 From: Jan Kunzmann Date: Fri, 12 Jun 2015 15:08:51 +0200 Subject: [PATCH 02/10] Make include file extensions configurable in package.json --- src/Composer/Autoload/AutoloadGenerator.php | 29 ++++++++++++++++-- src/Composer/Autoload/ClassLoader.php | 34 ++++++++++++++++++--- src/Composer/Package/AliasPackage.php | 4 +++ src/Composer/Package/Dumper/ArrayDumper.php | 1 + src/Composer/Package/Loader/ArrayLoader.php | 4 +++ src/Composer/Package/Package.php | 19 ++++++++++++ src/Composer/Package/PackageInterface.php | 7 +++++ 7 files changed, 91 insertions(+), 7 deletions(-) diff --git a/src/Composer/Autoload/AutoloadGenerator.php b/src/Composer/Autoload/AutoloadGenerator.php index 52166083cae5..2dfbb1c28d21 100644 --- a/src/Composer/Autoload/AutoloadGenerator.php +++ b/src/Composer/Autoload/AutoloadGenerator.php @@ -236,7 +236,7 @@ public static function autoload(\$class) file_put_contents($targetDir.'/autoload_files.php', $includeFilesFile); } file_put_contents($vendorPath.'/autoload.php', $this->getAutoloadFile($vendorPathToTargetDirCode, $suffix)); - file_put_contents($targetDir.'/autoload_real.php', $this->getAutoloadRealFile(true, (bool) $includePathFile, $targetDirLoader, (bool) $includeFilesFile, $vendorPathCode, $appBaseDirCode, $suffix, $useGlobalIncludePath, $prependAutoloader, $classMapAuthoritative)); + file_put_contents($targetDir.'/autoload_real.php', $this->getAutoloadRealFile(true, (bool) $includePathFile, $targetDirLoader, (bool) $includeFilesFile, $vendorPathCode, $appBaseDirCode, $suffix, $useGlobalIncludePath, $prependAutoloader, $classMapAuthoritative, $autoloads['extensions'])); // use stream_copy_to_stream instead of copy // to work around https://bugs.php.net/bug.php?id=64634 @@ -312,11 +312,12 @@ public function parseAutoloads(array $packageMap, PackageInterface $mainPackage) $psr4 = $this->parseAutoloadsType($packageMap, 'psr-4', $mainPackage); $classmap = $this->parseAutoloadsType($sortedPackageMap, 'classmap', $mainPackage); $files = $this->parseAutoloadsType($sortedPackageMap, 'files', $mainPackage); + $extensions = $this->parseExtensions($packageMap, $mainPackage); krsort($psr0); krsort($psr4); - return array('psr-0' => $psr0, 'psr-4' => $psr4, 'classmap' => $classmap, 'files' => $files); + return array('psr-0' => $psr0, 'psr-4' => $psr4, 'classmap' => $classmap, 'files' => $files, 'extensions' => $extensions); } /** @@ -453,7 +454,7 @@ protected function getAutoloadFile($vendorPathToTargetDirCode, $suffix) AUTOLOAD; } - protected function getAutoloadRealFile($useClassMap, $useIncludePath, $targetDirLoader, $useIncludeFiles, $vendorPathCode, $appBaseDirCode, $suffix, $useGlobalIncludePath, $prependAutoloader, $classMapAuthoritative) + protected function getAutoloadRealFile($useClassMap, $useIncludePath, $targetDirLoader, $useIncludeFiles, $vendorPathCode, $appBaseDirCode, $suffix, $useGlobalIncludePath, $prependAutoloader, $classMapAuthoritative, $autoloadExtensions) { // TODO the class ComposerAutoloaderInit should be revert to a closure // when APC has been fixed: @@ -544,6 +545,14 @@ public static function getLoader() INCLUDEPATH; } + if ($autoloadExtensions) { + $autoloadExtensions = var_export($autoloadExtensions, true); + $file .= <<setAutoloadExtensions($autoloadExtensions); + +AUTOLOAD_EXTENSION; + } + if ($targetDirLoader) { $file .= <<getAutoloadExtensions() as $ext) { + $extensions[$ext] = $ext; + } + } + + return array_values($extensions); + + } + /** * Sorts packages by dependency weight * diff --git a/src/Composer/Autoload/ClassLoader.php b/src/Composer/Autoload/ClassLoader.php index f3afbdaa4aba..95dd3604bbd0 100644 --- a/src/Composer/Autoload/ClassLoader.php +++ b/src/Composer/Autoload/ClassLoader.php @@ -56,6 +56,8 @@ class ClassLoader private $classMapAuthoritative = false; + private $autoloadExtensions = array(); + public function getPrefixes() { if (!empty($this->prefixesPsr0)) { @@ -271,6 +273,26 @@ public function isClassMapAuthoritative() return $this->classMapAuthoritative; } + /** + * Sets autoload extensions + * + * @param $autoloadExtensions + */ + public function setAutoloadExtensions($autoloadExtensions) + { + $this->autoloadExtensions = $autoloadExtensions; + } + + /** + * Returns autoload extensions + * + * @return array + */ + public function getAutoloadExtensions() + { + return $this->autoloadExtensions; + } + /** * Registers this instance as an autoloader. * @@ -326,10 +348,14 @@ public function findFile($class) return false; } - $exts = ['.php']; - // Search for Hack files if we are running on HHVM - if (defined('HHVM_VERSION')) { - $exts[] = '.hh'; + // set autoload extensions with a reasonable default + $exts = $this->autoloadExtensions; + if (count($exts) == 0) { + $exts = ['.php']; + // Search for Hack files if we are running on HHVM + if (defined('HHVM_VERSION')) { + $exts[] = '.hh'; + } } $file = $this->findFileWithExtensions($class, $exts); diff --git a/src/Composer/Package/AliasPackage.php b/src/Composer/Package/AliasPackage.php index f6aa98a4ca2f..1d57d6ba9391 100644 --- a/src/Composer/Package/AliasPackage.php +++ b/src/Composer/Package/AliasPackage.php @@ -297,6 +297,10 @@ public function getDevAutoload() { return $this->aliasOf->getDevAutoload(); } + public function getAutoloadExtensions() + { + return $this->aliasOf->getAutoloadExtensions(); + } public function getIncludePaths() { return $this->aliasOf->getIncludePaths(); diff --git a/src/Composer/Package/Dumper/ArrayDumper.php b/src/Composer/Package/Dumper/ArrayDumper.php index 714c5183b9b1..cce77869eb2f 100644 --- a/src/Composer/Package/Dumper/ArrayDumper.php +++ b/src/Composer/Package/Dumper/ArrayDumper.php @@ -32,6 +32,7 @@ public function dump(PackageInterface $package) 'installationSource' => 'installation-source', 'autoload', 'devAutoload' => 'autoload-dev', + 'autoloadExtensions' => 'autoload-extensions', 'notificationUrl' => 'notification-url', 'includePaths' => 'include-path', ); diff --git a/src/Composer/Package/Loader/ArrayLoader.php b/src/Composer/Package/Loader/ArrayLoader.php index 60cff3b33243..3ad6050a18b7 100644 --- a/src/Composer/Package/Loader/ArrayLoader.php +++ b/src/Composer/Package/Loader/ArrayLoader.php @@ -142,6 +142,10 @@ public function load(array $config, $class = 'Composer\Package\CompletePackage') $package->setDevAutoload($config['autoload-dev']); } + if (isset($config['autoload-extensions'])) { + $package->setAutoloadExtensions($config['autoload-extensions']); + } + if (isset($config['include-path'])) { $package->setIncludePaths($config['include-path']); } diff --git a/src/Composer/Package/Package.php b/src/Composer/Package/Package.php index 0c98a0e56353..69366501effa 100644 --- a/src/Composer/Package/Package.php +++ b/src/Composer/Package/Package.php @@ -51,6 +51,7 @@ class Package extends BasePackage protected $suggests = array(); protected $autoload = array(); protected $devAutoload = array(); + protected $autoloadExtensions = array(); protected $includePaths = array(); protected $archiveExcludes = array(); @@ -510,6 +511,24 @@ public function getDevAutoload() return $this->devAutoload; } + /** + * Set the autoload extensions + * + * @param array $extensions + */ + public function setAutoloadExtensions(array $extensions) + { + $this->autoloadExtensions = $extensions; + } + + /** + * {@inheritDoc} + */ + public function getAutoloadExtensions() + { + return $this->autoloadExtensions; + } + /** * Sets the list of paths added to PHP's include path. * diff --git a/src/Composer/Package/PackageInterface.php b/src/Composer/Package/PackageInterface.php index a51274d5b313..4a3326c8022b 100644 --- a/src/Composer/Package/PackageInterface.php +++ b/src/Composer/Package/PackageInterface.php @@ -278,6 +278,13 @@ public function getAutoload(); */ public function getDevAutoload(); + /** + * Returns an array of autoloading extensions + * + * @return array + */ + public function getAutoloadExtensions(); + /** * Returns a list of directories which should get added to PHP's * include path. From d00a8cab5f810ebee8dfc4c876ac523ce677599c Mon Sep 17 00:00:00 2001 From: Konrad Gibaszewski Date: Fri, 12 Jun 2015 15:46:46 +0200 Subject: [PATCH 03/10] Adds GitArchiver --- src/Composer/Factory.php | 1 + .../Package/Archiver/ArchiveManager.php | 2 +- src/Composer/Package/Archiver/GitArchiver.php | 67 +++++++++++++++++++ 3 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 src/Composer/Package/Archiver/GitArchiver.php diff --git a/src/Composer/Factory.php b/src/Composer/Factory.php index 6f9a5da365ea..141113e17778 100644 --- a/src/Composer/Factory.php +++ b/src/Composer/Factory.php @@ -423,6 +423,7 @@ public function createArchiveManager(Config $config, Downloader\DownloadManager $am = new Archiver\ArchiveManager($dm); $am->addArchiver(new Archiver\PharArchiver); + $am->addArchiver(new Archiver\GitArchiver); return $am; } diff --git a/src/Composer/Package/Archiver/ArchiveManager.php b/src/Composer/Package/Archiver/ArchiveManager.php index d600a7a753b7..9d721ca09944 100644 --- a/src/Composer/Package/Archiver/ArchiveManager.php +++ b/src/Composer/Package/Archiver/ArchiveManager.php @@ -26,7 +26,7 @@ class ArchiveManager { protected $downloadManager; - protected $archivers = array(); + protected $archivers = []; /** * @var bool diff --git a/src/Composer/Package/Archiver/GitArchiver.php b/src/Composer/Package/Archiver/GitArchiver.php new file mode 100644 index 000000000000..31fdbe67df84 --- /dev/null +++ b/src/Composer/Package/Archiver/GitArchiver.php @@ -0,0 +1,67 @@ + + * Jordi Boggiano + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Composer\Package\Archiver; + +use Composer\Util\Git as GitUtil; +//use Composer\Util\ProcessExecutor; +//use Composer\IO\IOInterface; +//use Composer\Util\Filesystem; +//use Composer\Config; + +/** + * @author Till Klampaeckel + * @author Nils Adermann + * @author Matthieu Moquet + * @author Konrad Gibaszewski + */ +class GitArchiver implements ArchiverInterface { + + protected static $formats = [ + 'zip' => \Phar::ZIP, + 'tar' => \Phar::TAR, + 'tar.gz' => \Phar::GZ, + 'bz2' => \Phar::BZ2, + ]; + + /** + * {@inheritdoc} + */ + public function archive($sources, $target, $format, array $excludes = []) { + + $sources = realpath($sources); + + GitUtil::cleanEnv(); + + try { + $tag = shell_exec("cd $sources && git describe"); + shell_exec("cd $sources && git archive -o $target $tag"); + return $target; + } catch (\UnexpectedValueException $e) { + $message = sprintf("Could not create archive '%s' from '%s': %s", + $target, + $sources, + $e->getMessage() + ); + + throw new \RuntimeException($message, $e->getCode(), $e); + } + } + + /** + * {@inheritdoc} + */ + public function supports($format, $sourceType) { + return isset(static::$formats[$format]); + } + +} From d35849ce61231fe52679da30c366e1351dd410a2 Mon Sep 17 00:00:00 2001 From: Jan Kunzmann Date: Mon, 15 Jun 2015 15:41:25 +0200 Subject: [PATCH 04/10] Improved composer console output if a repository is about to be deleted --- src/Composer/Downloader/DownloadManager.php | 2 ++ src/Composer/Installer/LibraryInstaller.php | 1 + src/Composer/Repository/Vcs/GitDriver.php | 1 + 3 files changed, 4 insertions(+) diff --git a/src/Composer/Downloader/DownloadManager.php b/src/Composer/Downloader/DownloadManager.php index 5c09807259ec..377bbd114e3c 100644 --- a/src/Composer/Downloader/DownloadManager.php +++ b/src/Composer/Downloader/DownloadManager.php @@ -244,6 +244,7 @@ public function update(PackageInterface $initial, PackageInterface $target, $tar // upgrading from a dist stable package to a dev package, force source reinstall if ($target->isDev() && 'dist' === $installationSource) { + $this->io->writeError(" Installation source changed from stable to dev, wiping $targetDir"); $downloader->remove($initial, $targetDir); $this->download($target, $targetDir); @@ -254,6 +255,7 @@ public function update(PackageInterface $initial, PackageInterface $target, $tar $target->setInstallationSource($installationSource); $downloader->update($initial, $target, $targetDir); } else { + $this->io->writeError(" Installation type changed from $initialType to $targetType, wiping $targetDir"); $downloader->remove($initial, $targetDir); $this->download($target, $targetDir, 'source' === $installationSource); } diff --git a/src/Composer/Installer/LibraryInstaller.php b/src/Composer/Installer/LibraryInstaller.php index aa2d4606214a..7b6e228dc2ba 100644 --- a/src/Composer/Installer/LibraryInstaller.php +++ b/src/Composer/Installer/LibraryInstaller.php @@ -166,6 +166,7 @@ protected function updateCode(PackageInterface $initial, PackageInterface $targe if (substr($initialDownloadPath, 0, strlen($targetDownloadPath)) === $targetDownloadPath || substr($targetDownloadPath, 0, strlen($initialDownloadPath)) === $initialDownloadPath ) { + $this->io->writeError(" Installation download path changed, wiping library directory"); $this->removeCode($initial); $this->installCode($target); diff --git a/src/Composer/Repository/Vcs/GitDriver.php b/src/Composer/Repository/Vcs/GitDriver.php index e9730412ddb6..a7d6803d31b7 100644 --- a/src/Composer/Repository/Vcs/GitDriver.php +++ b/src/Composer/Repository/Vcs/GitDriver.php @@ -69,6 +69,7 @@ public function initialize() $this->io->writeError('Failed to update '.$this->url.', package information from this repository may be outdated ('.$e->getMessage().')'); } } else { + $this->io->writeError(" Seems not to be a valid git repo, or can't rev-parse; wiping and cloning."); // clean up directory and do a fresh clone into it $fs->removeDirectory($this->repoDir); From 9807c969492d1e6972e2c5fa9f32b211c47291a8 Mon Sep 17 00:00:00 2001 From: Jan Kunzmann Date: Mon, 15 Jun 2015 17:43:37 +0200 Subject: [PATCH 05/10] Drop wild magic version guessing --- src/Composer/Package/Version/VersionParser.php | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/Composer/Package/Version/VersionParser.php b/src/Composer/Package/Version/VersionParser.php index b5a32a448847..bbb4bbf3aa42 100644 --- a/src/Composer/Package/Version/VersionParser.php +++ b/src/Composer/Package/Version/VersionParser.php @@ -124,15 +124,15 @@ public function normalize($version, $fullVersion = null) .(!empty($matches[3]) ? $matches[3] : '.0') .(!empty($matches[4]) ? $matches[4] : '.0'); $index = 5; - } elseif (preg_match('{^v?(\d{4}(?:[.:-]?\d{2}){1,6}(?:[.:-]?\d{1,3})?)'.self::$modifierRegex.'$}i', $version, $matches)) { // match date-based versioning - $version = preg_replace('{\D}', '-', $matches[1]); - $index = 2; - } elseif (preg_match('{^v?(\d{4,})(\.\d+)?(\.\d+)?(\.\d+)?'.self::$modifierRegex.'$}i', $version, $matches)) { - $version = $matches[1] - .(!empty($matches[2]) ? $matches[2] : '.0') - .(!empty($matches[3]) ? $matches[3] : '.0') - .(!empty($matches[4]) ? $matches[4] : '.0'); - $index = 5; +// } elseif (preg_match('{^v?(\d{4}(?:[.:-]?\d{2}){1,6}(?:[.:-]?\d{1,3})?)'.self::$modifierRegex.'$}i', $version, $matches)) { // match date-based versioning +// $version = preg_replace('{\D}', '-', $matches[1]); +// $index = 2; +// } elseif (preg_match('{^v?(\d{4,})(\.\d+)?(\.\d+)?(\.\d+)?'.self::$modifierRegex.'$}i', $version, $matches)) { +// $version = $matches[1] +// .(!empty($matches[2]) ? $matches[2] : '.0') +// .(!empty($matches[3]) ? $matches[3] : '.0') +// .(!empty($matches[4]) ? $matches[4] : '.0'); +// $index = 5; } // add version modifiers if a version was matched From 0b0ded6a87e5f872d0d5047751146ee2afd188ee Mon Sep 17 00:00:00 2001 From: Jan Kunzmann Date: Mon, 15 Jun 2015 18:31:36 +0200 Subject: [PATCH 06/10] Make self-update unusable --- src/Composer/Command/SelfUpdateCommand.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Composer/Command/SelfUpdateCommand.php b/src/Composer/Command/SelfUpdateCommand.php index e4e96e8f4ea6..ec1090022eb1 100644 --- a/src/Composer/Command/SelfUpdateCommand.php +++ b/src/Composer/Command/SelfUpdateCommand.php @@ -38,7 +38,7 @@ protected function configure() $this ->setName('self-update') ->setAliases(array('selfupdate')) - ->setDescription('Updates composer.phar to the latest version.') + ->setDescription('Updates composer.phar to the latest version. Do not use in erasys environment!') ->setDefinition(array( new InputOption('rollback', 'r', InputOption::VALUE_NONE, 'Revert to an older installation of composer'), new InputOption('clean-backups', null, InputOption::VALUE_NONE, 'Delete old backups during an update. This makes the current version of composer the only backup available after the update'), @@ -58,6 +58,9 @@ protected function configure() protected function execute(InputInterface $input, OutputInterface $output) { + $this->getIO()->writeError('Composer should not be updated with this command in erasys environment.'); + return; + $baseUrl = (extension_loaded('openssl') ? 'https' : 'http') . '://' . self::HOMEPAGE; $config = Factory::createConfig(); $remoteFilesystem = new RemoteFilesystem($this->getIO(), $config); From 8c29eea7881b522c010dc156511eb99355082631 Mon Sep 17 00:00:00 2001 From: Konrad Gibaszewski Date: Tue, 16 Jun 2015 14:29:14 +0200 Subject: [PATCH 07/10] Adds GitArchiver, Bzip2Downloader, fixes TarDownloader Details: Bzip2Downloader - Intermediate file is always .tar, removes intermediate tar file after download completion Bzip2Downloader - Supports tar.z2 files (requires PHP 5.5.24+) TarDownloader - Adds exception handling GitArchiver - refactored to use only tar and tar.bz2 GitArchiver - while trying to discover a tag consider both annotated and unannotated tags --- src/Composer/Downloader/Bzip2Downloader.php | 51 +++++++++++++++++++ src/Composer/Downloader/TarDownloader.php | 38 ++++++++++---- src/Composer/Factory.php | 1 + src/Composer/Package/Archiver/GitArchiver.php | 13 ++--- 4 files changed, 83 insertions(+), 20 deletions(-) create mode 100644 src/Composer/Downloader/Bzip2Downloader.php diff --git a/src/Composer/Downloader/Bzip2Downloader.php b/src/Composer/Downloader/Bzip2Downloader.php new file mode 100644 index 000000000000..d240c6da80e5 --- /dev/null +++ b/src/Composer/Downloader/Bzip2Downloader.php @@ -0,0 +1,51 @@ + + * Jordi Boggiano + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Composer\Downloader; + +/** + * Downloader for tar.bz2 files + * + * @author Konrad Gibaszewski + */ +class Bzip2Downloader extends ArchiveDownloader { + + /** + * {@inheritDoc} + */ + protected function extract($file, $path) { + + try { + // decompress from bz2 to tar + $archive = new \PharData($file); + $archive->decompress(); + + // Unpack from tar + $file = substr($file, 0, -4) . '.tar'; + $archive = new \PharData($file); + $archive->extractTo($path, null, true); + + // Remove intermediate tar file + unlink($file); + + } catch (\UnexpectedValueException $e) { + $message = sprintf("Could not extract archive '%s': %s", + $file, + $e->getMessage() + ); + + throw new \RuntimeException($message, $e->getCode(), $e); + } + + } + +} diff --git a/src/Composer/Downloader/TarDownloader.php b/src/Composer/Downloader/TarDownloader.php index 34c43da5fdc6..c3f46e44ab63 100644 --- a/src/Composer/Downloader/TarDownloader.php +++ b/src/Composer/Downloader/TarDownloader.php @@ -13,19 +13,35 @@ namespace Composer\Downloader; /** - * Downloader for tar files: tar, tar.gz or tar.bz2 + * Class TarDownloader + * + * Downloader for uncompressed tar files * * @author Kirill chEbba Chebunin + * @author Konrad Gibaszewski + * + * @package Composer\Downloader */ -class TarDownloader extends ArchiveDownloader -{ - /** - * {@inheritDoc} - */ - protected function extract($file, $path) - { - // Can throw an UnexpectedValueException - $archive = new \PharData($file); - $archive->extractTo($path, null, true); +class TarDownloader extends ArchiveDownloader { + + /** + * {@inheritDoc} + */ + protected function extract($file, $path) { + + try { + // Unpack from tar + $archive = new \PharData($file); + $archive->extractTo($path, null, true); + + } catch (\UnexpectedValueException $e) { + $message = sprintf("Could not unpack from tar archive '%s': %s", + $file, + $e->getMessage() + ); + + throw new \RuntimeException($message, $e->getCode(), $e); } + } + } diff --git a/src/Composer/Factory.php b/src/Composer/Factory.php index 141113e17778..f85708790d12 100644 --- a/src/Composer/Factory.php +++ b/src/Composer/Factory.php @@ -400,6 +400,7 @@ public function createDownloadManager(IOInterface $io, Config $config, EventDisp $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('tar.bz2', new Downloader\Bzip2Downloader($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)); diff --git a/src/Composer/Package/Archiver/GitArchiver.php b/src/Composer/Package/Archiver/GitArchiver.php index 31fdbe67df84..4de3a965b8e3 100644 --- a/src/Composer/Package/Archiver/GitArchiver.php +++ b/src/Composer/Package/Archiver/GitArchiver.php @@ -13,10 +13,6 @@ namespace Composer\Package\Archiver; use Composer\Util\Git as GitUtil; -//use Composer\Util\ProcessExecutor; -//use Composer\IO\IOInterface; -//use Composer\Util\Filesystem; -//use Composer\Config; /** * @author Till Klampaeckel @@ -27,10 +23,9 @@ class GitArchiver implements ArchiverInterface { protected static $formats = [ - 'zip' => \Phar::ZIP, - 'tar' => \Phar::TAR, - 'tar.gz' => \Phar::GZ, - 'bz2' => \Phar::BZ2, + 'tar' => \Phar::TAR, + 'tar.gz' => \Phar::GZ, + 'tar.bz2' => \Phar::BZ2, ]; /** @@ -43,7 +38,7 @@ public function archive($sources, $target, $format, array $excludes = []) { GitUtil::cleanEnv(); try { - $tag = shell_exec("cd $sources && git describe"); + $tag = shell_exec("cd $sources && git describe --tags"); shell_exec("cd $sources && git archive -o $target $tag"); return $target; } catch (\UnexpectedValueException $e) { From 3df8a29c2b51a7fe4ce65e9b75b977fb1951e38f Mon Sep 17 00:00:00 2001 From: Lukas Koell Date: Thu, 18 Jun 2015 13:09:22 +0200 Subject: [PATCH 08/10] Bzip2Downloader use command line tar instead of \PharData --- src/Composer/Downloader/Bzip2Downloader.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/Composer/Downloader/Bzip2Downloader.php b/src/Composer/Downloader/Bzip2Downloader.php index d240c6da80e5..d7bd014885b6 100644 --- a/src/Composer/Downloader/Bzip2Downloader.php +++ b/src/Composer/Downloader/Bzip2Downloader.php @@ -30,12 +30,11 @@ protected function extract($file, $path) { $archive->decompress(); // Unpack from tar - $file = substr($file, 0, -4) . '.tar'; - $archive = new \PharData($file); - $archive->extractTo($path, null, true); + $tarFile = substr($file, 0, -4) . '.tar'; + exec('tar xf -C ' . $path . ' ' . $tarFile); // Remove intermediate tar file - unlink($file); + unlink($tarFile); } catch (\UnexpectedValueException $e) { $message = sprintf("Could not extract archive '%s': %s", From da8434e027c2634f98645eec2eba476150b44b3b Mon Sep 17 00:00:00 2001 From: Lukas Koell Date: Thu, 18 Jun 2015 13:18:14 +0200 Subject: [PATCH 09/10] Bzip2Downloader: only use command line. FU \PharData!!! --- src/Composer/Downloader/Bzip2Downloader.php | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/src/Composer/Downloader/Bzip2Downloader.php b/src/Composer/Downloader/Bzip2Downloader.php index d7bd014885b6..507021b78c14 100644 --- a/src/Composer/Downloader/Bzip2Downloader.php +++ b/src/Composer/Downloader/Bzip2Downloader.php @@ -23,19 +23,8 @@ class Bzip2Downloader extends ArchiveDownloader { * {@inheritDoc} */ protected function extract($file, $path) { - try { - // decompress from bz2 to tar - $archive = new \PharData($file); - $archive->decompress(); - - // Unpack from tar - $tarFile = substr($file, 0, -4) . '.tar'; - exec('tar xf -C ' . $path . ' ' . $tarFile); - - // Remove intermediate tar file - unlink($tarFile); - + exec('tar xfj -C ' . $path . ' ' . $file); } catch (\UnexpectedValueException $e) { $message = sprintf("Could not extract archive '%s': %s", $file, From 57c35460b8d9249bd15a2a6f6278b58d833e2f4f Mon Sep 17 00:00:00 2001 From: Lukas Koell Date: Thu, 18 Jun 2015 13:37:59 +0200 Subject: [PATCH 10/10] correct order of parameters when calling tar. sry --- src/Composer/Downloader/Bzip2Downloader.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Composer/Downloader/Bzip2Downloader.php b/src/Composer/Downloader/Bzip2Downloader.php index 507021b78c14..c9b98304e0aa 100644 --- a/src/Composer/Downloader/Bzip2Downloader.php +++ b/src/Composer/Downloader/Bzip2Downloader.php @@ -24,7 +24,7 @@ class Bzip2Downloader extends ArchiveDownloader { */ protected function extract($file, $path) { try { - exec('tar xfj -C ' . $path . ' ' . $file); + exec('tar xfj ' . ' ' . $file . ' -C ' . $path); } catch (\UnexpectedValueException $e) { $message = sprintf("Could not extract archive '%s': %s", $file,