From 5896f283be3fdf588ee94f90d0953c5c728679a1 Mon Sep 17 00:00:00 2001 From: "Matthew J. Sahagian" Date: Fri, 21 Nov 2014 13:16:19 -0800 Subject: [PATCH 01/73] Allow for disabling autoloader on Installer --- src/Composer/Installer.php | 34 ++++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/src/Composer/Installer.php b/src/Composer/Installer.php index b76155a5a..3654cddd3 100644 --- a/src/Composer/Installer.php +++ b/src/Composer/Installer.php @@ -105,6 +105,7 @@ class Installer protected $dryRun = false; protected $verbose = false; protected $update = false; + protected $runAutoloader = true; protected $runScripts = true; protected $ignorePlatformReqs = false; /** @@ -311,16 +312,18 @@ class Installer } } - // write autoloader - if ($this->optimizeAutoloader) { - $this->io->write('Generating optimized autoload files'); - } else { - $this->io->write('Generating autoload files'); + if ($this->runAutoloader) { + // write autoloader + if ($this->optimizeAutoloader) { + $this->io->write('Generating optimized autoload files'); + } else { + $this->io->write('Generating autoload files'); + } + + $this->autoloadGenerator->setDevMode($this->devMode); + $this->autoloadGenerator->dump($this->config, $localRepo, $this->package, $this->installationManager, 'composer', $this->optimizeAutoloader); } - $this->autoloadGenerator->setDevMode($this->devMode); - $this->autoloadGenerator->dump($this->config, $localRepo, $this->package, $this->installationManager, 'composer', $this->optimizeAutoloader); - if ($this->runScripts) { // dispatch post event $eventName = $this->update ? ScriptEvents::POST_UPDATE_CMD : ScriptEvents::POST_INSTALL_CMD; @@ -1152,6 +1155,21 @@ class Installer return $this; } + + /** + * set whether to run autoloader or not + * + * @param boolean $runAutoloader + * @return Installer + */ + public function setRunAutoloader($runAutoloader = true) + { + $this->runAutoloader = (boolean) $runAutoloader; + + return $this; + } + + /** * set whether to run scripts or not * From 198ac7bc5b52460c8bab140226a6273327565d3b Mon Sep 17 00:00:00 2001 From: "Matthew J. Sahagian" Date: Fri, 21 Nov 2014 13:20:48 -0800 Subject: [PATCH 02/73] Expose no autoloader option to install command --- src/Composer/Command/InstallCommand.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Composer/Command/InstallCommand.php b/src/Composer/Command/InstallCommand.php index 669c03582..c1de25ce7 100644 --- a/src/Composer/Command/InstallCommand.php +++ b/src/Composer/Command/InstallCommand.php @@ -41,6 +41,7 @@ class InstallCommand extends Command new InputOption('no-dev', null, InputOption::VALUE_NONE, 'Disables installation of require-dev packages.'), new InputOption('no-plugins', null, InputOption::VALUE_NONE, 'Disables all plugins.'), new InputOption('no-custom-installers', null, InputOption::VALUE_NONE, 'DEPRECATED: Use no-plugins instead.'), + new InputOption('no-autoloader', null, InputOption::VALUE_NONE, 'Skips autoloader generation'), new InputOption('no-scripts', null, InputOption::VALUE_NONE, 'Skips the execution of all scripts defined in composer.json file.'), new InputOption('no-progress', null, InputOption::VALUE_NONE, 'Do not output download progress.'), new InputOption('verbose', 'v|vv|vvv', InputOption::VALUE_NONE, 'Shows more details including new commits pulled in when updating packages.'), @@ -113,6 +114,7 @@ EOT ->setPreferSource($preferSource) ->setPreferDist($preferDist) ->setDevMode(!$input->getOption('no-dev')) + ->setRunAutoloader(!$input->getOption('no-autoloader')) ->setRunScripts(!$input->getOption('no-scripts')) ->setOptimizeAutoloader($optimize) ->setIgnorePlatformRequirements($input->getOption('ignore-platform-reqs')) From 55b2afe9ad5da07277caa1061f06e47f70d24328 Mon Sep 17 00:00:00 2001 From: "Matthew J. Sahagian" Date: Fri, 21 Nov 2014 13:22:17 -0800 Subject: [PATCH 03/73] Expose no autoloader option to update command --- src/Composer/Command/UpdateCommand.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Composer/Command/UpdateCommand.php b/src/Composer/Command/UpdateCommand.php index ebfd4cb2a..bebde6ed1 100644 --- a/src/Composer/Command/UpdateCommand.php +++ b/src/Composer/Command/UpdateCommand.php @@ -41,6 +41,7 @@ class UpdateCommand extends Command new InputOption('lock', null, InputOption::VALUE_NONE, 'Only updates the lock file hash to suppress warning about the lock file being out of date.'), new InputOption('no-plugins', null, InputOption::VALUE_NONE, 'Disables all plugins.'), new InputOption('no-custom-installers', null, InputOption::VALUE_NONE, 'DEPRECATED: Use no-plugins instead.'), + new InputOption('no-autoloader', null, InputOption::VALUE_NONE, 'Skips autoloader generation'), new InputOption('no-scripts', null, InputOption::VALUE_NONE, 'Skips the execution of all scripts defined in composer.json file.'), new InputOption('no-progress', null, InputOption::VALUE_NONE, 'Do not output download progress.'), new InputOption('with-dependencies', null, InputOption::VALUE_NONE, 'Add also all dependencies of whitelisted packages to the whitelist.'), @@ -115,6 +116,7 @@ EOT ->setPreferSource($preferSource) ->setPreferDist($preferDist) ->setDevMode(!$input->getOption('no-dev')) + ->setRunAutoloader(!$input->getOption('no-autoloader')) ->setRunScripts(!$input->getOption('no-scripts')) ->setOptimizeAutoloader($optimize) ->setUpdate(true) From 14fe882b4459252ffa09d3944575a21b659c4e42 Mon Sep 17 00:00:00 2001 From: "Matthew J. Sahagian" Date: Fri, 21 Nov 2014 13:28:44 -0800 Subject: [PATCH 04/73] Added no-autoloder option to install and update --- doc/03-cli.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/03-cli.md b/doc/03-cli.md index 7fcafc2d6..0607a45b3 100644 --- a/doc/03-cli.md +++ b/doc/03-cli.md @@ -88,6 +88,7 @@ resolution. installation and show you what would happen. * **--dev:** Install packages listed in `require-dev` (this is the default behavior). * **--no-dev:** Skip installing packages listed in `require-dev`. +* **--no-autoloader:** Skips autoloader generation. * **--no-scripts:** Skips execution of scripts defined in `composer.json`. * **--no-plugins:** Disables plugins. * **--no-progress:** Removes the progress display that can mess with some @@ -130,6 +131,7 @@ php composer.phar update vendor/* * **--dry-run:** Simulate the command without actually doing anything. * **--dev:** Install packages listed in `require-dev` (this is the default behavior). * **--no-dev:** Skip installing packages listed in `require-dev`. +* **--no-autoloader:** Skips autoloader generation. * **--no-scripts:** Skips execution of scripts defined in `composer.json`. * **--no-plugins:** Disables plugins. * **--no-progress:** Removes the progress display that can mess with some From acf363876263e0eca620a77d2cfa5342f44e6217 Mon Sep 17 00:00:00 2001 From: Mads Kristensen Date: Fri, 28 Nov 2014 14:02:05 -0800 Subject: [PATCH 05/73] Converted to draft v4 schema Editors such as Visual Studio leverages JSON Schema draft v4, but this schema was authored in the old draft v3. With just a few minor changes, the schema is now draft v4. * Added `$schema` property to state it is using schema draft v4 * Changed `required` properties to arrays instead of strings. This is the only real difference from v3 to v4 in this schema --- res/composer-schema.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/res/composer-schema.json b/res/composer-schema.json index 95cd199e3..49ec0fa7a 100644 --- a/res/composer-schema.json +++ b/res/composer-schema.json @@ -1,12 +1,13 @@ { + "$schema": "http://json-schema.org/draft-04/schema#", "name": "Package", "type": "object", "additionalProperties": false, + "required": [ "name", "description" ], "properties": { "name": { "type": "string", - "description": "Package name, including 'vendor-name/' prefix.", - "required": true + "description": "Package name, including 'vendor-name/' prefix." }, "type": { "description": "Package type, either 'library' for common packages, 'composer-plugin' for plugins, 'metapackage' for empty packages, or a custom type ([a-z0-9-]+) defined by whatever project this package applies to.", @@ -18,8 +19,7 @@ }, "description": { "type": "string", - "description": "Short package description.", - "required": true + "description": "Short package description." }, "keywords": { "type": "array", @@ -51,11 +51,11 @@ "items": { "type": "object", "additionalProperties": false, + "required": [ "name"], "properties": { "name": { "type": "string", - "description": "Full name of the author.", - "required": true + "description": "Full name of the author." }, "email": { "type": "string", From 0c87048fedea9de8c64530019eb81dd40882f278 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Mon, 15 Dec 2014 20:21:53 +0000 Subject: [PATCH 06/73] Also detect full temp dir, fixes #3559 --- src/Composer/Console/Application.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Composer/Console/Application.php b/src/Composer/Console/Application.php index 8e49eedb5..1c8246f88 100644 --- a/src/Composer/Console/Application.php +++ b/src/Composer/Console/Application.php @@ -184,6 +184,7 @@ class Application extends BaseApplication $minSpaceFree = 1024*1024; if ((($df = @disk_free_space($dir = $config->get('home'))) !== false && $df < $minSpaceFree) || (($df = @disk_free_space($dir = $config->get('vendor-dir'))) !== false && $df < $minSpaceFree) + || (($df = @disk_free_space($dir = sys_get_temp_dir())) !== false && $df < $minSpaceFree) ) { $output->writeln('The disk hosting '.$dir.' is full, this may be the cause of the following exception'); } From 2b16a73659b12c35b2ab623b69688295d95ff2de Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Mon, 15 Dec 2014 20:34:23 +0000 Subject: [PATCH 07/73] Load plugins before purging packages, fixes #3557 --- src/Composer/Factory.php | 11 ++++++----- src/Composer/Installer/PluginInstaller.php | 4 ++-- src/Composer/Plugin/PluginManager.php | 7 +++++-- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/src/Composer/Factory.php b/src/Composer/Factory.php index 0eb428657..d42c5e7dd 100644 --- a/src/Composer/Factory.php +++ b/src/Composer/Factory.php @@ -283,11 +283,6 @@ class Factory // add installers to the manager (must happen after download manager is created since they read it out of $composer) $this->createDefaultInstallers($im, $composer, $io); - // purge packages if they have been deleted on the filesystem - if ($rm->getLocalRepository()) { - $this->purgePackages($rm->getLocalRepository(), $im); - } - if ($fullLoad) { $globalComposer = $this->createGlobalComposer($io, $config, $disablePlugins); $pm = $this->createPluginManager($io, $composer, $globalComposer); @@ -296,6 +291,12 @@ class Factory if (!$disablePlugins) { $pm->loadInstalledPlugins(); } + + // once we have plugins and custom installers we can + // purge packages from local repos if they have been deleted on the filesystem + if ($rm->getLocalRepository()) { + $this->purgePackages($rm->getLocalRepository(), $im); + } } // init locker if possible diff --git a/src/Composer/Installer/PluginInstaller.php b/src/Composer/Installer/PluginInstaller.php index b5469ccc6..ddb8e5bdd 100644 --- a/src/Composer/Installer/PluginInstaller.php +++ b/src/Composer/Installer/PluginInstaller.php @@ -61,7 +61,7 @@ class PluginInstaller extends LibraryInstaller } parent::install($repo, $package); - $this->composer->getPluginManager()->registerPackage($package); + $this->composer->getPluginManager()->registerPackage($package, true); } /** @@ -75,6 +75,6 @@ class PluginInstaller extends LibraryInstaller } parent::update($repo, $initial, $target); - $this->composer->getPluginManager()->registerPackage($target); + $this->composer->getPluginManager()->registerPackage($target, true); } } diff --git a/src/Composer/Plugin/PluginManager.php b/src/Composer/Plugin/PluginManager.php index d7c2d8657..9e4c12391 100644 --- a/src/Composer/Plugin/PluginManager.php +++ b/src/Composer/Plugin/PluginManager.php @@ -190,10 +190,11 @@ class PluginManager * instead for BC * * @param PackageInterface $package + * @param bool $failOnMissingClasses By default this silently skips plugins that can not be found, but if set to true it fails with an exception * * @throws \UnexpectedValueException */ - public function registerPackage(PackageInterface $package) + public function registerPackage(PackageInterface $package, $failOnMissingClasses = false) { $oldInstallerPlugin = ($package->getType() === 'composer-installer'); @@ -242,10 +243,12 @@ class PluginManager if ($oldInstallerPlugin) { $installer = new $class($this->io, $this->composer); $this->composer->getInstallationManager()->addInstaller($installer); - } else { + } elseif (class_exists($class)) { $plugin = new $class(); $this->addPlugin($plugin); $this->registeredPlugins[] = $package->getName(); + } elseif ($failOnMissingClasses) { + throw new \UnexpectedValueException('Plugin '.$package->getName().' could not be initialized, class not found: '.$class); } } } From 331bda235c810787be90219f7625cc8a548aa92e Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Tue, 16 Dec 2014 11:12:13 +0000 Subject: [PATCH 08/73] Fix activation of global plugins, fixes #3557 --- src/Composer/Config.php | 23 +++++++++++++++++++++-- src/Composer/Factory.php | 24 ++++++++++++++---------- tests/Composer/Test/ConfigTest.php | 15 +++++++++++++++ tests/Composer/Test/Mock/FactoryMock.php | 4 ++-- 4 files changed, 52 insertions(+), 14 deletions(-) diff --git a/src/Composer/Config.php b/src/Composer/Config.php index 176c228eb..4bb2a06c1 100644 --- a/src/Composer/Config.php +++ b/src/Composer/Config.php @@ -55,6 +55,7 @@ class Config ); private $config; + private $baseDir; private $repositories; private $configSource; private $authConfigSource; @@ -63,12 +64,13 @@ class Config /** * @param boolean $useEnvironment Use COMPOSER_ environment variables to replace config settings */ - public function __construct($useEnvironment = true) + public function __construct($useEnvironment = true, $baseDir = null) { // load defaults $this->config = static::$defaultConfig; $this->repositories = static::$defaultRepositories; $this->useEnvironment = (bool) $useEnvironment; + $this->baseDir = $baseDir; } public function setConfigSource(ConfigSourceInterface $source) @@ -167,7 +169,7 @@ class Config $val = rtrim($this->process($this->getComposerEnv($env) ?: $this->config[$key]), '/\\'); $val = preg_replace('#^(\$HOME|~)(/|$)#', rtrim(getenv('HOME') ?: getenv('USERPROFILE'), '/\\') . '/', $val); - return $val; + return $this->realpath($val); case 'cache-ttl': return (int) $this->config[$key]; @@ -294,6 +296,23 @@ class Config }, $value); } + /** + * Turns relative paths in absolute paths without realpath() + * + * Since the dirs might not exist yet we can not call realpath or it will fail. + * + * @param string $path + * @return string + */ + private function realpath($path) + { + if (substr($path, 0, 1) === '/' || substr($path, 1, 1) === ':') { + return $path; + } + + return $this->baseDir . '/' . $path; + } + /** * Reads the value of a Composer environment variable * diff --git a/src/Composer/Factory.php b/src/Composer/Factory.php index d42c5e7dd..f2aa27e22 100644 --- a/src/Composer/Factory.php +++ b/src/Composer/Factory.php @@ -89,8 +89,10 @@ class Factory * @param IOInterface|null $io * @return Config */ - public static function createConfig(IOInterface $io = null) + public static function createConfig(IOInterface $io = null, $cwd = null) { + $cwd = $cwd ?: getcwd(); + // determine home and cache dirs $home = self::getHomeDir(); $cacheDir = self::getCacheDir($home); @@ -107,7 +109,7 @@ class Factory } } - $config = new Config(); + $config = new Config(true, $cwd); // add dirs to the config $config->merge(array('config' => array('home' => $home, 'cache-dir' => $cacheDir))); @@ -192,8 +194,10 @@ class Factory * @throws \UnexpectedValueException * @return Composer */ - public function createComposer(IOInterface $io, $localConfig = null, $disablePlugins = false, $fullLoad = true) + public function createComposer(IOInterface $io, $localConfig = null, $disablePlugins = false, $cwd = null, $fullLoad = true) { + $cwd = $cwd ?: getcwd(); + // load Composer configuration if (null === $localConfig) { $localConfig = static::getComposerFile(); @@ -205,7 +209,7 @@ class Factory if (!$file->exists()) { if ($localConfig === './composer.json' || $localConfig === 'composer.json') { - $message = 'Composer could not find a composer.json file in '.getcwd(); + $message = 'Composer could not find a composer.json file in '.$cwd; } else { $message = 'Composer could not find the config file: '.$localConfig; } @@ -218,7 +222,7 @@ class Factory } // Load config and override with local config/auth config - $config = static::createConfig($io); + $config = static::createConfig($io, $cwd); $config->merge($localConfig); if (isset($composerFile)) { if ($io && $io->isDebug()) { @@ -348,18 +352,18 @@ class Factory */ protected function createGlobalComposer(IOInterface $io, Config $config, $disablePlugins) { - $oldCwd = getcwd(); - if (realpath($config->get('home')) === realpath($oldCwd)) { + if (realpath($config->get('home')) === getcwd()) { return; } $composer = null; try { - chdir($config->get('home')); - $composer = self::createComposer($io, null, $disablePlugins, false); + $composer = self::createComposer($io, $config->get('home') . '/composer.json', $disablePlugins, $config->get('home'), false); } catch (\Exception $e) { + if ($io->isDebug()) { + $io->write('Failed to initialize global composer: '.$e->getMessage()); + } } - @chdir($oldCwd); return $composer; } diff --git a/tests/Composer/Test/ConfigTest.php b/tests/Composer/Test/ConfigTest.php index 521fb634b..04160b63f 100644 --- a/tests/Composer/Test/ConfigTest.php +++ b/tests/Composer/Test/ConfigTest.php @@ -121,6 +121,21 @@ class ConfigTest extends \PHPUnit_Framework_TestCase $this->assertEquals($home.'/foo', $config->get('cache-dir')); } + public function testRealpathReplacement() + { + $config = new Config(false, '/foo/bar'); + $config->merge(array('config' => array( + 'bin-dir' => '$HOME/foo', + 'cache-dir' => '/baz/', + 'vendor-dir' => 'vendor' + ))); + + $home = rtrim(getenv('HOME') ?: getenv('USERPROFILE'), '\\/'); + $this->assertEquals('/foo/bar/vendor', $config->get('vendor-dir')); + $this->assertEquals($home.'/foo', $config->get('bin-dir')); + $this->assertEquals('/baz', $config->get('cache-dir')); + } + public function testOverrideGithubProtocols() { $config = new Config(false); diff --git a/tests/Composer/Test/Mock/FactoryMock.php b/tests/Composer/Test/Mock/FactoryMock.php index ccbda8040..52c3fbf2e 100644 --- a/tests/Composer/Test/Mock/FactoryMock.php +++ b/tests/Composer/Test/Mock/FactoryMock.php @@ -22,9 +22,9 @@ use Composer\IO\IOInterface; class FactoryMock extends Factory { - public static function createConfig(IOInterface $io = null) + public static function createConfig(IOInterface $io = null, $cwd = null) { - $config = new Config(); + $config = new Config(true, $cwd); $config->merge(array( 'config' => array('home' => sys_get_temp_dir().'/composer-test'), From c54d6f93e3c5838092363447498ecb366e1e60a2 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Tue, 16 Dec 2014 14:28:51 +0000 Subject: [PATCH 09/73] Add --absolute to resolve absolute paths in config command, otherwise set default back to relative --- doc/03-cli.md | 14 ++++++++------ src/Composer/Command/ConfigCommand.php | 3 ++- src/Composer/Config.php | 6 ++++-- 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/doc/03-cli.md b/doc/03-cli.md index 26e70f54a..9fc3d552a 100644 --- a/doc/03-cli.md +++ b/doc/03-cli.md @@ -397,16 +397,18 @@ options. ### Options * **--global (-g):** Operate on the global config file located at -`$COMPOSER_HOME/config.json` by default. Without this option, this command -affects the local composer.json file or a file specified by `--file`. + `$COMPOSER_HOME/config.json` by default. Without this option, this command + affects the local composer.json file or a file specified by `--file`. * **--editor (-e):** Open the local composer.json file using in a text editor as -defined by the `EDITOR` env variable. With the `--global` option, this opens -the global config file. + defined by the `EDITOR` env variable. With the `--global` option, this opens + the global config file. * **--unset:** Remove the configuration element named by `setting-key`. * **--list (-l):** Show the list of current config variables. With the `--global` - option this lists the global configuration only. + option this lists the global configuration only. * **--file="..." (-f):** Operate on a specific file instead of composer.json. Note - that this cannot be used in conjunction with the `--global` option. + that this cannot be used in conjunction with the `--global` option. +* **--absolute:** Returns absolute paths when fetching *-dir config values + instead of relative. ### Modifying Repositories diff --git a/src/Composer/Command/ConfigCommand.php b/src/Composer/Command/ConfigCommand.php index a08a6f4a6..832571b3f 100644 --- a/src/Composer/Command/ConfigCommand.php +++ b/src/Composer/Command/ConfigCommand.php @@ -57,6 +57,7 @@ class ConfigCommand extends Command new InputOption('unset', null, InputOption::VALUE_NONE, 'Unset the given setting-key'), new InputOption('list', 'l', InputOption::VALUE_NONE, 'List configuration settings'), new InputOption('file', 'f', InputOption::VALUE_REQUIRED, 'If you want to choose a different composer.json or config.json', 'composer.json'), + new InputOption('absolute', null, InputOption::VALUE_NONE, 'Returns absolute paths when fetching *-dir config values instead of relative'), new InputArgument('setting-key', null, 'Setting key'), new InputArgument('setting-value', InputArgument::IS_ARRAY, 'Setting value'), )) @@ -218,7 +219,7 @@ EOT $value = $data; } elseif (isset($data['config'][$settingKey])) { - $value = $data['config'][$settingKey]; + $value = $this->config->get($settingKey, $input->getOption('absolute') ? 0 : Config::RELATIVE_PATHS); } else { throw new \RuntimeException($settingKey.' is not defined'); } diff --git a/src/Composer/Config.php b/src/Composer/Config.php index 4bb2a06c1..f95b30177 100644 --- a/src/Composer/Config.php +++ b/src/Composer/Config.php @@ -19,6 +19,8 @@ use Composer\Config\ConfigSourceInterface; */ class Config { + const RELATIVE_PATHS = 1; + public static $defaultConfig = array( 'process-timeout' => 300, 'use-include-path' => false, @@ -153,7 +155,7 @@ class Config * @throws \RuntimeException * @return mixed */ - public function get($key) + public function get($key, $flags = 0) { switch ($key) { case 'vendor-dir': @@ -169,7 +171,7 @@ class Config $val = rtrim($this->process($this->getComposerEnv($env) ?: $this->config[$key]), '/\\'); $val = preg_replace('#^(\$HOME|~)(/|$)#', rtrim(getenv('HOME') ?: getenv('USERPROFILE'), '/\\') . '/', $val); - return $this->realpath($val); + return ($flags & self::RELATIVE_PATHS == 1) ? $val : $this->realpath($val); case 'cache-ttl': return (int) $this->config[$key]; From d22070526f4de7e12338e8c4baae2adb6c09e914 Mon Sep 17 00:00:00 2001 From: Christophe Coevoet Date: Tue, 16 Dec 2014 15:52:34 +0100 Subject: [PATCH 10/73] Add the package license for PEAR packages Refs https://github.com/composer/satis/issues/192 --- src/Composer/Repository/PearRepository.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Composer/Repository/PearRepository.php b/src/Composer/Repository/PearRepository.php index 5006c4927..6086df1ed 100644 --- a/src/Composer/Repository/PearRepository.php +++ b/src/Composer/Repository/PearRepository.php @@ -160,6 +160,7 @@ class PearRepository extends ArrayRepository $package = new CompletePackage($composerPackageName, $normalizedVersion, $version); $package->setType('pear-library'); $package->setDescription($packageDefinition->getDescription()); + $package->setLicense(array($packageDefinition->getLicense())); $package->setDistType('file'); $package->setDistUrl($distUrl); $package->setAutoload(array('classmap' => array(''))); From e0291f3a30fe8959884b433c47abfdb99797dd53 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Wed, 17 Dec 2014 15:25:22 +0000 Subject: [PATCH 11/73] Fix parsing of empty git commits, fixes #3565 --- src/Composer/Repository/Vcs/GitDriver.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Composer/Repository/Vcs/GitDriver.php b/src/Composer/Repository/Vcs/GitDriver.php index daa3d81d3..da87e2e7d 100644 --- a/src/Composer/Repository/Vcs/GitDriver.php +++ b/src/Composer/Repository/Vcs/GitDriver.php @@ -202,7 +202,7 @@ class GitDriver extends VcsDriver $this->process->execute('git branch --no-color --no-abbrev -v', $output, $this->repoDir); foreach ($this->process->splitLines($output) as $branch) { if ($branch && !preg_match('{^ *[^/]+/HEAD }', $branch)) { - if (preg_match('{^(?:\* )? *(\S+) *([a-f0-9]+) .*$}', $branch, $match)) { + if (preg_match('{^(?:\* )? *(\S+) *([a-f0-9]+)(?: .*)?$}', $branch, $match)) { $branches[$match[1]] = $match[2]; } } From 60ac971419ba4e8130b401757894b6b5636cf4e6 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Wed, 17 Dec 2014 21:57:27 +0000 Subject: [PATCH 12/73] Fix relative path fetching when a var uses var replacement, fixes #3564 --- src/Composer/Config.php | 22 ++++++++++++++-------- tests/Composer/Test/ConfigTest.php | 14 ++++++++++++++ 2 files changed, 28 insertions(+), 8 deletions(-) diff --git a/src/Composer/Config.php b/src/Composer/Config.php index f95b30177..86e318765 100644 --- a/src/Composer/Config.php +++ b/src/Composer/Config.php @@ -152,6 +152,7 @@ class Config * Returns a setting * * @param string $key + * @param int $flags Options (see class constants) * @throws \RuntimeException * @return mixed */ @@ -168,9 +169,13 @@ class Config // convert foo-bar to COMPOSER_FOO_BAR and check if it exists since it overrides the local config $env = 'COMPOSER_' . strtoupper(strtr($key, '-', '_')); - $val = rtrim($this->process($this->getComposerEnv($env) ?: $this->config[$key]), '/\\'); + $val = rtrim($this->process($this->getComposerEnv($env) ?: $this->config[$key], $flags), '/\\'); $val = preg_replace('#^(\$HOME|~)(/|$)#', rtrim(getenv('HOME') ?: getenv('USERPROFILE'), '/\\') . '/', $val); + if (substr($key, -4) !== '-dir') { + return $val; + } + return ($flags & self::RELATIVE_PATHS == 1) ? $val : $this->realpath($val); case 'cache-ttl': @@ -207,7 +212,7 @@ class Config return (int) $this->config['cache-ttl']; case 'home': - return rtrim($this->process($this->config[$key]), '/\\'); + return rtrim($this->process($this->config[$key], $flags), '/\\'); case 'discard-changes': if ($env = $this->getComposerEnv('COMPOSER_DISCARD_CHANGES')) { @@ -244,17 +249,17 @@ class Config return null; } - return $this->process($this->config[$key]); + return $this->process($this->config[$key], $flags); } } - public function all() + public function all($flags = 0) { $all = array( 'repositories' => $this->getRepositories(), ); foreach (array_keys($this->config) as $key) { - $all['config'][$key] = $this->get($key); + $all['config'][$key] = $this->get($key, $flags); } return $all; @@ -283,9 +288,10 @@ class Config * Replaces {$refs} inside a config string * * @param string $value a config string that can contain {$refs-to-other-config} + * @param int $flags Options (see class constants) * @return string */ - private function process($value) + private function process($value, $flags) { $config = $this; @@ -293,8 +299,8 @@ class Config return $value; } - return preg_replace_callback('#\{\$(.+)\}#', function ($match) use ($config) { - return $config->get($match[1]); + return preg_replace_callback('#\{\$(.+)\}#', function ($match) use ($config, $flags) { + return $config->get($match[1], $flags); }, $value); } diff --git a/tests/Composer/Test/ConfigTest.php b/tests/Composer/Test/ConfigTest.php index 04160b63f..99970125c 100644 --- a/tests/Composer/Test/ConfigTest.php +++ b/tests/Composer/Test/ConfigTest.php @@ -136,6 +136,20 @@ class ConfigTest extends \PHPUnit_Framework_TestCase $this->assertEquals('/baz', $config->get('cache-dir')); } + public function testFetchingRelativePaths() + { + $config = new Config(false, '/foo/bar'); + $config->merge(array('config' => array( + 'bin-dir' => '{$vendor-dir}/foo', + 'vendor-dir' => 'vendor' + ))); + + $this->assertEquals('/foo/bar/vendor', $config->get('vendor-dir')); + $this->assertEquals('/foo/bar/vendor/foo', $config->get('bin-dir')); + $this->assertEquals('vendor', $config->get('vendor-dir', Config::RELATIVE_PATHS)); + $this->assertEquals('vendor/foo', $config->get('bin-dir', Config::RELATIVE_PATHS)); + } + public function testOverrideGithubProtocols() { $config = new Config(false); From 6b5a531782fbfe837e0dcf7e5bc801e095fbcf00 Mon Sep 17 00:00:00 2001 From: tomzx Date: Wed, 17 Dec 2014 21:11:36 -0500 Subject: [PATCH 13/73] Minor fix to the HTTP Basic Authentication documentation Replaced JSON array with JSON object since you cannot assign key values in an array. --- doc/articles/http-basic-authentication.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/articles/http-basic-authentication.md b/doc/articles/http-basic-authentication.md index af62fe2df..1add2d7a6 100644 --- a/doc/articles/http-basic-authentication.md +++ b/doc/articles/http-basic-authentication.md @@ -40,7 +40,7 @@ username/password pairs, for example: ```json { - "basic-auth": [ + "basic-auth": { "repo.example1.org": { "username": "my-username1", "password": "my-secret-password1" @@ -49,7 +49,7 @@ username/password pairs, for example: "username": "my-username2", "password": "my-secret-password2" } - ] + } } ``` From 70007fee4ef9d8e09f443de16fde096942a889b3 Mon Sep 17 00:00:00 2001 From: Arfan Date: Sun, 21 Dec 2014 02:18:29 +0530 Subject: [PATCH 14/73] Typo edited. Silly typo edit. --- doc/01-basic-usage.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/01-basic-usage.md b/doc/01-basic-usage.md index 1ab4acbdb..d83e79aed 100644 --- a/doc/01-basic-usage.md +++ b/doc/01-basic-usage.md @@ -2,7 +2,7 @@ ## Installing -If you have not yet installed Composer, refer to to the [Intro](00-intro.md) chapter. +If you have not yet installed Composer, refer to the [Intro](00-intro.md) chapter. ## `composer.json`: Project Setup From 267af928df41085ef2390d686d245614bf2f6f80 Mon Sep 17 00:00:00 2001 From: Christophe Coevoet Date: Mon, 22 Dec 2014 12:22:29 +0100 Subject: [PATCH 15/73] Add a failing testcase for stability flags in complex constraints Refs #3570 --- tests/Composer/Test/Package/Loader/RootPackageLoaderTest.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/Composer/Test/Package/Loader/RootPackageLoaderTest.php b/tests/Composer/Test/Package/Loader/RootPackageLoaderTest.php index 51799d053..d1f3be1f8 100644 --- a/tests/Composer/Test/Package/Loader/RootPackageLoaderTest.php +++ b/tests/Composer/Test/Package/Loader/RootPackageLoaderTest.php @@ -143,6 +143,7 @@ class RootPackageLoaderTest extends \PHPUnit_Framework_TestCase 'foo/bar' => '~2.1.0-beta2', 'bar/baz' => '1.0.x-dev as 1.2.0', 'qux/quux' => '1.0.*@rc', + 'zux/complex' => '~1.0,>=1.0.2@dev' ), 'minimum-stability' => 'alpha', )); @@ -151,6 +152,7 @@ class RootPackageLoaderTest extends \PHPUnit_Framework_TestCase $this->assertEquals(array( 'bar/baz' => BasePackage::STABILITY_DEV, 'qux/quux' => BasePackage::STABILITY_RC, + 'zux/complex' => BasePackage::STABILITY_DEV, ), $package->getStabilityFlags()); } } From d8813341c3fb0026c130f2d4e153e4954906f861 Mon Sep 17 00:00:00 2001 From: Christophe Coevoet Date: Mon, 22 Dec 2014 12:31:34 +0100 Subject: [PATCH 16/73] Support parsing stability flags on complex constraints Fixes #3570 --- src/Composer/Package/Loader/RootPackageLoader.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Composer/Package/Loader/RootPackageLoader.php b/src/Composer/Package/Loader/RootPackageLoader.php index 64880d727..250f2952f 100644 --- a/src/Composer/Package/Loader/RootPackageLoader.php +++ b/src/Composer/Package/Loader/RootPackageLoader.php @@ -131,7 +131,7 @@ class RootPackageLoader extends ArrayLoader $minimumStability = $stabilities[$minimumStability]; foreach ($requires as $reqName => $reqVersion) { // parse explicit stability flags to the most unstable - if (preg_match('{^[^,\s]*?@('.implode('|', array_keys($stabilities)).')$}i', $reqVersion, $match)) { + if (preg_match('{^[^@]*?@('.implode('|', array_keys($stabilities)).')$}i', $reqVersion, $match)) { $name = strtolower($reqName); $stability = $stabilities[VersionParser::normalizeStability($match[1])]; From c93305a80548bf04650d8c05c98803b95dada90e Mon Sep 17 00:00:00 2001 From: SofHad Date: Fri, 26 Dec 2014 00:07:49 +0100 Subject: [PATCH 17/73] To show instead of open the repository or homepage URL --- src/Composer/Command/HomeCommand.php | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/Composer/Command/HomeCommand.php b/src/Composer/Command/HomeCommand.php index 5b0e32244..fe7929839 100644 --- a/src/Composer/Command/HomeCommand.php +++ b/src/Composer/Command/HomeCommand.php @@ -40,12 +40,14 @@ class HomeCommand extends Command ->setDefinition(array( new InputArgument('packages', InputArgument::IS_ARRAY | InputArgument::REQUIRED, 'Package(s) to browse to.'), new InputOption('homepage', 'H', InputOption::VALUE_NONE, 'Open the homepage instead of the repository URL.'), + new InputOption('show', 's', InputOption::VALUE_NONE, 'Only show the homepage or repository URL.'), )) ->setHelp(<<openBrowser($url); + if ($input->getOption('show')) { + $output->writeln(sprintf('%s: %s', $input->getOption('homepage') ? 'Homepage URL' : 'Repository URL', $url).' '); + } else { + $this->openBrowser($url); + } } return $return; From 9bc6209be931e423b6377a1502c093578b8ba9ab Mon Sep 17 00:00:00 2001 From: Christophe Coevoet Date: Tue, 16 Dec 2014 18:45:36 +0100 Subject: [PATCH 18/73] Fix tests for the pear repository --- tests/Composer/Test/Repository/Pear/ChannelReaderTest.php | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/Composer/Test/Repository/Pear/ChannelReaderTest.php b/tests/Composer/Test/Repository/Pear/ChannelReaderTest.php index 214d7b702..c22250a04 100644 --- a/tests/Composer/Test/Repository/Pear/ChannelReaderTest.php +++ b/tests/Composer/Test/Repository/Pear/ChannelReaderTest.php @@ -121,6 +121,7 @@ class ChannelReaderTest extends TestCase $expectedPackage->setType('pear-library'); $expectedPackage->setDistType('file'); $expectedPackage->setDescription('description'); + $expectedPackage->setLicense(array('license')); $expectedPackage->setDistUrl("http://test.loc/get/sample-1.0.0.1.tgz"); $expectedPackage->setAutoload(array('classmap' => array(''))); $expectedPackage->setIncludePaths(array('/')); From 45089a6771e00c644cb543372def3d6eceb301b6 Mon Sep 17 00:00:00 2001 From: SofHad Date: Sun, 28 Dec 2014 00:42:01 +0100 Subject: [PATCH 19/73] [Minor] remove the unused private variables --- src/Composer/Repository/ComposerRepository.php | 2 -- src/Composer/Util/RemoteFilesystem.php | 1 - 2 files changed, 3 deletions(-) diff --git a/src/Composer/Repository/ComposerRepository.php b/src/Composer/Repository/ComposerRepository.php index d5d8c11ef..5409a8dd3 100644 --- a/src/Composer/Repository/ComposerRepository.php +++ b/src/Composer/Repository/ComposerRepository.php @@ -53,8 +53,6 @@ class ComposerRepository extends ArrayRepository protected $eventDispatcher; protected $sourceMirrors; protected $distMirrors; - private $rawData; - private $minimalPackages; private $degradedMode = false; private $rootData; diff --git a/src/Composer/Util/RemoteFilesystem.php b/src/Composer/Util/RemoteFilesystem.php index cfb4a946e..e03cf8ec8 100644 --- a/src/Composer/Util/RemoteFilesystem.php +++ b/src/Composer/Util/RemoteFilesystem.php @@ -26,7 +26,6 @@ class RemoteFilesystem { private $io; private $config; - private $firstCall; private $bytesMax; private $originUrl; private $fileUrl; From 82b84f7a0ac1e575b95d1540ea8c6c8cab3392cc Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Mon, 29 Dec 2014 19:27:35 +0000 Subject: [PATCH 20/73] Fix formatting of constraint output --- src/Composer/Package/LinkConstraint/MultiConstraint.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Composer/Package/LinkConstraint/MultiConstraint.php b/src/Composer/Package/LinkConstraint/MultiConstraint.php index f2eff93ec..3871aeb2f 100644 --- a/src/Composer/Package/LinkConstraint/MultiConstraint.php +++ b/src/Composer/Package/LinkConstraint/MultiConstraint.php @@ -78,6 +78,6 @@ class MultiConstraint implements LinkConstraintInterface $constraints[] = $constraint->__toString(); } - return '['.implode($this->conjunctive ? ', ' : ' | ', $constraints).']'; + return '['.implode($this->conjunctive ? ' ' : ' || ', $constraints).']'; } } From 095dc6129550de93cd98170c8e6c6ccd4558e983 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Mon, 29 Dec 2014 20:29:13 +0000 Subject: [PATCH 21/73] Rename runAutoloader to dumpAutoloader, refs #3453 --- src/Composer/Command/InstallCommand.php | 2 +- src/Composer/Command/UpdateCommand.php | 2 +- src/Composer/Installer.php | 16 ++++++++-------- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/Composer/Command/InstallCommand.php b/src/Composer/Command/InstallCommand.php index c1de25ce7..98cd21b9f 100644 --- a/src/Composer/Command/InstallCommand.php +++ b/src/Composer/Command/InstallCommand.php @@ -114,7 +114,7 @@ EOT ->setPreferSource($preferSource) ->setPreferDist($preferDist) ->setDevMode(!$input->getOption('no-dev')) - ->setRunAutoloader(!$input->getOption('no-autoloader')) + ->setDumpAutoloader(!$input->getOption('no-autoloader')) ->setRunScripts(!$input->getOption('no-scripts')) ->setOptimizeAutoloader($optimize) ->setIgnorePlatformRequirements($input->getOption('ignore-platform-reqs')) diff --git a/src/Composer/Command/UpdateCommand.php b/src/Composer/Command/UpdateCommand.php index cb3b50209..10fa26987 100644 --- a/src/Composer/Command/UpdateCommand.php +++ b/src/Composer/Command/UpdateCommand.php @@ -118,7 +118,7 @@ EOT ->setPreferSource($preferSource) ->setPreferDist($preferDist) ->setDevMode(!$input->getOption('no-dev')) - ->setRunAutoloader(!$input->getOption('no-autoloader')) + ->setDumpAutoloader(!$input->getOption('no-autoloader')) ->setRunScripts(!$input->getOption('no-scripts')) ->setOptimizeAutoloader($optimize) ->setUpdate(true) diff --git a/src/Composer/Installer.php b/src/Composer/Installer.php index 041a2f6c9..3594336e3 100644 --- a/src/Composer/Installer.php +++ b/src/Composer/Installer.php @@ -105,7 +105,7 @@ class Installer protected $dryRun = false; protected $verbose = false; protected $update = false; - protected $runAutoloader = true; + protected $dumpAutoloader = true; protected $runScripts = true; protected $ignorePlatformReqs = false; protected $preferStable = false; @@ -318,14 +318,14 @@ class Installer } } - if ($this->runAutoloader) { + if ($this->dumpAutoloader) { // write autoloader if ($this->optimizeAutoloader) { $this->io->write('Generating optimized autoload files'); } else { $this->io->write('Generating autoload files'); } - + $this->autoloadGenerator->setDevMode($this->devMode); $this->autoloadGenerator->dump($this->config, $localRepo, $this->package, $this->installationManager, 'composer', $this->optimizeAutoloader); } @@ -1169,14 +1169,14 @@ class Installer /** * set whether to run autoloader or not - * - * @param boolean $runAutoloader + * + * @param boolean $dumpAutoloader * @return Installer */ - public function setRunAutoloader($runAutoloader = true) + public function setDumpAutoloader($dumpAutoloader = true) { - $this->runAutoloader = (boolean) $runAutoloader; - + $this->dumpAutoloader = (boolean) $dumpAutoloader; + return $this; } From 5c43485e570dd5cf7594dabb3edc6257896f872e Mon Sep 17 00:00:00 2001 From: SofHad Date: Sun, 28 Dec 2014 00:53:35 +0100 Subject: [PATCH 22/73] Suppress unused parameters in HomeCommand --- src/Composer/Command/HomeCommand.php | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/Composer/Command/HomeCommand.php b/src/Composer/Command/HomeCommand.php index 5b0e32244..09b48bb2b 100644 --- a/src/Composer/Command/HomeCommand.php +++ b/src/Composer/Command/HomeCommand.php @@ -55,7 +55,7 @@ EOT */ protected function execute(InputInterface $input, OutputInterface $output) { - $repo = $this->initializeRepo($input, $output); + $repo = $this->initializeRepo(); $return = 0; foreach ($input->getArgument('packages') as $packageName) { @@ -138,13 +138,11 @@ EOT } /** - * initializes the repo + * Initializes the repo * - * @param InputInterface $input - * @param OutputInterface $output * @return CompositeRepository */ - private function initializeRepo(InputInterface $input, OutputInterface $output) + private function initializeRepo() { $composer = $this->getComposer(false); From 8d0c1a14b33a107712b6ced6857d77eef685ba48 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Thu, 1 Jan 2015 16:21:22 +0000 Subject: [PATCH 23/73] Add --ignore-platform-reqs to create-project, refs #1426 --- doc/03-cli.md | 3 +++ src/Composer/Command/CreateProjectCommand.php | 7 +++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/doc/03-cli.md b/doc/03-cli.md index ad31c2220..f9625eb2e 100644 --- a/doc/03-cli.md +++ b/doc/03-cli.md @@ -467,6 +467,9 @@ By default the command checks for the packages on packagist.org. * **--keep-vcs:** Skip the deletion of the VCS metadata for the created project. This is mostly useful if you run the command in non-interactive mode. +* **--ignore-platform-reqs:** ignore `php`, `hhvm`, `lib-*` and `ext-*` + requirements and force the installation even if the local machine does not + fulfill these. ## dump-autoload diff --git a/src/Composer/Command/CreateProjectCommand.php b/src/Composer/Command/CreateProjectCommand.php index 4a3d33831..0242afcd3 100644 --- a/src/Composer/Command/CreateProjectCommand.php +++ b/src/Composer/Command/CreateProjectCommand.php @@ -69,6 +69,7 @@ class CreateProjectCommand extends Command new InputOption('no-progress', null, InputOption::VALUE_NONE, 'Do not output download progress.'), new InputOption('keep-vcs', null, InputOption::VALUE_NONE, 'Whether to prevent deletion vcs folder.'), new InputOption('no-install', null, InputOption::VALUE_NONE, 'Whether to skip installation of the package dependencies.'), + new InputOption('ignore-platform-reqs', null, InputOption::VALUE_NONE, 'Ignore platform requirements (php & ext- packages).'), )) ->setHelp(<<create-project command creates a new project from a given @@ -125,11 +126,12 @@ EOT $input->getOption('keep-vcs'), $input->getOption('no-progress'), $input->getOption('no-install'), + $input->getOption('ignore-platform-reqs'), $input ); } - public function installProject(IOInterface $io, Config $config, $packageName, $directory = null, $packageVersion = null, $stability = 'stable', $preferSource = false, $preferDist = false, $installDevPackages = false, $repositoryUrl = null, $disablePlugins = false, $noScripts = false, $keepVcs = false, $noProgress = false, $noInstall = false, InputInterface $input) + public function installProject(IOInterface $io, Config $config, $packageName, $directory = null, $packageVersion = null, $stability = 'stable', $preferSource = false, $preferDist = false, $installDevPackages = false, $repositoryUrl = null, $disablePlugins = false, $noScripts = false, $keepVcs = false, $noProgress = false, $noInstall = false, $ignorePlatformReqs = false, InputInterface $input) { $oldCwd = getcwd(); @@ -159,7 +161,8 @@ EOT $installer->setPreferSource($preferSource) ->setPreferDist($preferDist) ->setDevMode($installDevPackages) - ->setRunScripts( ! $noScripts); + ->setRunScripts(!$noScripts) + ->setIgnorePlatformRequirements($ignorePlatformReqs); if ($disablePlugins) { $installer->disablePlugins(); From 220bd2bd1edc19c809a341f8f1e1dfac15ccacff Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Thu, 1 Jan 2015 16:26:14 +0000 Subject: [PATCH 24/73] Remove phpunit repo from tests --- tests/Composer/Test/Repository/PearRepositoryTest.php | 7 ------- 1 file changed, 7 deletions(-) diff --git a/tests/Composer/Test/Repository/PearRepositoryTest.php b/tests/Composer/Test/Repository/PearRepositoryTest.php index a42c8e0b3..7eaad13e7 100644 --- a/tests/Composer/Test/Repository/PearRepositoryTest.php +++ b/tests/Composer/Test/Repository/PearRepositoryTest.php @@ -84,13 +84,6 @@ class PearRepositoryTest extends TestCase public function repositoryDataProvider() { return array( - array( - 'pear.phpunit.de', - array( - array('name' => 'pear-pear.phpunit.de/PHPUnit_MockObject', 'version' => '1.1.1'), - array('name' => 'pear-pear.phpunit.de/PHPUnit', 'version' => '3.6.10'), - ) - ), array( 'pear.php.net', array( From bf32d2b83ce52a1cf79e4ee7310e405bf92f1eae Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Thu, 1 Jan 2015 20:53:06 +0000 Subject: [PATCH 25/73] Update deps --- composer.json | 2 +- composer.lock | 33 +++++++++++++++++---------------- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/composer.json b/composer.json index 6d239970d..9fca7d74c 100644 --- a/composer.json +++ b/composer.json @@ -23,7 +23,7 @@ }, "require": { "php": ">=5.3.2", - "justinrainbow/json-schema": "~1.1", + "justinrainbow/json-schema": "~1.3", "seld/jsonlint": "~1.0", "symfony/console": "~2.3", "symfony/finder": "~2.2", diff --git a/composer.lock b/composer.lock index 0c7ff85ba..7d28fcb09 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "0430383b5ba00e406ce4a44253f49fe7", + "hash": "2bc9cc8aa706b68d611d7058e4eb8de7", "packages": [ { "name": "justinrainbow/json-schema", @@ -327,16 +327,16 @@ }, { "name": "phpunit/php-code-coverage", - "version": "2.0.13", + "version": "2.0.14", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "0e7d2eec5554f869fa7a4ec2d21e4b37af943ea5" + "reference": "ca158276c1200cc27f5409a5e338486bc0b4fc94" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/0e7d2eec5554f869fa7a4ec2d21e4b37af943ea5", - "reference": "0e7d2eec5554f869fa7a4ec2d21e4b37af943ea5", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/ca158276c1200cc27f5409a5e338486bc0b4fc94", + "reference": "ca158276c1200cc27f5409a5e338486bc0b4fc94", "shasum": "" }, "require": { @@ -388,7 +388,7 @@ "testing", "xunit" ], - "time": "2014-12-03 06:41:44" + "time": "2014-12-26 13:28:33" }, { "name": "phpunit/php-file-iterator", @@ -574,16 +574,16 @@ }, { "name": "phpunit/phpunit", - "version": "4.4.0", + "version": "4.4.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "bbe7bcb83b6ec1a9eaabbe1b70d4795027c53ee0" + "reference": "6a5e49a86ce5e33b8d0657abe145057fc513543a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/bbe7bcb83b6ec1a9eaabbe1b70d4795027c53ee0", - "reference": "bbe7bcb83b6ec1a9eaabbe1b70d4795027c53ee0", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/6a5e49a86ce5e33b8d0657abe145057fc513543a", + "reference": "6a5e49a86ce5e33b8d0657abe145057fc513543a", "shasum": "" }, "require": { @@ -641,7 +641,7 @@ "testing", "xunit" ], - "time": "2014-12-05 06:49:03" + "time": "2014-12-28 07:57:05" }, { "name": "phpunit/phpunit-mock-objects", @@ -982,16 +982,16 @@ }, { "name": "sebastian/version", - "version": "1.0.3", + "version": "1.0.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/version.git", - "reference": "b6e1f0cf6b9e1ec409a0d3e2f2a5fb0998e36b43" + "reference": "a77d9123f8e809db3fbdea15038c27a95da4058b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/b6e1f0cf6b9e1ec409a0d3e2f2a5fb0998e36b43", - "reference": "b6e1f0cf6b9e1ec409a0d3e2f2a5fb0998e36b43", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/a77d9123f8e809db3fbdea15038c27a95da4058b", + "reference": "a77d9123f8e809db3fbdea15038c27a95da4058b", "shasum": "" }, "type": "library", @@ -1013,7 +1013,7 @@ ], "description": "Library that helps with managing the version number of Git-hosted PHP projects", "homepage": "https://github.com/sebastianbergmann/version", - "time": "2014-03-07 15:35:33" + "time": "2014-12-15 14:25:24" }, { "name": "symfony/yaml", @@ -1067,6 +1067,7 @@ "minimum-stability": "stable", "stability-flags": [], "prefer-stable": false, + "prefer-lowest": false, "platform": { "php": ">=5.3.2" }, From e172cd81a146666d844d2b7b37b5feccb89e2b61 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Fri, 2 Jan 2015 07:52:56 +0000 Subject: [PATCH 26/73] Fix lax validation of packages when loading them, fixes #3606, fixes #3605 --- src/Composer/Json/JsonFile.php | 3 +-- src/Composer/Json/JsonValidationException.php | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/Composer/Json/JsonFile.php b/src/Composer/Json/JsonFile.php index ceaffaa25..3375329c7 100644 --- a/src/Composer/Json/JsonFile.php +++ b/src/Composer/Json/JsonFile.php @@ -154,8 +154,7 @@ class JsonFile if ($schema === self::LAX_SCHEMA) { $schemaData->additionalProperties = true; - $schemaData->properties->name->required = false; - $schemaData->properties->description->required = false; + $schemaData->required = array(); } $validator = new Validator(); diff --git a/src/Composer/Json/JsonValidationException.php b/src/Composer/Json/JsonValidationException.php index 0b2b2ba70..5d21f533c 100644 --- a/src/Composer/Json/JsonValidationException.php +++ b/src/Composer/Json/JsonValidationException.php @@ -21,10 +21,10 @@ class JsonValidationException extends Exception { protected $errors; - public function __construct($message, $errors = array()) + public function __construct($message, $errors = array(), \Exception $previous = null) { $this->errors = $errors; - parent::__construct($message); + parent::__construct($message, 0, $previous); } public function getErrors() From ad1f8e6c5afdf869754c9d7092c3bf8d33e8d1ed Mon Sep 17 00:00:00 2001 From: Bryan Davis Date: Sat, 3 Jan 2015 17:35:25 -0700 Subject: [PATCH 27/73] Add classmap-authoritative config setting Add a "classmap-authoritative" configuration setting that can be used to disable searching the various prefix and fallback directories for classes that have not been registered with the Composer\Autoload\ClassLoader class map. This setting can be used to optimize performance by avoiding a potentially large number of `file_exists` calls when Composer is being used in a program with additional autoloader facilities. Use of the setting implies "optimize-autoloader" to ensure that the most complete class map possible is generated. Closes #3603 --- doc/04-schema.md | 3 + res/composer-schema.json | 4 + src/Composer/Autoload/AutoloadGenerator.php | 12 ++- src/Composer/Autoload/ClassLoader.php | 25 ++++++ src/Composer/Command/ConfigCommand.php | 1 + src/Composer/Command/DumpAutoloadCommand.php | 2 +- src/Composer/Command/InstallCommand.php | 2 +- src/Composer/Command/UpdateCommand.php | 2 +- src/Composer/Config.php | 1 + .../Test/Autoload/AutoloadGeneratorTest.php | 76 +++++++++++++++---- 10 files changed, 110 insertions(+), 18 deletions(-) diff --git a/doc/04-schema.md b/doc/04-schema.md index 6dd06d635..f88ce11df 100644 --- a/doc/04-schema.md +++ b/doc/04-schema.md @@ -789,6 +789,9 @@ The following options are supported: the generated Composer autoloader. When null a random one will be generated. * **optimize-autoloader** Defaults to `false`. Always optimize when dumping the autoloader. +* **classmap-authoritative:** Defaults to `false`. If true, the composer + autoloader will not scan the filesystem for classes that are not found in + the class map. Implies 'optimize-autoloader'. * **github-domains:** Defaults to `["github.com"]`. A list of domains to use in github mode. This is used for GitHub Enterprise setups. * **github-expose-hostname:** Defaults to `true`. If set to false, the OAuth diff --git a/res/composer-schema.json b/res/composer-schema.json index 49ec0fa7a..4c40bdfb2 100644 --- a/res/composer-schema.json +++ b/res/composer-schema.json @@ -197,6 +197,10 @@ "type": "boolean", "description": "If false, the composer autoloader will not be prepended to existing autoloaders, defaults to true." }, + "classmap-authoritative": { + "type": "boolean", + "description": "If true, the composer autoloader will not scan the filesystem for classes that are not found in the class map, defaults to false." + }, "github-domains": { "type": "array", "description": "A list of domains to use in github mode. This is used for GitHub Enterprise setups, defaults to [\"github.com\"].", diff --git a/src/Composer/Autoload/AutoloadGenerator.php b/src/Composer/Autoload/AutoloadGenerator.php index 19f194fa1..c88c34b41 100644 --- a/src/Composer/Autoload/AutoloadGenerator.php +++ b/src/Composer/Autoload/AutoloadGenerator.php @@ -63,6 +63,7 @@ class AutoloadGenerator $vendorPath = $filesystem->normalizePath(realpath($config->get('vendor-dir'))); $useGlobalIncludePath = (bool) $config->get('use-include-path'); $prependAutoloader = $config->get('prepend-autoloader') === false ? 'false' : 'true'; + $classMapAuthoritative = $config->get('classmap-authoritative'); $targetDir = $vendorPath.'/'.$targetDir; $filesystem->ensureDirectoryExists($targetDir); @@ -226,7 +227,7 @@ EOF; 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)); + file_put_contents($targetDir.'/autoload_real.php', $this->getAutoloadRealFile(true, (bool) $includePathFile, $targetDirLoader, (bool) $includeFilesFile, $vendorPathCode, $appBaseDirCode, $suffix, $useGlobalIncludePath, $prependAutoloader, $classMapAuthoritative)); // use stream_copy_to_stream instead of copy // to work around https://bugs.php.net/bug.php?id=64634 @@ -443,7 +444,7 @@ return ComposerAutoloaderInit$suffix::getLoader(); AUTOLOAD; } - protected function getAutoloadRealFile($useClassMap, $useIncludePath, $targetDirLoader, $useIncludeFiles, $vendorPathCode, $appBaseDirCode, $suffix, $useGlobalIncludePath, $prependAutoloader) + protected function getAutoloadRealFile($useClassMap, $useIncludePath, $targetDirLoader, $useIncludeFiles, $vendorPathCode, $appBaseDirCode, $suffix, $useGlobalIncludePath, $prependAutoloader, $classMapAuthoritative) { // TODO the class ComposerAutoloaderInit should be revert to a closure // when APC has been fixed: @@ -520,6 +521,13 @@ PSR4; CLASSMAP; } + if ($classMapAuthoritative) { + $file .= <<<'CLASSMAPAUTHORITATIVE' + $loader->setClassMapAuthoritative(true); + +CLASSMAPAUTHORITATIVE; + } + if ($useGlobalIncludePath) { $file .= <<<'INCLUDEPATH' $loader->setUseIncludePath(true); diff --git a/src/Composer/Autoload/ClassLoader.php b/src/Composer/Autoload/ClassLoader.php index 70d78bc3f..112815324 100644 --- a/src/Composer/Autoload/ClassLoader.php +++ b/src/Composer/Autoload/ClassLoader.php @@ -54,6 +54,8 @@ class ClassLoader private $useIncludePath = false; private $classMap = array(); + private $classMapAuthoratative = false; + public function getPrefixes() { if (!empty($this->prefixesPsr0)) { @@ -248,6 +250,27 @@ class ClassLoader return $this->useIncludePath; } + /** + * Turns off searching the prefix and fallback directories for classes + * that have not been registered with the class map. + * + * @param bool $classMapAuthoratative + */ + public function setClassMapAuthoritative($classMapAuthoratative) + { + $this->classMapAuthoratative = $classMapAuthoratative; + } + + /** + * Should class lookup fail if not found in the current class map? + * + * @return bool + */ + public function getClassMapAuthoratative() + { + return $this->classMapAuthoratative; + } + /** * Registers this instance as an autoloader. * @@ -298,6 +321,8 @@ class ClassLoader // class map lookup if (isset($this->classMap[$class])) { return $this->classMap[$class]; + } elseif ($this->classMapAuthoratative) { + return false; } $file = $this->findFileWithExtension($class, '.php'); diff --git a/src/Composer/Command/ConfigCommand.php b/src/Composer/Command/ConfigCommand.php index 832571b3f..b50707f0b 100644 --- a/src/Composer/Command/ConfigCommand.php +++ b/src/Composer/Command/ConfigCommand.php @@ -323,6 +323,7 @@ EOT ), 'autoloader-suffix' => array('is_string', function ($val) { return $val === 'null' ? null : $val; }), 'optimize-autoloader' => array($booleanValidator, $booleanNormalizer), + 'classmap-authoritative' => array($booleanValidator, $booleanNormalizer), 'prepend-autoloader' => array($booleanValidator, $booleanNormalizer), 'github-expose-hostname' => array($booleanValidator, $booleanNormalizer), ); diff --git a/src/Composer/Command/DumpAutoloadCommand.php b/src/Composer/Command/DumpAutoloadCommand.php index b30fbd140..adcc7adfd 100644 --- a/src/Composer/Command/DumpAutoloadCommand.php +++ b/src/Composer/Command/DumpAutoloadCommand.php @@ -52,7 +52,7 @@ EOT $package = $composer->getPackage(); $config = $composer->getConfig(); - $optimize = $input->getOption('optimize') || $config->get('optimize-autoloader'); + $optimize = $input->getOption('optimize') || $config->get('optimize-autoloader') || $config->get('classmap-authoritative'); if ($optimize) { $output->writeln('Generating optimized autoload files'); diff --git a/src/Composer/Command/InstallCommand.php b/src/Composer/Command/InstallCommand.php index 98cd21b9f..9d359cad0 100644 --- a/src/Composer/Command/InstallCommand.php +++ b/src/Composer/Command/InstallCommand.php @@ -106,7 +106,7 @@ EOT $preferDist = $input->getOption('prefer-dist'); } - $optimize = $input->getOption('optimize-autoloader') || $config->get('optimize-autoloader'); + $optimize = $input->getOption('optimize-autoloader') || $config->get('optimize-autoloader') || $config->get('classmap-authoritative'); $install ->setDryRun($input->getOption('dry-run')) diff --git a/src/Composer/Command/UpdateCommand.php b/src/Composer/Command/UpdateCommand.php index 10fa26987..4e4f003c9 100644 --- a/src/Composer/Command/UpdateCommand.php +++ b/src/Composer/Command/UpdateCommand.php @@ -110,7 +110,7 @@ EOT $preferDist = $input->getOption('prefer-dist'); } - $optimize = $input->getOption('optimize-autoloader') || $config->get('optimize-autoloader'); + $optimize = $input->getOption('optimize-autoloader') || $config->get('optimize-autoloader') || $config->get('classmap-authoritative'); $install ->setDryRun($input->getOption('dry-run')) diff --git a/src/Composer/Config.php b/src/Composer/Config.php index 86e318765..92ce8246b 100644 --- a/src/Composer/Config.php +++ b/src/Composer/Config.php @@ -39,6 +39,7 @@ class Config 'discard-changes' => false, 'autoloader-suffix' => null, 'optimize-autoloader' => false, + 'classmap-authoritative' => false, 'prepend-autoloader' => true, 'github-domains' => array('github.com'), 'github-expose-hostname' => true, diff --git a/tests/Composer/Test/Autoload/AutoloadGeneratorTest.php b/tests/Composer/Test/Autoload/AutoloadGeneratorTest.php index 7c4ddccd9..7ca90b244 100644 --- a/tests/Composer/Test/Autoload/AutoloadGeneratorTest.php +++ b/tests/Composer/Test/Autoload/AutoloadGeneratorTest.php @@ -67,6 +67,11 @@ class AutoloadGeneratorTest extends TestCase */ private $eventDispatcher; + /** + * @var array + */ + private $configValueMap; + protected function setUp() { $this->fs = new Filesystem; @@ -79,18 +84,23 @@ class AutoloadGeneratorTest extends TestCase $this->config = $this->getMock('Composer\Config'); - $this->config->expects($this->at(0)) - ->method('get') - ->with($this->equalTo('vendor-dir')) - ->will($this->returnCallback(function () use ($that) { + $this->configValueMap = array( + 'vendor-dir' => function () use ($that) { return $that->vendorDir; - })); + }, + ); - $this->config->expects($this->at(1)) + $this->config->expects($this->atLeastOnce()) ->method('get') - ->with($this->equalTo('vendor-dir')) - ->will($this->returnCallback(function () use ($that) { - return $that->vendorDir; + ->will($this->returnCallback(function ($arg) use ($that) { + $ret = null; + if (isset($that->configValueMap[$arg])) { + $ret = $that->configValueMap[$arg]; + if (is_callable($ret)) { + $ret = $ret(); + } + } + return $ret; })); $this->origDir = getcwd(); @@ -483,6 +493,49 @@ class AutoloadGeneratorTest extends TestCase include $this->vendorDir.'/composer/autoload_classmap.php' ); $this->assertAutoloadFiles('classmap5', $this->vendorDir.'/composer', 'classmap'); + $this->assertNotRegExp('/\$loader->setClassMapAuthoritative\(true\);/', file_get_contents($this->vendorDir.'/composer/autoload_real.php')); + } + + public function testClassMapAutoloadingAuthoritative() + { + $package = new Package('a', '1.0', '1.0'); + + $packages = array(); + $packages[] = $a = new Package('a/a', '1.0', '1.0'); + $packages[] = $b = new Package('b/b', '1.0', '1.0'); + $packages[] = $c = new Package('c/c', '1.0', '1.0'); + $a->setAutoload(array('classmap' => array(''))); + $b->setAutoload(array('classmap' => array('test.php'))); + $c->setAutoload(array('classmap' => array('./'))); + + $this->repository->expects($this->once()) + ->method('getCanonicalPackages') + ->will($this->returnValue($packages)); + + $this->configValueMap['classmap-authoritative'] = true; + + $this->fs->ensureDirectoryExists($this->vendorDir.'/composer'); + $this->fs->ensureDirectoryExists($this->vendorDir.'/a/a/src'); + $this->fs->ensureDirectoryExists($this->vendorDir.'/b/b'); + $this->fs->ensureDirectoryExists($this->vendorDir.'/c/c/foo'); + file_put_contents($this->vendorDir.'/a/a/src/a.php', 'vendorDir.'/b/b/test.php', 'vendorDir.'/c/c/foo/test.php', 'generator->dump($this->config, $this->repository, $package, $this->im, 'composer', false, '_7'); + $this->assertTrue(file_exists($this->vendorDir.'/composer/autoload_classmap.php'), "ClassMap file needs to be generated."); + $this->assertEquals( + array( + 'ClassMapBar' => $this->vendorDir.'/b/b/test.php', + 'ClassMapBaz' => $this->vendorDir.'/c/c/foo/test.php', + 'ClassMapFoo' => $this->vendorDir.'/a/a/src/a.php', + ), + include $this->vendorDir.'/composer/autoload_classmap.php' + ); + $this->assertAutoloadFiles('classmap5', $this->vendorDir.'/composer', 'classmap'); + + $this->assertRegExp('/\$loader->setClassMapAuthoritative\(true\);/', file_get_contents($this->vendorDir.'/composer/autoload_real.php')); + // FIXME: how can we actually test the ClassLoader implementation? } public function testFilesAutoloadGeneration() @@ -829,10 +882,7 @@ EOF; ->method('getCanonicalPackages') ->will($this->returnValue(array())); - $this->config->expects($this->at(2)) - ->method('get') - ->with($this->equalTo('use-include-path')) - ->will($this->returnValue(true)); + $this->configValueMap['use-include-path'] = true; $this->fs->ensureDirectoryExists($this->vendorDir.'/a'); From 92455759fc6e74b5e8eefab1d17fef118876cbe6 Mon Sep 17 00:00:00 2001 From: Bryan Davis Date: Sat, 3 Jan 2015 18:01:18 -0700 Subject: [PATCH 28/73] Fix AutoloadGeneratorTest for PHP 5.3.x --- tests/Composer/Test/Autoload/AutoloadGeneratorTest.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tests/Composer/Test/Autoload/AutoloadGeneratorTest.php b/tests/Composer/Test/Autoload/AutoloadGeneratorTest.php index 7ca90b244..54370381c 100644 --- a/tests/Composer/Test/Autoload/AutoloadGeneratorTest.php +++ b/tests/Composer/Test/Autoload/AutoloadGeneratorTest.php @@ -68,9 +68,15 @@ class AutoloadGeneratorTest extends TestCase private $eventDispatcher; /** + * Map of setting name => return value configuration for the stub Config + * object. + * + * Note: must be public for compatibility with PHP 5.3 runtimes where + * closures cannot access private members of the classes they are created + * in. * @var array */ - private $configValueMap; + public $configValueMap; protected function setUp() { From e0d36e19eb8a5c96ccad3d145faf9024727e856c Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Mon, 5 Jan 2015 16:17:15 +0000 Subject: [PATCH 29/73] Disable overwrites when no-ansi is present, fixes #3612 --- src/Composer/IO/ConsoleIO.php | 8 ++++++++ tests/Composer/Test/IO/ConsoleIOTest.php | 16 +++++++++++----- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/src/Composer/IO/ConsoleIO.php b/src/Composer/IO/ConsoleIO.php index 07e529666..491a6b7fb 100644 --- a/src/Composer/IO/ConsoleIO.php +++ b/src/Composer/IO/ConsoleIO.php @@ -113,6 +113,14 @@ class ConsoleIO extends BaseIO */ public function overwrite($messages, $newline = true, $size = null) { + if (!$this->output->isDecorated()) { + if (!$messages) { + return; + } + + return $this->write($messages, count($messages) === 1 || $newline); + } + // messages can be an array, let's convert it to string anyway $messages = join($newline ? "\n" : '', (array) $messages); diff --git a/tests/Composer/Test/IO/ConsoleIOTest.php b/tests/Composer/Test/IO/ConsoleIOTest.php index 3a4313f69..6ce95b0ac 100644 --- a/tests/Composer/Test/IO/ConsoleIOTest.php +++ b/tests/Composer/Test/IO/ConsoleIOTest.php @@ -58,21 +58,27 @@ class ConsoleIOTest extends TestCase ->method('write') ->with($this->equalTo('something (strlen = 23)')); $outputMock->expects($this->at(1)) + ->method('isDecorated') + ->willReturn(true); + $outputMock->expects($this->at(2)) ->method('write') ->with($this->equalTo(str_repeat("\x08", 23)), $this->equalTo(false)); - $outputMock->expects($this->at(2)) + $outputMock->expects($this->at(3)) ->method('write') ->with($this->equalTo('shorter (12)'), $this->equalTo(false)); - $outputMock->expects($this->at(3)) + $outputMock->expects($this->at(4)) ->method('write') ->with($this->equalTo(str_repeat(' ', 11)), $this->equalTo(false)); - $outputMock->expects($this->at(4)) + $outputMock->expects($this->at(5)) ->method('write') ->with($this->equalTo(str_repeat("\x08", 11)), $this->equalTo(false)); - $outputMock->expects($this->at(5)) + $outputMock->expects($this->at(6)) + ->method('isDecorated') + ->willReturn(true); + $outputMock->expects($this->at(7)) ->method('write') ->with($this->equalTo(str_repeat("\x08", 12)), $this->equalTo(false)); - $outputMock->expects($this->at(6)) + $outputMock->expects($this->at(8)) ->method('write') ->with($this->equalTo('something longer than initial (34)')); From c58b7d917c65692eeb00c22b2fbaaa251cb390dc Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Mon, 5 Jan 2015 16:31:16 +0000 Subject: [PATCH 30/73] Disable progress when no-ansi is specified, refs #3612 --- src/Composer/Command/Command.php | 14 ++++++++++++++ src/Composer/Command/ConfigCommand.php | 2 ++ 2 files changed, 16 insertions(+) diff --git a/src/Composer/Command/Command.php b/src/Composer/Command/Command.php index b99686219..6c5226c6a 100644 --- a/src/Composer/Command/Command.php +++ b/src/Composer/Command/Command.php @@ -16,6 +16,8 @@ use Composer\Composer; use Composer\Console\Application; use Composer\IO\IOInterface; use Composer\IO\NullIO; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Command\Command as BaseCommand; /** @@ -102,4 +104,16 @@ abstract class Command extends BaseCommand { $this->io = $io; } + + /** + * {@inheritDoc} + */ + protected function initialize(InputInterface $input, OutputInterface $output) + { + if (true === $input->hasParameterOption(array('--no-ansi')) && $input->hasOption('no-progress')) { + $input->setOption('no-progress', true); + } + + parent::initialize($input, $output); + } } diff --git a/src/Composer/Command/ConfigCommand.php b/src/Composer/Command/ConfigCommand.php index 832571b3f..4d52c8473 100644 --- a/src/Composer/Command/ConfigCommand.php +++ b/src/Composer/Command/ConfigCommand.php @@ -100,6 +100,8 @@ EOT */ protected function initialize(InputInterface $input, OutputInterface $output) { + parent::initialize($input, $output); + if ($input->getOption('global') && 'composer.json' !== $input->getOption('file')) { throw new \RuntimeException('--file and --global can not be combined'); } From 8ceb5714a49e848b549cbbc2ff9f6a496f4e3618 Mon Sep 17 00:00:00 2001 From: Bryan Davis Date: Mon, 5 Jan 2015 11:48:34 -0700 Subject: [PATCH 31/73] Fix spelling of "Authoritative" - classMapAuthoratative -> classMapAuthoritative - getClassMapAuthoratative -> isClassMapAuthoritative - Don't use elseif since if block returns --- src/Composer/Autoload/ClassLoader.php | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/Composer/Autoload/ClassLoader.php b/src/Composer/Autoload/ClassLoader.php index 112815324..5e1469e83 100644 --- a/src/Composer/Autoload/ClassLoader.php +++ b/src/Composer/Autoload/ClassLoader.php @@ -54,7 +54,7 @@ class ClassLoader private $useIncludePath = false; private $classMap = array(); - private $classMapAuthoratative = false; + private $classMapAuthoritative = false; public function getPrefixes() { @@ -254,11 +254,11 @@ class ClassLoader * Turns off searching the prefix and fallback directories for classes * that have not been registered with the class map. * - * @param bool $classMapAuthoratative + * @param bool $classMapAuthoritative */ - public function setClassMapAuthoritative($classMapAuthoratative) + public function setClassMapAuthoritative($classMapAuthoritative) { - $this->classMapAuthoratative = $classMapAuthoratative; + $this->classMapAuthoritative = $classMapAuthoritative; } /** @@ -266,9 +266,9 @@ class ClassLoader * * @return bool */ - public function getClassMapAuthoratative() + public function isClassMapAuthoritative() { - return $this->classMapAuthoratative; + return $this->classMapAuthoritative; } /** @@ -321,7 +321,8 @@ class ClassLoader // class map lookup if (isset($this->classMap[$class])) { return $this->classMap[$class]; - } elseif ($this->classMapAuthoratative) { + } + if ($this->classMapAuthoritative) { return false; } From 0f2558dab3d893a3ab72c6c39377ec5bd5e47763 Mon Sep 17 00:00:00 2001 From: Bryan Davis Date: Mon, 5 Jan 2015 12:05:17 -0700 Subject: [PATCH 32/73] Use assertContains in ClassMapAuthoritative checks Use assertContains instead of assertRegExp when checking for ClassMapAuthoritative settings. --- tests/Composer/Test/Autoload/AutoloadGeneratorTest.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tests/Composer/Test/Autoload/AutoloadGeneratorTest.php b/tests/Composer/Test/Autoload/AutoloadGeneratorTest.php index 54370381c..2ad1e4729 100644 --- a/tests/Composer/Test/Autoload/AutoloadGeneratorTest.php +++ b/tests/Composer/Test/Autoload/AutoloadGeneratorTest.php @@ -499,7 +499,7 @@ class AutoloadGeneratorTest extends TestCase include $this->vendorDir.'/composer/autoload_classmap.php' ); $this->assertAutoloadFiles('classmap5', $this->vendorDir.'/composer', 'classmap'); - $this->assertNotRegExp('/\$loader->setClassMapAuthoritative\(true\);/', file_get_contents($this->vendorDir.'/composer/autoload_real.php')); + $this->assertNotContains('$loader->setClassMapAuthoritative(true);', file_get_contents($this->vendorDir.'/composer/autoload_real.php')); } public function testClassMapAutoloadingAuthoritative() @@ -540,8 +540,7 @@ class AutoloadGeneratorTest extends TestCase ); $this->assertAutoloadFiles('classmap5', $this->vendorDir.'/composer', 'classmap'); - $this->assertRegExp('/\$loader->setClassMapAuthoritative\(true\);/', file_get_contents($this->vendorDir.'/composer/autoload_real.php')); - // FIXME: how can we actually test the ClassLoader implementation? + $this->assertContains('$loader->setClassMapAuthoritative(true);', file_get_contents($this->vendorDir.'/composer/autoload_real.php')); } public function testFilesAutoloadGeneration() From 5b800169e757ad28e8e8a19f64c70b7c761226ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Paris?= Date: Wed, 7 Jan 2015 21:47:00 +0100 Subject: [PATCH 33/73] move contributing instructions to a separate file A link to the CONTRIBUTING.md will show up on Github's pull request creation form. Plus, this makes the README shorter and more relevant for users. --- CONTRIBUTING.md | 29 +++++++++++++++++++++++++++++ README.md | 26 -------------------------- 2 files changed, 29 insertions(+), 26 deletions(-) create mode 100644 CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 000000000..820a4002e --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,29 @@ +Contributing to Composer +======================== + +Installation from Source +------------------------ + +Prior to contributing to Composer, you must use be able to run the tests. +To achieve this, you must use the sources and not the phar file. + +1. Run `git clone https://github.com/composer/composer.git` +2. Download the [`composer.phar`](https://getcomposer.org/composer.phar) executable +3. Run Composer to get the dependencies: `cd composer && php ../composer.phar install` + +You can now run Composer by executing the `bin/composer` script: `php /path/to/composer/bin/composer` + +Contributing policy +------------------- + +All code contributions - including those of people having commit access - +must go through a pull request and approved by a core developer before being +merged. This is to ensure proper review of all the code. + +Fork the project, create a feature branch, and send us a pull request. + +To ensure a consistent code base, you should make sure the code follows +the [Coding Standards](http://symfony.com/doc/current/contributing/code/standards.html) +which we borrowed from Symfony. + +If you would like to help, take a look at the [list of issues](http://github.com/composer/composer/issues). diff --git a/README.md b/README.md index a86bc83f6..728e11f2e 100644 --- a/README.md +++ b/README.md @@ -32,18 +32,6 @@ themselves. To create libraries/packages please read the 3. Run Composer: `php composer.phar install` 4. Browse for more packages on [Packagist](https://packagist.org). -Installation from Source ------------------------- - -To run tests, or develop Composer itself, you must use the sources and not the phar -file as described above. - -1. Run `git clone https://github.com/composer/composer.git` -2. Download the [`composer.phar`](https://getcomposer.org/composer.phar) executable -3. Run Composer to get the dependencies: `cd composer && php ../composer.phar install` - -You can now run Composer by executing the `bin/composer` script: `php /path/to/composer/bin/composer` - Global installation of Composer (manual) ---------------------------------------- @@ -55,20 +43,6 @@ Updating Composer Running `php composer.phar self-update` or equivalent will update a phar install with the latest version. -Contributing ------------- - -All code contributions - including those of people having commit access - -must go through a pull request and approved by a core developer before being -merged. This is to ensure proper review of all the code. - -Fork the project, create a feature branch, and send us a pull request. - -To ensure a consistent code base, you should make sure the code follows -the [Coding Standards](http://symfony.com/doc/current/contributing/code/standards.html) -which we borrowed from Symfony. - -If you would like to help take a look at the [list of issues](http://github.com/composer/composer/issues). Community --------- From 091fee8a3b3b0e3a9a18c7a681797038c018cbc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Paris?= Date: Thu, 8 Jan 2015 08:56:12 +0100 Subject: [PATCH 34/73] skip some tests when the zip extension misses It is required for some tests to run. --- tests/Composer/Test/Repository/ArtifactRepositoryTest.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/Composer/Test/Repository/ArtifactRepositoryTest.php b/tests/Composer/Test/Repository/ArtifactRepositoryTest.php index 7d64a0141..66c02acdc 100644 --- a/tests/Composer/Test/Repository/ArtifactRepositoryTest.php +++ b/tests/Composer/Test/Repository/ArtifactRepositoryTest.php @@ -19,6 +19,14 @@ use Composer\Package\BasePackage; class ArtifactRepositoryTest extends TestCase { + public function setUp() + { + parent::setUp(); + if (!extension_loaded('zip')) { + $this->markTestSkipped('You need the zip extension to run this test.'); + } + } + public function testExtractsConfigsFromZipArchives() { $expectedPackages = array( From 200f867d64d13fbc25648ef9f538c2cc7869a076 Mon Sep 17 00:00:00 2001 From: Hannes Van De Vreken Date: Fri, 9 Jan 2015 10:08:13 +0100 Subject: [PATCH 35/73] "suggest" was on a wrong heading level compared to the others --- doc/04-schema.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/04-schema.md b/doc/04-schema.md index 6dd06d635..8662ca855 100644 --- a/doc/04-schema.md +++ b/doc/04-schema.md @@ -375,7 +375,7 @@ useful for common interfaces. A package could depend on some virtual `logger` package, any library that implements this logger interface would simply list it in `provide`. -### suggest +#### suggest Suggested packages that can enhance or work well with this package. These are just informational and are displayed after the package is installed, to give From 7e3f4805c0670ff3dbbff40a4d4e5f4f66b73adc Mon Sep 17 00:00:00 2001 From: Carsten Brandt Date: Sat, 10 Jan 2015 17:25:31 +0100 Subject: [PATCH 36/73] Updated the documentation of the require command It did not mention that it is possible to leave out the version constraint. --- src/Composer/Command/RequireCommand.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Composer/Command/RequireCommand.php b/src/Composer/Command/RequireCommand.php index 91043ad71..ea972aaf0 100644 --- a/src/Composer/Command/RequireCommand.php +++ b/src/Composer/Command/RequireCommand.php @@ -38,7 +38,7 @@ class RequireCommand extends InitCommand ->setName('require') ->setDescription('Adds required packages to your composer.json and installs them') ->setDefinition(array( - new InputArgument('packages', InputArgument::IS_ARRAY | InputArgument::OPTIONAL, 'Required package with a version constraint, e.g. foo/bar:1.0.0 or foo/bar=1.0.0 or "foo/bar 1.0.0"'), + new InputArgument('packages', InputArgument::IS_ARRAY | InputArgument::OPTIONAL, 'Required package name optionally including a version constraint, e.g. foo/bar or foo/bar:1.0.0 or foo/bar=1.0.0 or "foo/bar 1.0.0"'), new InputOption('dev', null, InputOption::VALUE_NONE, 'Add requirement to require-dev.'), new InputOption('prefer-source', null, InputOption::VALUE_NONE, 'Forces installation from package sources when possible, including VCS information.'), new InputOption('prefer-dist', null, InputOption::VALUE_NONE, 'Forces installation from package dist even for dev versions.'), @@ -50,7 +50,9 @@ class RequireCommand extends InitCommand new InputOption('sort-packages', null, InputOption::VALUE_NONE, 'Sorts packages when adding/updating a new dependency'), )) ->setHelp(<< Date: Sun, 11 Jan 2015 23:09:41 +0000 Subject: [PATCH 37/73] Also clean up DYLD_LIBRARY_PATH before running git, refs #2146 --- src/Composer/Util/Git.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Composer/Util/Git.php b/src/Composer/Util/Git.php index 4a0c3933f..c3c5eb02c 100644 --- a/src/Composer/Util/Git.php +++ b/src/Composer/Util/Git.php @@ -169,6 +169,9 @@ class Git if (getenv('GIT_WORK_TREE')) { putenv('GIT_WORK_TREE'); } + + // clean up env for OSX, see https://github.com/composer/composer/issues/2146#issuecomment-35478940 + putenv("DYLD_LIBRARY_PATH"); } public static function getGitHubDomainsRegex(Config $config) From 9f0d36290bbbb81d0063225da4f8949d0fefc12c Mon Sep 17 00:00:00 2001 From: Vladimir Kartaviy Date: Mon, 12 Jan 2015 22:48:19 +0200 Subject: [PATCH 38/73] Added missing variable --- src/Composer/EventDispatcher/EventDispatcher.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Composer/EventDispatcher/EventDispatcher.php b/src/Composer/EventDispatcher/EventDispatcher.php index c5033124e..dff5456e1 100644 --- a/src/Composer/EventDispatcher/EventDispatcher.php +++ b/src/Composer/EventDispatcher/EventDispatcher.php @@ -44,6 +44,7 @@ class EventDispatcher protected $io; protected $loader; protected $process; + protected $listeners; /** * Constructor. From 395903863bf0659d074c900f0b162e21bd4e5212 Mon Sep 17 00:00:00 2001 From: Alexander Schwenn Date: Thu, 15 Jan 2015 22:33:31 +0100 Subject: [PATCH 39/73] Add 'info' alias for 'show' command --- src/Composer/Command/ShowCommand.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Composer/Command/ShowCommand.php b/src/Composer/Command/ShowCommand.php index 28ea81028..907e99f90 100644 --- a/src/Composer/Command/ShowCommand.php +++ b/src/Composer/Command/ShowCommand.php @@ -41,6 +41,7 @@ class ShowCommand extends Command { $this ->setName('show') + ->setAliases(array('info')) ->setDescription('Show information about packages') ->setDefinition(array( new InputArgument('package', InputArgument::OPTIONAL, 'Package to inspect'), From 9d84a9216350a39cfb7ce0ebc5809b6116cf0f60 Mon Sep 17 00:00:00 2001 From: SofHad Date: Fri, 16 Jan 2015 20:59:30 +0100 Subject: [PATCH 40/73] Fixed json syntax error --- doc/05-repositories.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/05-repositories.md b/doc/05-repositories.md index 975b473e5..80d15c561 100644 --- a/doc/05-repositories.md +++ b/doc/05-repositories.md @@ -122,7 +122,7 @@ JSON request body: ```json { "downloads": [ - {"name": "monolog/monolog", "version": "1.2.1.0"}, + {"name": "monolog/monolog", "version": "1.2.1.0"} ] } ``` From 296252330e5e449792058fc7240846d1a99c9366 Mon Sep 17 00:00:00 2001 From: Rob Bast Date: Mon, 19 Jan 2015 17:28:27 +0100 Subject: [PATCH 41/73] fix-token-retrying-itself --- src/Composer/Util/RemoteFilesystem.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Composer/Util/RemoteFilesystem.php b/src/Composer/Util/RemoteFilesystem.php index e03cf8ec8..455bda92e 100644 --- a/src/Composer/Util/RemoteFilesystem.php +++ b/src/Composer/Util/RemoteFilesystem.php @@ -343,7 +343,7 @@ class RemoteFilesystem { if ($this->config && in_array($this->originUrl, $this->config->get('github-domains'), true)) { $message = "\n".'Could not fetch '.$this->fileUrl.', enter your GitHub credentials '.($httpStatus === 404 ? 'to access private repos' : 'to go over the API rate limit'); - $gitHubUtil = new GitHub($this->io, $this->config, null, $this); + $gitHubUtil = new GitHub($this->io, $this->config, null); if (!$gitHubUtil->authorizeOAuth($this->originUrl) && (!$this->io->isInteractive() || !$gitHubUtil->authorizeOAuthInteractively($this->originUrl, $message)) ) { From 2a1a963b0064ad57172d4aa0fb649f964edf6e33 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Mon, 19 Jan 2015 17:56:20 +0000 Subject: [PATCH 42/73] support bitbucket URLs with plain http --- src/Composer/Repository/Vcs/GitBitbucketDriver.php | 4 ++-- src/Composer/Repository/Vcs/HgBitbucketDriver.php | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Composer/Repository/Vcs/GitBitbucketDriver.php b/src/Composer/Repository/Vcs/GitBitbucketDriver.php index 88a6d5454..68389dc33 100644 --- a/src/Composer/Repository/Vcs/GitBitbucketDriver.php +++ b/src/Composer/Repository/Vcs/GitBitbucketDriver.php @@ -33,7 +33,7 @@ class GitBitbucketDriver extends VcsDriver implements VcsDriverInterface */ public function initialize() { - preg_match('#^https://bitbucket\.org/([^/]+)/(.+?)\.git$#', $this->url, $match); + preg_match('#^https?://bitbucket\.org/([^/]+)/(.+?)\.git$#', $this->url, $match); $this->owner = $match[1]; $this->repository = $match[2]; $this->originUrl = 'bitbucket.org'; @@ -143,7 +143,7 @@ class GitBitbucketDriver extends VcsDriver implements VcsDriverInterface */ public static function supports(IOInterface $io, Config $config, $url, $deep = false) { - if (!preg_match('#^https://bitbucket\.org/([^/]+)/(.+?)\.git$#', $url)) { + if (!preg_match('#^https?://bitbucket\.org/([^/]+)/(.+?)\.git$#', $url)) { return false; } diff --git a/src/Composer/Repository/Vcs/HgBitbucketDriver.php b/src/Composer/Repository/Vcs/HgBitbucketDriver.php index 5e6f71241..cc2b386eb 100644 --- a/src/Composer/Repository/Vcs/HgBitbucketDriver.php +++ b/src/Composer/Repository/Vcs/HgBitbucketDriver.php @@ -33,7 +33,7 @@ class HgBitbucketDriver extends VcsDriver */ public function initialize() { - preg_match('#^https://bitbucket\.org/([^/]+)/([^/]+)/?$#', $this->url, $match); + preg_match('#^https?://bitbucket\.org/([^/]+)/([^/]+)/?$#', $this->url, $match); $this->owner = $match[1]; $this->repository = $match[2]; $this->originUrl = 'bitbucket.org'; @@ -153,7 +153,7 @@ class HgBitbucketDriver extends VcsDriver */ public static function supports(IOInterface $io, Config $config, $url, $deep = false) { - if (!preg_match('#^https://bitbucket\.org/([^/]+)/([^/]+)/?$#', $url)) { + if (!preg_match('#^https?://bitbucket\.org/([^/]+)/([^/]+)/?$#', $url)) { return false; } From 7bb85ff21e5f7989512190ba1f802733244be535 Mon Sep 17 00:00:00 2001 From: Damian Mooyman Date: Mon, 1 Dec 2014 18:09:35 +1300 Subject: [PATCH 43/73] Support aliases for numeric branches. Fixes #3461 --- doc/articles/aliases.md | 12 ++++++---- src/Composer/Package/Loader/ArrayLoader.php | 10 ++++++++- .../Package/Loader/ValidatingArrayLoader.php | 11 ++++++++++ .../Package/Version/VersionParser.php | 15 +++++++++++++ .../Test/Package/Loader/ArrayLoaderTest.php | 22 +++++++++++++++++++ .../Loader/ValidatingArrayLoaderTest.php | 15 +++++++++++++ .../Package/Version/VersionParserTest.php | 20 +++++++++++++++++ .../Package/Version/VersionSelectorTest.php | 2 ++ 8 files changed, 102 insertions(+), 5 deletions(-) diff --git a/doc/articles/aliases.md b/doc/articles/aliases.md index 2b436322f..79c573d3d 100644 --- a/doc/articles/aliases.md +++ b/doc/articles/aliases.md @@ -38,10 +38,14 @@ specifying a `branch-alias` field under `extra` in `composer.json`: } ``` -The branch version must begin with `dev-` (non-comparable version), the alias -must be a comparable dev version (i.e. start with numbers, and end with -`.x-dev`). The `branch-alias` must be present on the branch that it references. -For `dev-master`, you need to commit it on the `master` branch. +If you alias a non-comparible version (such as dev-develop) `dev-` must prefix the +branch name. You may also alias a comparible version (i.e. start with numbers, +and end with `.x-dev`), but only as a more specific version. +For example, 1.x-dev could be aliased as 1.2.x-dev. + +The alias must be a comparable dev version, and the `branch-alias` must be present on +the branch that it references. For `dev-master`, you need to commit it on the +`master` branch. As a result, anyone can now require `1.0.*` and it will happily install `dev-master`. diff --git a/src/Composer/Package/Loader/ArrayLoader.php b/src/Composer/Package/Loader/ArrayLoader.php index 243b7b574..558a24e35 100644 --- a/src/Composer/Package/Loader/ArrayLoader.php +++ b/src/Composer/Package/Loader/ArrayLoader.php @@ -224,7 +224,7 @@ class ArrayLoader implements LoaderInterface */ public function getBranchAlias(array $config) { - if ('dev-' !== substr($config['version'], 0, 4) + if (('dev-' !== substr($config['version'], 0, 4) && '-dev' !== substr($config['version'], -4)) || !isset($config['extra']['branch-alias']) || !is_array($config['extra']['branch-alias']) ) { @@ -248,6 +248,14 @@ class ArrayLoader implements LoaderInterface continue; } + // If using numeric aliases ensure the alias is a valid subversion + if(($sourcePrefix = $this->versionParser->parseNumericAliasPrefix($sourceBranch)) + && ($targetPrefix = $this->versionParser->parseNumericAliasPrefix($targetBranch)) + && (stripos($targetPrefix, $sourcePrefix) !== 0) + ) { + continue; + } + return $validatedTargetBranch; } } diff --git a/src/Composer/Package/Loader/ValidatingArrayLoader.php b/src/Composer/Package/Loader/ValidatingArrayLoader.php index 3493d3d5b..9a6f4dd32 100644 --- a/src/Composer/Package/Loader/ValidatingArrayLoader.php +++ b/src/Composer/Package/Loader/ValidatingArrayLoader.php @@ -251,6 +251,17 @@ class ValidatingArrayLoader implements LoaderInterface if ('-dev' !== substr($validatedTargetBranch, -4)) { $this->warnings[] = 'extra.branch-alias.'.$sourceBranch.' : the target branch ('.$targetBranch.') must be a parseable number like 2.0-dev'; unset($this->config['extra']['branch-alias'][$sourceBranch]); + + continue; + } + + // If using numeric aliases ensure the alias is a valid subversion + if(($sourcePrefix = $this->versionParser->parseNumericAliasPrefix($sourceBranch)) + && ($targetPrefix = $this->versionParser->parseNumericAliasPrefix($targetBranch)) + && (stripos($targetPrefix, $sourcePrefix) !== 0) + ) { + $this->warnings[] = 'extra.branch-alias.'.$sourceBranch.' : the target branch ('.$targetBranch.') is not a valid numeric alias for this version'; + unset($this->config['extra']['branch-alias'][$sourceBranch]); } } } diff --git a/src/Composer/Package/Version/VersionParser.php b/src/Composer/Package/Version/VersionParser.php index 2a2c38371..3925e7e65 100644 --- a/src/Composer/Package/Version/VersionParser.php +++ b/src/Composer/Package/Version/VersionParser.php @@ -169,6 +169,21 @@ class VersionParser throw new \UnexpectedValueException('Invalid version string "'.$version.'"'.$extraMessage); } + /** + * Extract numeric prefix from alias, if it is in numeric format, suitable for + * version comparison + * + * @param string $branch Branch name (e.g. 2.1.x-dev) + * @return string|false Numeric prefix if present (e.g. 2.1.) or false + */ + public function parseNumericAliasPrefix($branch) { + if(preg_match('/^(?(\d+\\.)*\d+).x-dev$/i', $branch, $matches)) { + return $matches['version']."."; + } else { + return false; + } + } + /** * Normalizes a branch name to be able to perform comparisons on it * diff --git a/tests/Composer/Test/Package/Loader/ArrayLoaderTest.php b/tests/Composer/Test/Package/Loader/ArrayLoaderTest.php index 6e4e2f5ee..4b98ae26d 100644 --- a/tests/Composer/Test/Package/Loader/ArrayLoaderTest.php +++ b/tests/Composer/Test/Package/Loader/ArrayLoaderTest.php @@ -138,6 +138,28 @@ class ArrayLoaderTest extends \PHPUnit_Framework_TestCase $this->assertInstanceOf('Composer\Package\AliasPackage', $package); $this->assertEquals('1.0.x-dev', $package->getPrettyVersion()); + + $config = array( + 'name' => 'B', + 'version' => '4.x-dev', + 'extra' => array('branch-alias' => array('4.x-dev' => '4.0.x-dev')), + ); + + $package = $this->loader->load($config); + + $this->assertInstanceOf('Composer\Package\AliasPackage', $package); + $this->assertEquals('4.0.x-dev', $package->getPrettyVersion()); + + $config = array( + 'name' => 'C', + 'version' => '4.x-dev', + 'extra' => array('branch-alias' => array('4.x-dev' => '3.4.x-dev')), + ); + + $package = $this->loader->load($config); + + $this->assertInstanceOf('Composer\Package\CompletePackage', $package); + $this->assertEquals('4.x-dev', $package->getPrettyVersion()); } public function testAbandoned() diff --git a/tests/Composer/Test/Package/Loader/ValidatingArrayLoaderTest.php b/tests/Composer/Test/Package/Loader/ValidatingArrayLoaderTest.php index 23c47c3c7..2b0829759 100644 --- a/tests/Composer/Test/Package/Loader/ValidatingArrayLoaderTest.php +++ b/tests/Composer/Test/Package/Loader/ValidatingArrayLoaderTest.php @@ -140,6 +140,7 @@ class ValidatingArrayLoaderTest extends \PHPUnit_Framework_TestCase 'branch-alias' => array( 'dev-master' => '2.0-dev', 'dev-old' => '1.0.x-dev', + '3.x-dev' => '3.1.x-dev' ), ), 'bin' => array( @@ -324,6 +325,20 @@ class ValidatingArrayLoaderTest extends \PHPUnit_Framework_TestCase ), false ), + array( + array( + 'name' => 'foo/bar', + 'extra' => array( + 'branch-alias' => array( + '5.x-dev' => '3.1.x-dev' + ), + ) + ), + array( + 'extra.branch-alias.5.x-dev : the target branch (3.1.x-dev) is not a valid numeric alias for this version' + ), + false + ), ); } } diff --git a/tests/Composer/Test/Package/Version/VersionParserTest.php b/tests/Composer/Test/Package/Version/VersionParserTest.php index 88058f6aa..c52ec1382 100644 --- a/tests/Composer/Test/Package/Version/VersionParserTest.php +++ b/tests/Composer/Test/Package/Version/VersionParserTest.php @@ -76,6 +76,26 @@ class VersionParserTest extends \PHPUnit_Framework_TestCase $this->assertSame($expected, $parser->normalize($input)); } + public function numericAliasVersions() { + return array( + array('0.x-dev', '0.'), + array('1.0.x-dev', '1.0.'), + array('1.x-dev', '1.'), + array('1.2.x-dev', '1.2.'), + array('dev-develop', false), + array('dev-master', false), + ); + } + + /** + * @dataProvider numericAliasVersions + */ + public function testParseNumericAliasPrefix($input, $expected) + { + $parser = new VersionParser; + $this->assertSame($expected, $parser->parseNumericAliasPrefix($input)); + } + public function successfulNormalizedVersions() { return array( diff --git a/tests/Composer/Test/Package/Version/VersionSelectorTest.php b/tests/Composer/Test/Package/Version/VersionSelectorTest.php index 90f820e8f..fb3a6f666 100644 --- a/tests/Composer/Test/Package/Version/VersionSelectorTest.php +++ b/tests/Composer/Test/Package/Version/VersionSelectorTest.php @@ -115,6 +115,8 @@ class VersionSelectorTest extends \PHPUnit_Framework_TestCase array('dev-master', true, 'dev', '~2.1@dev', '2.1.x-dev'), array('dev-master', true, 'dev', '~2.1@dev', '2.1.3.x-dev'), array('dev-master', true, 'dev', '~2.0@dev', '2.x-dev'), + // numeric alias + array('3.x-dev', true, 'dev', '~3.0@dev', '3.0.x-dev'), ); } From ea3736522d4f99e93e349d6e7491a443a6aac8d3 Mon Sep 17 00:00:00 2001 From: Robin Hallabro Date: Tue, 20 Jan 2015 09:05:40 +0100 Subject: [PATCH 44/73] Update documententation for version shorthand parsing --- doc/02-libraries.md | 4 ++-- doc/04-schema.md | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/doc/02-libraries.md b/doc/02-libraries.md index 561f3aa79..913f996b7 100644 --- a/doc/02-libraries.md +++ b/doc/02-libraries.md @@ -77,8 +77,8 @@ you can just add a `version` field: For every tag that looks like a version, a package version of that tag will be created. It should match 'X.Y.Z' or 'vX.Y.Z', with an optional suffix -of `-patch`, `-alpha`, `-beta` or `-RC`. The suffixes can also be followed by -a number. +of `-patch` (`-p`), `-alpha` (`-a`), `-beta` (`-b`) or `-RC`. The suffixes +can also be followed by a number. Here are a few examples of valid tag names: diff --git a/doc/04-schema.md b/doc/04-schema.md index 8662ca855..3acfef735 100644 --- a/doc/04-schema.md +++ b/doc/04-schema.md @@ -54,8 +54,8 @@ The version of the package. In most cases this is not required and should be omitted (see below). This must follow the format of `X.Y.Z` or `vX.Y.Z` with an optional suffix -of `-dev`, `-patch`, `-alpha`, `-beta` or `-RC`. The patch, alpha, beta and -RC suffixes can also be followed by a number. +of `-dev`, `-patch` (`-p`), `-alpha` (`-a`), `-beta` (`-b`) or `-RC`. +The patch, alpha, beta and RC suffixes can also be followed by a number. Examples: @@ -67,6 +67,7 @@ Examples: - 1.0.0-alpha3 - 1.0.0-beta2 - 1.0.0-RC5 +- v2.0.4-p1 Optional if the package repository can infer the version from somewhere, such as the VCS tag name in the VCS repository. In that case it is also recommended From af161e242e0990f0c64ad2acc44ae0db38f522e9 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Tue, 20 Jan 2015 09:55:18 +0000 Subject: [PATCH 45/73] Add more troubleshooting info, refs #3457 --- doc/articles/troubleshooting.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/doc/articles/troubleshooting.md b/doc/articles/troubleshooting.md index 922526a52..4de3ad19e 100644 --- a/doc/articles/troubleshooting.md +++ b/doc/articles/troubleshooting.md @@ -114,8 +114,9 @@ php -d memory_limit=-1 composer.phar <...> ## "The system cannot find the path specified" (Windows) 1. Open regedit. -2. Search for an ```AutoRun``` key inside ```HKEY_LOCAL_MACHINE\Software\Microsoft\Command Processor``` - or ```HKEY_CURRENT_USER\Software\Microsoft\Command Processor```. +2. Search for an `AutoRun` key inside `HKEY_LOCAL_MACHINE\Software\Microsoft\Command Processor`, + `HKEY_CURRENT_USER\Software\Microsoft\Command Processor` + or `HKEY_LOCAL_MACHINE\Software\Wow6432Node\Microsoft\Command Processor`. 3. Check if it contains any path to non-existent file, if it's the case, just remove them. ## API rate limit and OAuth tokens From 3b678ee37939e4a5cd0a7a1eddba5c11d282a879 Mon Sep 17 00:00:00 2001 From: Dmitry Tarasov Date: Tue, 20 Jan 2015 13:03:55 +0300 Subject: [PATCH 46/73] Fix error handling for incorrect "repositories" array --- src/Composer/Config.php | 2 +- tests/Composer/Test/ConfigTest.php | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/Composer/Config.php b/src/Composer/Config.php index 86e318765..a144467aa 100644 --- a/src/Composer/Config.php +++ b/src/Composer/Config.php @@ -124,7 +124,7 @@ class Config } // disable a repository with an anonymous {"name": false} repo - if (1 === count($repository) && false === current($repository)) { + if (is_array($repository) && 1 === count($repository) && false === current($repository)) { unset($this->repositories[key($repository)]); continue; } diff --git a/tests/Composer/Test/ConfigTest.php b/tests/Composer/Test/ConfigTest.php index 99970125c..e50af5e87 100644 --- a/tests/Composer/Test/ConfigTest.php +++ b/tests/Composer/Test/ConfigTest.php @@ -97,6 +97,18 @@ class ConfigTest extends \PHPUnit_Framework_TestCase ), ); + $data['incorrect local config does not cause ErrorException'] = array( + array( + 'packagist' => array('type' => 'composer', 'url' => 'https?://packagist.org', 'allow_ssl_downgrade' => true), + 'type' => 'vcs', + 'url' => 'http://example.com', + ), + array( + 'type' => 'vcs', + 'url' => 'http://example.com', + ), + ); + return $data; } From cd38d1e096b403229363fce98fd671c71f644649 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Tue, 20 Jan 2015 10:26:10 +0000 Subject: [PATCH 47/73] Tweaks to also support 1.0-dev style aliases, refs #3480 --- .../Package/Version/VersionParser.php | 9 ++++---- .../Test/Package/Loader/ArrayLoaderTest.php | 22 +++++++++++++++++++ .../Loader/ValidatingArrayLoaderTest.php | 14 ++++++++++++ .../Package/Version/VersionParserTest.php | 17 ++++++++------ .../Package/Version/VersionSelectorTest.php | 2 ++ 5 files changed, 53 insertions(+), 11 deletions(-) diff --git a/src/Composer/Package/Version/VersionParser.php b/src/Composer/Package/Version/VersionParser.php index 3925e7e65..d546b2655 100644 --- a/src/Composer/Package/Version/VersionParser.php +++ b/src/Composer/Package/Version/VersionParser.php @@ -176,12 +176,13 @@ class VersionParser * @param string $branch Branch name (e.g. 2.1.x-dev) * @return string|false Numeric prefix if present (e.g. 2.1.) or false */ - public function parseNumericAliasPrefix($branch) { - if(preg_match('/^(?(\d+\\.)*\d+).x-dev$/i', $branch, $matches)) { + public function parseNumericAliasPrefix($branch) + { + if (preg_match('/^(?(\d+\\.)*\d+)(?:\.x)?-dev$/i', $branch, $matches)) { return $matches['version']."."; - } else { - return false; } + + return false; } /** diff --git a/tests/Composer/Test/Package/Loader/ArrayLoaderTest.php b/tests/Composer/Test/Package/Loader/ArrayLoaderTest.php index 4b98ae26d..1491571a1 100644 --- a/tests/Composer/Test/Package/Loader/ArrayLoaderTest.php +++ b/tests/Composer/Test/Package/Loader/ArrayLoaderTest.php @@ -139,6 +139,17 @@ class ArrayLoaderTest extends \PHPUnit_Framework_TestCase $this->assertInstanceOf('Composer\Package\AliasPackage', $package); $this->assertEquals('1.0.x-dev', $package->getPrettyVersion()); + $config = array( + 'name' => 'A', + 'version' => 'dev-master', + 'extra' => array('branch-alias' => array('dev-master' => '1.0-dev')), + ); + + $package = $this->loader->load($config); + + $this->assertInstanceOf('Composer\Package\AliasPackage', $package); + $this->assertEquals('1.0.x-dev', $package->getPrettyVersion()); + $config = array( 'name' => 'B', 'version' => '4.x-dev', @@ -150,6 +161,17 @@ class ArrayLoaderTest extends \PHPUnit_Framework_TestCase $this->assertInstanceOf('Composer\Package\AliasPackage', $package); $this->assertEquals('4.0.x-dev', $package->getPrettyVersion()); + $config = array( + 'name' => 'B', + 'version' => '4.x-dev', + 'extra' => array('branch-alias' => array('4.x-dev' => '4.0-dev')), + ); + + $package = $this->loader->load($config); + + $this->assertInstanceOf('Composer\Package\AliasPackage', $package); + $this->assertEquals('4.0.x-dev', $package->getPrettyVersion()); + $config = array( 'name' => 'C', 'version' => '4.x-dev', diff --git a/tests/Composer/Test/Package/Loader/ValidatingArrayLoaderTest.php b/tests/Composer/Test/Package/Loader/ValidatingArrayLoaderTest.php index 2b0829759..32c55bd40 100644 --- a/tests/Composer/Test/Package/Loader/ValidatingArrayLoaderTest.php +++ b/tests/Composer/Test/Package/Loader/ValidatingArrayLoaderTest.php @@ -339,6 +339,20 @@ class ValidatingArrayLoaderTest extends \PHPUnit_Framework_TestCase ), false ), + array( + array( + 'name' => 'foo/bar', + 'extra' => array( + 'branch-alias' => array( + '5.x-dev' => '3.1-dev' + ), + ) + ), + array( + 'extra.branch-alias.5.x-dev : the target branch (3.1-dev) is not a valid numeric alias for this version' + ), + false + ), ); } } diff --git a/tests/Composer/Test/Package/Version/VersionParserTest.php b/tests/Composer/Test/Package/Version/VersionParserTest.php index c52ec1382..13920e2f0 100644 --- a/tests/Composer/Test/Package/Version/VersionParserTest.php +++ b/tests/Composer/Test/Package/Version/VersionParserTest.php @@ -68,32 +68,35 @@ class VersionParserTest extends \PHPUnit_Framework_TestCase } /** - * @dataProvider successfulNormalizedVersions + * @dataProvider numericAliasVersions */ - public function testNormalizeSucceeds($input, $expected) + public function testParseNumericAliasPrefix($input, $expected) { $parser = new VersionParser; - $this->assertSame($expected, $parser->normalize($input)); + $this->assertSame($expected, $parser->parseNumericAliasPrefix($input)); } - public function numericAliasVersions() { + public function numericAliasVersions() + { return array( array('0.x-dev', '0.'), array('1.0.x-dev', '1.0.'), array('1.x-dev', '1.'), array('1.2.x-dev', '1.2.'), + array('1.2-dev', '1.2.'), + array('1-dev', '1.'), array('dev-develop', false), array('dev-master', false), ); } /** - * @dataProvider numericAliasVersions + * @dataProvider successfulNormalizedVersions */ - public function testParseNumericAliasPrefix($input, $expected) + public function testNormalizeSucceeds($input, $expected) { $parser = new VersionParser; - $this->assertSame($expected, $parser->parseNumericAliasPrefix($input)); + $this->assertSame($expected, $parser->normalize($input)); } public function successfulNormalizedVersions() diff --git a/tests/Composer/Test/Package/Version/VersionSelectorTest.php b/tests/Composer/Test/Package/Version/VersionSelectorTest.php index fb3a6f666..6feb207a7 100644 --- a/tests/Composer/Test/Package/Version/VersionSelectorTest.php +++ b/tests/Composer/Test/Package/Version/VersionSelectorTest.php @@ -113,10 +113,12 @@ class VersionSelectorTest extends \PHPUnit_Framework_TestCase array('3.1.2-dev', true, 'dev', '3.1.2-dev'), // dev packages with alias inherit the alias array('dev-master', true, 'dev', '~2.1@dev', '2.1.x-dev'), + array('dev-master', true, 'dev', '~2.1@dev', '2.1-dev'), array('dev-master', true, 'dev', '~2.1@dev', '2.1.3.x-dev'), array('dev-master', true, 'dev', '~2.0@dev', '2.x-dev'), // numeric alias array('3.x-dev', true, 'dev', '~3.0@dev', '3.0.x-dev'), + array('3.x-dev', true, 'dev', '~3.0@dev', '3.0-dev'), ); } From f50cfe6d4539b7521467fc7fca7b46d29299ab2c Mon Sep 17 00:00:00 2001 From: Dmitry Tarasov Date: Tue, 20 Jan 2015 13:44:29 +0300 Subject: [PATCH 48/73] Improve error message for case with incorrect "repositories" --- src/Composer/Factory.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Composer/Factory.php b/src/Composer/Factory.php index f2aa27e22..fdb5982e4 100644 --- a/src/Composer/Factory.php +++ b/src/Composer/Factory.php @@ -167,10 +167,10 @@ class Factory foreach ($config->getRepositories() as $index => $repo) { if (!is_array($repo)) { - throw new \UnexpectedValueException('Repository '.$index.' ('.json_encode($repo).') should be an array, '.gettype($repo).' given'); + throw new \UnexpectedValueException('Repository "'.$index.'" ('.json_encode($repo).') should be an array, '.gettype($repo).' given'); } if (!isset($repo['type'])) { - throw new \UnexpectedValueException('Repository '.$index.' ('.json_encode($repo).') must have a type defined'); + throw new \UnexpectedValueException('Repository "'.$index.'" ('.json_encode($repo).') must have a type defined'); } $name = is_int($index) && isset($repo['url']) ? preg_replace('{^https?://}i', '', $repo['url']) : $index; while (isset($repos[$name])) { From c8011af219bbfe832d3dc7eeba447e12fe0df4c7 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Tue, 20 Jan 2015 10:49:03 +0000 Subject: [PATCH 49/73] Improve message some more, refs #3655 --- src/Composer/Factory.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Composer/Factory.php b/src/Composer/Factory.php index fdb5982e4..a6597afd7 100644 --- a/src/Composer/Factory.php +++ b/src/Composer/Factory.php @@ -166,6 +166,9 @@ class Factory } foreach ($config->getRepositories() as $index => $repo) { + if (is_string($repo)) { + throw new \UnexpectedValueException('Repositories should be an array of repository defintions, only a single repository was given'); + } if (!is_array($repo)) { throw new \UnexpectedValueException('Repository "'.$index.'" ('.json_encode($repo).') should be an array, '.gettype($repo).' given'); } From 825b4b9c63a29c586d005de8dbbcfdfeb86bbf6f Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Tue, 20 Jan 2015 16:39:06 +0000 Subject: [PATCH 50/73] Improve error message and fix typo, closes #3657 --- src/Composer/Factory.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Composer/Factory.php b/src/Composer/Factory.php index a6597afd7..3f0041a85 100644 --- a/src/Composer/Factory.php +++ b/src/Composer/Factory.php @@ -167,7 +167,7 @@ class Factory foreach ($config->getRepositories() as $index => $repo) { if (is_string($repo)) { - throw new \UnexpectedValueException('Repositories should be an array of repository defintions, only a single repository was given'); + throw new \UnexpectedValueException('"repositories" should be an array of repository definitions, only a single repository was given'); } if (!is_array($repo)) { throw new \UnexpectedValueException('Repository "'.$index.'" ('.json_encode($repo).') should be an array, '.gettype($repo).' given'); From 506d923e7c1e7a6d06467a35b8af3804ca5767d3 Mon Sep 17 00:00:00 2001 From: Dmitry Tarasov Date: Thu, 22 Jan 2015 11:26:25 +0300 Subject: [PATCH 51/73] #3663 fix error message for config command --- src/Composer/Command/ConfigCommand.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Composer/Command/ConfigCommand.php b/src/Composer/Command/ConfigCommand.php index 4d52c8473..9d27464b5 100644 --- a/src/Composer/Command/ConfigCommand.php +++ b/src/Composer/Command/ConfigCommand.php @@ -137,7 +137,7 @@ EOT } if (!$this->configFile->exists()) { - throw new \RuntimeException('No composer.json found in the current directory'); + throw new \RuntimeException("File '$configFile' cannot be found in the current directory"); } } From e047ca994448d319952a1639b86e4d521f724dfd Mon Sep 17 00:00:00 2001 From: Dmitry Tarasov Date: Fri, 23 Jan 2015 10:52:53 +0300 Subject: [PATCH 52/73] #3665 fix exception message coding style --- src/Composer/Command/ConfigCommand.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Composer/Command/ConfigCommand.php b/src/Composer/Command/ConfigCommand.php index 9d27464b5..c65afdb7d 100644 --- a/src/Composer/Command/ConfigCommand.php +++ b/src/Composer/Command/ConfigCommand.php @@ -137,7 +137,7 @@ EOT } if (!$this->configFile->exists()) { - throw new \RuntimeException("File '$configFile' cannot be found in the current directory"); + throw new \RuntimeException(sprintf('File "%s" cannot be found in the current directory', $configFile)); } } From 59141c8663b80c0baeed40c268af07ff54fd6d9c Mon Sep 17 00:00:00 2001 From: Josh Pollock Date: Sun, 25 Jan 2015 17:05:21 -0500 Subject: [PATCH 53/73] Add note about /usr not existing in OSX Yosemite by default. BTW Seriously Apple? --- doc/00-intro.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/00-intro.md b/doc/00-intro.md index c1bafa3cd..a927f35fb 100644 --- a/doc/00-intro.md +++ b/doc/00-intro.md @@ -107,6 +107,8 @@ mv composer.phar /usr/local/bin/composer > **Note:** If the above fails due to permissions, run the `mv` line > again with sudo. +> **Note:** In OSX Yosemite the `/usr` directory does not exist by default. If you recive the error "/usr/local/bin/composer: No such file or directory" then you must create `/usr/local/bin/composer/` manually. + Then, just run `composer` in order to run Composer instead of `php composer.phar`. ## Installation - Windows From 5e5eb069dceef1c584a4c9fa570b0dfe61abcf55 Mon Sep 17 00:00:00 2001 From: Nils Adermann Date: Tue, 27 Jan 2015 16:56:39 +0100 Subject: [PATCH 54/73] Don't use a regex to parse installer tests to allow for longer tests --- tests/Composer/Test/InstallerTest.php | 141 ++++++++++++++++---------- 1 file changed, 89 insertions(+), 52 deletions(-) diff --git a/tests/Composer/Test/InstallerTest.php b/tests/Composer/Test/InstallerTest.php index 9bf2c01a7..2c77f9bc3 100644 --- a/tests/Composer/Test/InstallerTest.php +++ b/tests/Composer/Test/InstallerTest.php @@ -241,10 +241,10 @@ class InstallerTest extends TestCase } $installationManager = $composer->getInstallationManager(); - $this->assertSame($expect, implode("\n", $installationManager->getTrace())); + $this->assertSame(rtrim($expect), implode("\n", $installationManager->getTrace())); if ($expectOutput) { - $this->assertEquals($expectOutput, $output); + $this->assertEquals(rtrim($expectOutput), rtrim($output)); } } @@ -258,21 +258,7 @@ class InstallerTest extends TestCase continue; } - $test = file_get_contents($file->getRealpath()); - - $content = '(?:.(?!--[A-Z]))+'; - $pattern = '{^ - --TEST--\s*(?P.*?)\s* - (?:--CONDITION--\s*(?P'.$content.'))?\s* - --COMPOSER--\s*(?P'.$content.')\s* - (?:--LOCK--\s*(?P'.$content.'))?\s* - (?:--INSTALLED--\s*(?P'.$content.'))?\s* - --RUN--\s*(?P.*?)\s* - (?:--EXPECT-LOCK--\s*(?P'.$content.'))?\s* - (?:--EXPECT-OUTPUT--\s*(?P'.$content.'))?\s* - (?:--EXPECT-EXIT-CODE--\s*(?P\d+))?\s* - --EXPECT--\s*(?P.*?)\s* - $}xs'; + $testData = $this->readTestFile($file, $fixturesDir); $installed = array(); $installedDev = array(); @@ -280,48 +266,44 @@ class InstallerTest extends TestCase $expectLock = array(); $expectExitCode = 0; - if (preg_match($pattern, $test, $match)) { - try { - $message = $match['test']; - $condition = !empty($match['condition']) ? $match['condition'] : null; - $composer = JsonFile::parseJson($match['composer']); + try { + $message = $testData['TEST']; + $condition = !empty($testData['CONDITION']) ? $testData['CONDITION'] : null; + $composer = JsonFile::parseJson($testData['COMPOSER']); - if (isset($composer['repositories'])) { - foreach ($composer['repositories'] as &$repo) { - if ($repo['type'] !== 'composer') { - continue; - } - - // Change paths like file://foobar to file:///path/to/fixtures - if (preg_match('{^file://[^/]}', $repo['url'])) { - $repo['url'] = 'file://' . strtr($fixturesDir, '\\', '/') . '/' . substr($repo['url'], 7); - } - - unset($repo); + if (isset($composer['repositories'])) { + foreach ($composer['repositories'] as &$repo) { + if ($repo['type'] !== 'composer') { + continue; } - } - if (!empty($match['lock'])) { - $lock = JsonFile::parseJson($match['lock']); - if (!isset($lock['hash'])) { - $lock['hash'] = md5(json_encode($composer)); + // Change paths like file://foobar to file:///path/to/fixtures + if (preg_match('{^file://[^/]}', $repo['url'])) { + $repo['url'] = 'file://' . strtr($fixturesDir, '\\', '/') . '/' . substr($repo['url'], 7); } + + unset($repo); } - if (!empty($match['installed'])) { - $installed = JsonFile::parseJson($match['installed']); - } - $run = $match['run']; - if (!empty($match['expectLock'])) { - $expectLock = JsonFile::parseJson($match['expectLock']); + } + + if (!empty($testData['LOCK'])) { + $lock = JsonFile::parseJson($testData['LOCK']); + if (!isset($lock['hash'])) { + $lock['hash'] = md5(json_encode($composer)); } - $expectOutput = $match['expectOutput']; - $expect = $match['expect']; - $expectExitCode = (int) $match['expectExitCode']; - } catch (\Exception $e) { - die(sprintf('Test "%s" is not valid: '.$e->getMessage(), str_replace($fixturesDir.'/', '', $file))); } - } else { - die(sprintf('Test "%s" is not valid, did not match the expected format.', str_replace($fixturesDir.'/', '', $file))); + if (!empty($testData['INSTALLED'])) { + $installed = JsonFile::parseJson($testData['INSTALLED']); + } + $run = $testData['RUN']; + if (!empty($testData['EXPECT-LOCK'])) { + $expectLock = JsonFile::parseJson($testData['EXPECT-LOCK']); + } + $expectOutput = isset($testData['EXPECT-OUTPUT']) ? $testData['EXPECT-OUTPUT'] : null; + $expect = $testData['EXPECT']; + $expectExitCode = isset($testData['EXPECT-EXIT-CODE']) ? (int) $testData['EXPECT-EXIT-CODE'] : 0; + } catch (\Exception $e) { + die(sprintf('Test "%s" is not valid: '.$e->getMessage(), str_replace($fixturesDir.'/', '', $file))); } $tests[basename($file)] = array(str_replace($fixturesDir.'/', '', $file), $message, $condition, $composer, $lock, $installed, $run, $expectLock, $expectOutput, $expect, $expectExitCode); @@ -329,4 +311,59 @@ class InstallerTest extends TestCase return $tests; } + + protected function readTestFile(\SplFileInfo $file, $fixturesDir) + { + $tokens = preg_split('#(?:^|\n*)--([A-Z-]+)--\n#', file_get_contents($file->getRealPath()), null, PREG_SPLIT_DELIM_CAPTURE); + + $sectionInfo = array( + 'TEST' => true, + 'CONDITION' => false, + 'COMPOSER' => true, + 'LOCK' => false, + 'INSTALLED' => false, + 'RUN' => true, + 'EXPECT-LOCK' => false, + 'EXPECT-OUTPUT' => false, + 'EXPECT-EXIT-CODE' => false, + 'EXPECT' => true, + ); + + $section = null; + foreach ($tokens as $i => $token) + { + if (null === $section && empty($token)) { + continue; // skip leading blank + } + + if (null === $section) { + if (!isset($sectionInfo[$token])) { + throw new \RuntimeException(sprintf( + 'The test file "%s" must not contain a section named "%s".', + str_replace($fixturesDir.'/', '', $file), + $token + )); + } + $section = $token; + continue; + } + + $sectionData = $token; + + $data[$section] = $sectionData; + $section = $sectionData = null; + } + + foreach ($sectionInfo as $section => $required) { + if ($required && !isset($data[$section])) { + throw new \RuntimeException(sprintf( + 'The test file "%s" must have a section named "%s".', + str_replace($fixturesDir.'/', '', $file), + $section + )); + } + } + + return $data; + } } From 82831bec130346f6c00446e19ce15a7c24003606 Mon Sep 17 00:00:00 2001 From: findstar Date: Wed, 28 Jan 2015 15:07:44 +0900 Subject: [PATCH 55/73] I think 'dump-autoload' command is more proper. --- doc/01-basic-usage.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/01-basic-usage.md b/doc/01-basic-usage.md index d83e79aed..ef72f556c 100644 --- a/doc/01-basic-usage.md +++ b/doc/01-basic-usage.md @@ -213,7 +213,7 @@ You define a mapping from namespaces to directories. The `src` directory would be in your project root, on the same level as `vendor` directory is. An example filename would be `src/Foo.php` containing an `Acme\Foo` class. -After adding the `autoload` field, you have to re-run `install` to re-generate +After adding the `autoload` field, you have to re-run `dump-autoload` to re-generate the `vendor/autoload.php` file. Including that file will also return the autoloader instance, so you can store From bb0a2df293807b04410477abefcd92731e7f04d0 Mon Sep 17 00:00:00 2001 From: Xavier Fornes Date: Wed, 28 Jan 2015 08:49:38 +0100 Subject: [PATCH 56/73] fix for issue #3657 ConsoleIO writing a message which contains end of lines characters --- src/Composer/IO/ConsoleIO.php | 14 ++++++++------ tests/Composer/Test/IO/ConsoleIOTest.php | 24 ++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/src/Composer/IO/ConsoleIO.php b/src/Composer/IO/ConsoleIO.php index 491a6b7fb..78b271356 100644 --- a/src/Composer/IO/ConsoleIO.php +++ b/src/Composer/IO/ConsoleIO.php @@ -97,12 +97,14 @@ class ConsoleIO extends BaseIO { if (null !== $this->startTime) { $messages = (array) $messages; - $messages[0] = sprintf( - '[%.1fMB/%.2fs] %s', - memory_get_usage() / 1024 / 1024, - microtime(true) - $this->startTime, - $messages[0] - ); + $messages = array_map(function (&$message) { + return sprintf( + '[%.1fMB/%.2fs] %s', + memory_get_usage() / 1024 / 1024, + microtime(true) - $this->startTime, + $message + ); + }, $messages); } $this->output->write($messages, $newline); $this->lastMessage = join($newline ? "\n" : '', (array) $messages); diff --git a/tests/Composer/Test/IO/ConsoleIOTest.php b/tests/Composer/Test/IO/ConsoleIOTest.php index 6ce95b0ac..8c9fad5fa 100644 --- a/tests/Composer/Test/IO/ConsoleIOTest.php +++ b/tests/Composer/Test/IO/ConsoleIOTest.php @@ -49,6 +49,30 @@ class ConsoleIOTest extends TestCase $consoleIO->write('some information about something', false); } + public function testWriteWithMultipleLineStringWhenDebugging() + { + $inputMock = $this->getMock('Symfony\Component\Console\Input\InputInterface'); + $outputMock = $this->getMock('Symfony\Component\Console\Output\OutputInterface'); + $outputMock->expects($this->once()) + ->method('write') + ->with( + $this->callback(function($messages){ + $this->assertRegExp("[(.*)/(.*) First line]", $messages[0]); + $this->assertRegExp("[(.*)/(.*) Second line]", $messages[1]); + return true; + }), + $this->equalTo(false) + ); + $helperMock = $this->getMock('Symfony\Component\Console\Helper\HelperSet'); + + $consoleIO = new ConsoleIO($inputMock, $outputMock, $helperMock); + $startTime = microtime(true); + $consoleIO->enableDebugging($startTime); + + $example = explode('\n', 'First line\nSecond lines'); + $consoleIO->write($example, false); + } + public function testOverwrite() { $inputMock = $this->getMock('Symfony\Component\Console\Input\InputInterface'); From 8ba8580a28a4b122ee002bd31e8b87df79f32960 Mon Sep 17 00:00:00 2001 From: Xavier Fornes Date: Wed, 28 Jan 2015 11:46:38 +0100 Subject: [PATCH 57/73] fix test implementation for php 5.3 refs issue #3657 --- tests/Composer/Test/IO/ConsoleIOTest.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/Composer/Test/IO/ConsoleIOTest.php b/tests/Composer/Test/IO/ConsoleIOTest.php index 8c9fad5fa..c83ec6296 100644 --- a/tests/Composer/Test/IO/ConsoleIOTest.php +++ b/tests/Composer/Test/IO/ConsoleIOTest.php @@ -57,9 +57,9 @@ class ConsoleIOTest extends TestCase ->method('write') ->with( $this->callback(function($messages){ - $this->assertRegExp("[(.*)/(.*) First line]", $messages[0]); - $this->assertRegExp("[(.*)/(.*) Second line]", $messages[1]); - return true; + $result = preg_match("[(.*)/(.*) First line]", $messages[0]) > 0; + $result &= preg_match("[(.*)/(.*) Second line]", $messages[1]) > 0; + return $result; }), $this->equalTo(false) ); From 3f59c007f776fde89a1c11e2776a9fde3a8ae378 Mon Sep 17 00:00:00 2001 From: Xavier Fornes Date: Wed, 28 Jan 2015 11:50:54 +0100 Subject: [PATCH 58/73] fix implementation for php 5.3 refs issue #3657 --- src/Composer/IO/ConsoleIO.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Composer/IO/ConsoleIO.php b/src/Composer/IO/ConsoleIO.php index 78b271356..11623a143 100644 --- a/src/Composer/IO/ConsoleIO.php +++ b/src/Composer/IO/ConsoleIO.php @@ -97,11 +97,12 @@ class ConsoleIO extends BaseIO { if (null !== $this->startTime) { $messages = (array) $messages; - $messages = array_map(function (&$message) { + $startTime = $this->startTime; + $messages = array_map(function (&$message) use ($startTime) { return sprintf( '[%.1fMB/%.2fs] %s', memory_get_usage() / 1024 / 1024, - microtime(true) - $this->startTime, + microtime(true) - $startTime, $message ); }, $messages); From a4ffda699f2bcb57d0a0b2aa7bc9fd1d68888412 Mon Sep 17 00:00:00 2001 From: Xavier Fornes Date: Wed, 28 Jan 2015 13:38:43 +0100 Subject: [PATCH 59/73] remove by reference on message parameter refs issue #3657 --- src/Composer/IO/ConsoleIO.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Composer/IO/ConsoleIO.php b/src/Composer/IO/ConsoleIO.php index 11623a143..28a2247cd 100644 --- a/src/Composer/IO/ConsoleIO.php +++ b/src/Composer/IO/ConsoleIO.php @@ -98,7 +98,7 @@ class ConsoleIO extends BaseIO if (null !== $this->startTime) { $messages = (array) $messages; $startTime = $this->startTime; - $messages = array_map(function (&$message) use ($startTime) { + $messages = array_map(function ($message) use ($startTime) { return sprintf( '[%.1fMB/%.2fs] %s', memory_get_usage() / 1024 / 1024, From 2936dc0e55f823251aaad05092c05d28cfb86279 Mon Sep 17 00:00:00 2001 From: Xavier Fornes Date: Wed, 28 Jan 2015 14:43:58 +0100 Subject: [PATCH 60/73] some micro-optimizations made refs issue #3657 --- src/Composer/IO/ConsoleIO.php | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/src/Composer/IO/ConsoleIO.php b/src/Composer/IO/ConsoleIO.php index 28a2247cd..7df26eabf 100644 --- a/src/Composer/IO/ConsoleIO.php +++ b/src/Composer/IO/ConsoleIO.php @@ -96,16 +96,11 @@ class ConsoleIO extends BaseIO public function write($messages, $newline = true) { if (null !== $this->startTime) { - $messages = (array) $messages; - $startTime = $this->startTime; - $messages = array_map(function ($message) use ($startTime) { - return sprintf( - '[%.1fMB/%.2fs] %s', - memory_get_usage() / 1024 / 1024, - microtime(true) - $startTime, - $message - ); - }, $messages); + $memoryUsage = memory_get_usage() / 1024 / 1024; + $timeSpent = microtime(true) - $this->startTime; + $messages = array_map(function ($message) use ($memoryUsage, $timeSpent) { + return sprintf('[%.1fMB/%.2fs] %s', $memoryUsage, $timeSpent, $message); + }, (array) $messages); } $this->output->write($messages, $newline); $this->lastMessage = join($newline ? "\n" : '', (array) $messages); From 32218e97d14432d657e23faac42571546482f1ff Mon Sep 17 00:00:00 2001 From: Wouter J Date: Mon, 8 Dec 2014 01:03:58 +0100 Subject: [PATCH 61/73] Added deprecated warning for the dev option --- src/Composer/Command/InstallCommand.php | 4 ++++ src/Composer/Command/UpdateCommand.php | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/src/Composer/Command/InstallCommand.php b/src/Composer/Command/InstallCommand.php index 669c03582..1b41bd7ec 100644 --- a/src/Composer/Command/InstallCommand.php +++ b/src/Composer/Command/InstallCommand.php @@ -74,6 +74,10 @@ EOT $input->setOption('no-plugins', true); } + if ($input->getOption('dev')) { + $output->writeln('You are using the deprecated option "dev". Dev packages are installed by default now.'); + } + $composer = $this->getComposer(true, $input->getOption('no-plugins')); $composer->getDownloadManager()->setOutputProgress(!$input->getOption('no-progress')); $io = $this->getIO(); diff --git a/src/Composer/Command/UpdateCommand.php b/src/Composer/Command/UpdateCommand.php index ebfd4cb2a..c8e1f8587 100644 --- a/src/Composer/Command/UpdateCommand.php +++ b/src/Composer/Command/UpdateCommand.php @@ -76,6 +76,10 @@ EOT $input->setOption('no-plugins', true); } + if ($input->getOption('dev')) { + $output->writeln('You are using the deprecated option "dev". Dev packages are installed by default now.'); + } + $composer = $this->getComposer(true, $input->getOption('no-plugins')); $composer->getDownloadManager()->setOutputProgress(!$input->getOption('no-progress')); $io = $this->getIO(); From 87b7de4d0a5b9adcd5199a6b77c1fff46a5ff5e2 Mon Sep 17 00:00:00 2001 From: Chris Brand Date: Mon, 26 Jan 2015 17:07:58 +0200 Subject: [PATCH 62/73] Add the P character to the regex pattern According to http://php.net/manual/en/function.preg-match.php and some other sources named groups should contain a 'P' character after the '?' Without this, I receive the following error when running an update: [ErrorException] preg_match(): Compilation failed: unrecognized character after (?< at offset 4 Exception trace: () at phar:///var/www/git/smmqa/app/admin/composer.phar/src/Composer/Package/Version/VersionParser.php:181 --- src/Composer/Package/Version/VersionParser.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Composer/Package/Version/VersionParser.php b/src/Composer/Package/Version/VersionParser.php index d546b2655..9707ac017 100644 --- a/src/Composer/Package/Version/VersionParser.php +++ b/src/Composer/Package/Version/VersionParser.php @@ -178,7 +178,7 @@ class VersionParser */ public function parseNumericAliasPrefix($branch) { - if (preg_match('/^(?(\d+\\.)*\d+)(?:\.x)?-dev$/i', $branch, $matches)) { + if (preg_match('/^(?P(\d+\\.)*\d+)(?:\.x)?-dev$/i', $branch, $matches)) { return $matches['version']."."; } From e7f40140189935b7515ba48d6c1b16f30899b754 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Deruss=C3=A9?= Date: Wed, 28 Jan 2015 20:00:16 +0100 Subject: [PATCH 63/73] Reuse current file permissions --- src/Composer/Command/SelfUpdateCommand.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Composer/Command/SelfUpdateCommand.php b/src/Composer/Command/SelfUpdateCommand.php index 0687de161..eb0de083e 100644 --- a/src/Composer/Command/SelfUpdateCommand.php +++ b/src/Composer/Command/SelfUpdateCommand.php @@ -173,7 +173,7 @@ EOT protected function setLocalPhar($localFilename, $newFilename, $backupTarget = null) { try { - @chmod($newFilename, 0777 & ~umask()); + @chmod($newFilename, fileperms($localFilename)); if (!ini_get('phar.readonly')) { // test the phar validity $phar = new \Phar($newFilename); From 76a0e818b5cb9feae9e1d799e8bf1591cabf389d Mon Sep 17 00:00:00 2001 From: Josh Pollock Date: Wed, 28 Jan 2015 21:33:42 -0500 Subject: [PATCH 64/73] Improve notice about /usr/local/bin --- doc/00-intro.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/00-intro.md b/doc/00-intro.md index a927f35fb..714b55be0 100644 --- a/doc/00-intro.md +++ b/doc/00-intro.md @@ -107,7 +107,7 @@ mv composer.phar /usr/local/bin/composer > **Note:** If the above fails due to permissions, run the `mv` line > again with sudo. -> **Note:** In OSX Yosemite the `/usr` directory does not exist by default. If you recive the error "/usr/local/bin/composer: No such file or directory" then you must create `/usr/local/bin/composer/` manually. +> **Note:** In OSX Yosemite the `/usr` directory does not exist by default. If you receive the error "/usr/local/bin/composer: No such file or directory" then you must create `/usr/local/bin/` manually before proceeding. Then, just run `composer` in order to run Composer instead of `php composer.phar`. From 0b2a31a89de99738096cc3a24f46c3266631c15d Mon Sep 17 00:00:00 2001 From: shaddag Date: Thu, 29 Jan 2015 10:20:31 +0100 Subject: [PATCH 65/73] suppress the prefix --- src/Composer/Command/HomeCommand.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Composer/Command/HomeCommand.php b/src/Composer/Command/HomeCommand.php index fe7929839..8501ef65f 100644 --- a/src/Composer/Command/HomeCommand.php +++ b/src/Composer/Command/HomeCommand.php @@ -84,7 +84,7 @@ EOT } if ($input->getOption('show')) { - $output->writeln(sprintf('%s: %s', $input->getOption('homepage') ? 'Homepage URL' : 'Repository URL', $url).' '); + $output->writeln(sprintf('%s', $url)); } else { $this->openBrowser($url); } From 80d7ab57ed215f443a03f770ea9f86fbc1fa9372 Mon Sep 17 00:00:00 2001 From: davidverholen Date: Thu, 29 Jan 2015 15:46:11 +0100 Subject: [PATCH 66/73] add check for remote Repository in GitDriver::supports --- src/Composer/Repository/Vcs/GitDriver.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Composer/Repository/Vcs/GitDriver.php b/src/Composer/Repository/Vcs/GitDriver.php index da87e2e7d..b8aa31298 100644 --- a/src/Composer/Repository/Vcs/GitDriver.php +++ b/src/Composer/Repository/Vcs/GitDriver.php @@ -241,7 +241,11 @@ class GitDriver extends VcsDriver return false; } - // TODO try to connect to the server + $process = new ProcessExecutor($io); + if($process->execute('git ls-remote ' . $url, $output) === 0) { + return true; + } + return false; } } From 50d068b977128b19b67966c4eeb002ebb4184389 Mon Sep 17 00:00:00 2001 From: davidverholen Date: Thu, 29 Jan 2015 17:08:32 +0100 Subject: [PATCH 67/73] + limit git ls-remote to heads + escape repo url --- src/Composer/Repository/Vcs/GitDriver.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Composer/Repository/Vcs/GitDriver.php b/src/Composer/Repository/Vcs/GitDriver.php index b8aa31298..298639bc0 100644 --- a/src/Composer/Repository/Vcs/GitDriver.php +++ b/src/Composer/Repository/Vcs/GitDriver.php @@ -242,7 +242,7 @@ class GitDriver extends VcsDriver } $process = new ProcessExecutor($io); - if($process->execute('git ls-remote ' . $url, $output) === 0) { + if($process->execute('git ls-remote --heads ' . ProcessExecutor::escape($url), $output) === 0) { return true; } From d650f05ddf7933a1cf6f62b6f3e4bc8a737a9872 Mon Sep 17 00:00:00 2001 From: "brandung GmbH & Co. KG" Date: Thu, 29 Jan 2015 20:00:49 +0100 Subject: [PATCH 68/73] removed needless output param --- src/Composer/Repository/Vcs/GitDriver.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Composer/Repository/Vcs/GitDriver.php b/src/Composer/Repository/Vcs/GitDriver.php index 298639bc0..807ab7294 100644 --- a/src/Composer/Repository/Vcs/GitDriver.php +++ b/src/Composer/Repository/Vcs/GitDriver.php @@ -242,7 +242,7 @@ class GitDriver extends VcsDriver } $process = new ProcessExecutor($io); - if($process->execute('git ls-remote --heads ' . ProcessExecutor::escape($url), $output) === 0) { + if($process->execute('git ls-remote --heads ' . ProcessExecutor::escape($url)) === 0) { return true; } From 0ec450540121cb5b682b31c88a256365a439ea20 Mon Sep 17 00:00:00 2001 From: TaeL Kim Date: Fri, 30 Jan 2015 16:39:55 +0900 Subject: [PATCH 69/73] remove unused statements --- src/Composer/Factory.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Composer/Factory.php b/src/Composer/Factory.php index 3f0041a85..3290b51dc 100644 --- a/src/Composer/Factory.php +++ b/src/Composer/Factory.php @@ -17,11 +17,9 @@ use Composer\Json\JsonFile; use Composer\IO\IOInterface; use Composer\Package\Archiver; use Composer\Repository\RepositoryManager; -use Composer\Repository\RepositoryInterface; use Composer\Repository\WritableRepositoryInterface; use Composer\Util\ProcessExecutor; use Composer\Util\RemoteFilesystem; -use Composer\Util\Filesystem; use Symfony\Component\Console\Formatter\OutputFormatterStyle; use Composer\EventDispatcher\EventDispatcher; use Composer\Autoload\AutoloadGenerator; From 2bd9cef79906e8ce42ffe33db84258e336fedfb3 Mon Sep 17 00:00:00 2001 From: Paul Dragoonis Date: Fri, 30 Jan 2015 10:35:39 +0000 Subject: [PATCH 70/73] Satis grammar fix. --- doc/articles/handling-private-packages-with-satis.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/articles/handling-private-packages-with-satis.md b/doc/articles/handling-private-packages-with-satis.md index 0ee0adbca..5fce5377b 100644 --- a/doc/articles/handling-private-packages-with-satis.md +++ b/doc/articles/handling-private-packages-with-satis.md @@ -66,7 +66,7 @@ constraint if you want really specific versions. } ``` -Once you did this, you just run `php bin/satis build `. +Once you've done this, you just run `php bin/satis build `. For example `php bin/satis build config.json web/` would read the `config.json` file and build a static repository inside the `web/` directory. From 955e3f776a274429f731a130fda71bd0b54ff0aa Mon Sep 17 00:00:00 2001 From: Hannes Van De Vreken Date: Fri, 30 Jan 2015 21:51:12 +0100 Subject: [PATCH 71/73] Add notion of autoloader skipping autoload-dev rules --- doc/03-cli.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/03-cli.md b/doc/03-cli.md index f9625eb2e..40478ee9b 100644 --- a/doc/03-cli.md +++ b/doc/03-cli.md @@ -87,7 +87,7 @@ resolution. installing a package, you can use `--dry-run`. This will simulate the installation and show you what would happen. * **--dev:** Install packages listed in `require-dev` (this is the default behavior). -* **--no-dev:** Skip installing packages listed in `require-dev`. +* **--no-dev:** Skip installing packages listed in `require-dev`. The autoloader generation skips the `autoload-dev` rules. * **--no-autoloader:** Skips autoloader generation. * **--no-scripts:** Skips execution of scripts defined in `composer.json`. * **--no-plugins:** Disables plugins. @@ -130,7 +130,7 @@ php composer.phar update vendor/* fulfill these. * **--dry-run:** Simulate the command without actually doing anything. * **--dev:** Install packages listed in `require-dev` (this is the default behavior). -* **--no-dev:** Skip installing packages listed in `require-dev`. +* **--no-dev:** Skip installing packages listed in `require-dev`. The autoloader generation skips the `autoload-dev` rules. * **--no-autoloader:** Skips autoloader generation. * **--no-scripts:** Skips execution of scripts defined in `composer.json`. * **--no-plugins:** Disables plugins. From 777f2e81a3eb08beffc00ee5e513e68899dbd21e Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Sat, 31 Jan 2015 21:24:16 +0000 Subject: [PATCH 72/73] Show more info when a download fails --- src/Composer/Downloader/FileDownloader.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Composer/Downloader/FileDownloader.php b/src/Composer/Downloader/FileDownloader.php index 0c03f18ab..96bd57c06 100644 --- a/src/Composer/Downloader/FileDownloader.php +++ b/src/Composer/Downloader/FileDownloader.php @@ -90,10 +90,10 @@ class FileDownloader implements DownloaderInterface } catch (\Exception $e) { if ($this->io->isDebug()) { $this->io->write(''); - $this->io->write('Failed: ['.get_class($e).'] '.$e->getMessage()); + $this->io->write('Failed: ['.get_class($e).'] '.$e->getCode().': '.$e->getMessage()); } elseif (count($urls)) { $this->io->write(''); - $this->io->write(' Failed, trying the next URL'); + $this->io->write(' Failed, trying the next URL ('.$e->getCode().': '.$e->getMessage().')'); } if (!count($urls)) { From 8b46880f42ace73aca885b4652c8c50c589ac082 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Sat, 31 Jan 2015 21:24:33 +0000 Subject: [PATCH 73/73] Avoid failing on composer show of lazy providers --- src/Composer/Repository/ComposerRepository.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Composer/Repository/ComposerRepository.php b/src/Composer/Repository/ComposerRepository.php index 5409a8dd3..ad3c9996b 100644 --- a/src/Composer/Repository/ComposerRepository.php +++ b/src/Composer/Repository/ComposerRepository.php @@ -204,6 +204,11 @@ class ComposerRepository extends ArrayRepository $this->loadProviderListings($this->loadRootServerFile()); } + if ($this->lazyProvidersUrl) { + // Can not determine list of provided packages for lazy repositories + return array(); + } + if ($this->providersUrl) { return array_keys($this->providerListing); }