diff --git a/src/Composer/Console/Application.php b/src/Composer/Console/Application.php index 3344d0c0f..b21656558 100644 --- a/src/Composer/Console/Application.php +++ b/src/Composer/Console/Application.php @@ -27,6 +27,7 @@ use Composer\IO\IOInterface; use Composer\IO\ConsoleIO; use Composer\Json\JsonValidationException; use Composer\Util\ErrorHandler; +use Composer\Plugin\CommandsProviderInterface; /** * The console application that handles the commands @@ -194,6 +195,10 @@ class Application extends BaseApplication $this->io->enableDebugging($startTime); } + if (!$input->hasParameterOption('--no-plugins')) { + $this->addCommands($this->getPluginCommands()); + } + $result = parent::doRun($input, $output); if (isset($oldWorkingDir)) { @@ -374,8 +379,29 @@ class Application extends BaseApplication { $definition = parent::getDefaultInputDefinition(); $definition->addOption(new InputOption('--profile', null, InputOption::VALUE_NONE, 'Display timing and memory usage information')); + $definition->addOption(new InputOption('--no-plugins', null, InputOption::VALUE_NONE, 'Whether to disable plugins.')); $definition->addOption(new InputOption('--working-dir', '-d', InputOption::VALUE_REQUIRED, 'If specified, use the given directory as working directory.')); return $definition; } + + private function getPluginCommands() + { + $commands = array(); + + $composer = $this->getComposer(false, false); + if (null === $composer) { + $composer = Factory::createGlobal($this->io, false); + } + + if (null !== $composer) { + foreach ($composer->getPluginManager()->getPlugins() as $plugin) { + if ($plugin instanceof CommandsProviderInterface) { + $commands = array_merge($commands, $plugin->getCommands()); + } + } + } + + return $commands; + } } diff --git a/src/Composer/Factory.php b/src/Composer/Factory.php index 84c6a6e76..1e594900c 100644 --- a/src/Composer/Factory.php +++ b/src/Composer/Factory.php @@ -350,7 +350,11 @@ class Factory $this->createDefaultInstallers($im, $composer, $io); if ($fullLoad) { - $globalComposer = $this->createGlobalComposer($io, $config, $disablePlugins); + $globalComposer = null; + if (realpath($config->get('home')) !== $cwd) { + $globalComposer = $this->createGlobalComposer($io, $config, $disablePlugins); + } + $pm = $this->createPluginManager($io, $composer, $globalComposer, $disablePlugins); $composer->setPluginManager($pm); @@ -381,6 +385,18 @@ class Factory return $composer; } + /** + * @param IOInterface $io IO instance + * @param bool $disablePlugins Whether plugins should not be loaded + * @return Composer + */ + public static function createGlobal(IOInterface $io, $disablePlugins = false) + { + $factory = new static(); + + return $factory->createGlobalComposer($io, static::createConfig($io), $disablePlugins, true); + } + /** * @param Repository\RepositoryManager $rm * @param string $vendorDir @@ -394,15 +410,11 @@ class Factory * @param Config $config * @return Composer|null */ - protected function createGlobalComposer(IOInterface $io, Config $config, $disablePlugins) + protected function createGlobalComposer(IOInterface $io, Config $config, $disablePlugins, $fullLoad = false) { - if (realpath($config->get('home')) === getcwd()) { - return; - } - $composer = null; try { - $composer = self::createComposer($io, $config->get('home') . '/composer.json', $disablePlugins, $config->get('home'), false); + $composer = self::createComposer($io, $config->get('home') . '/composer.json', $disablePlugins, $config->get('home'), $fullLoad); } catch (\Exception $e) { $io->writeError('Failed to initialize global composer: '.$e->getMessage(), true, IOInterface::DEBUG); } diff --git a/src/Composer/Plugin/CommandsProviderInterface.php b/src/Composer/Plugin/CommandsProviderInterface.php new file mode 100644 index 000000000..4879b47fb --- /dev/null +++ b/src/Composer/Plugin/CommandsProviderInterface.php @@ -0,0 +1,32 @@ + + * Jordi Boggiano + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Composer\Plugin; + +use Composer\Composer; +use Composer\IO\IOInterface; + +/** + * Commands Provider Interface + * + * @author Jérémy Derussé + */ +interface CommandsProviderInterface +{ + + /** + * Retreives list of commands + * + * @return array + */ + public function getCommands(); +} diff --git a/tests/Composer/Test/Plugin/Fixtures/plugin-v5/composer.json b/tests/Composer/Test/Plugin/Fixtures/plugin-v5/composer.json index 7885cd6fd..de263ebf2 100644 --- a/tests/Composer/Test/Plugin/Fixtures/plugin-v5/composer.json +++ b/tests/Composer/Test/Plugin/Fixtures/plugin-v5/composer.json @@ -1,5 +1,6 @@ { "name": "plugin-v5", +<<<<<<< HEAD "version": "1.0.0", "type": "composer-plugin", "autoload": { "psr-0": { "Installer": "" } }, @@ -8,5 +9,17 @@ }, "require": { "composer-plugin-api": "*" +======= + "version": "5.0.0", + "type": "composer-plugin", + "autoload": { "psr-0": { "Installer": "" } }, + "extra": { + "class": [ + "Installer\\Plugin" + ] + }, + "require": { + "composer-plugin-api": "1.0.0" +>>>>>>> jderusse/plugin-with-commands } } diff --git a/tests/Composer/Test/Plugin/Fixtures/plugin-v8/Installer/Plugin8.php b/tests/Composer/Test/Plugin/Fixtures/plugin-v8/Installer/Plugin8.php new file mode 100644 index 000000000..aeb231f6d --- /dev/null +++ b/tests/Composer/Test/Plugin/Fixtures/plugin-v8/Installer/Plugin8.php @@ -0,0 +1,22 @@ +packages = array(); $this->directory = $this->getUniqueTmpDirectory(); - for ($i = 1; $i <= 7; $i++) { + for ($i = 1; $i <= 8; $i++) { $filename = '/Fixtures/plugin-v'.$i.'/composer.json'; mkdir(dirname($this->directory . $filename), 0777, true); $this->packages[] = $loader->load(__DIR__ . $filename);