1
0
Fork 0

Allow plugins to register commands

pull/3377/head
Jérémy Derussé 2014-10-26 18:47:29 +01:00 committed by Jérémy Derussé
parent e5985a9b55
commit 86e0b847be
6 changed files with 114 additions and 8 deletions

View File

@ -27,6 +27,7 @@ use Composer\IO\IOInterface;
use Composer\IO\ConsoleIO; use Composer\IO\ConsoleIO;
use Composer\Json\JsonValidationException; use Composer\Json\JsonValidationException;
use Composer\Util\ErrorHandler; use Composer\Util\ErrorHandler;
use Composer\Plugin\CommandsProviderInterface;
/** /**
* The console application that handles the commands * The console application that handles the commands
@ -144,6 +145,10 @@ class Application extends BaseApplication
$this->io->enableDebugging($startTime); $this->io->enableDebugging($startTime);
} }
if (!$input->hasParameterOption('--no-plugins')) {
$this->addCommands($this->getPluginCommands());
}
$result = parent::doRun($input, $output); $result = parent::doRun($input, $output);
if (isset($oldWorkingDir)) { if (isset($oldWorkingDir)) {
@ -317,6 +322,7 @@ class Application extends BaseApplication
{ {
$definition = parent::getDefaultInputDefinition(); $definition = parent::getDefaultInputDefinition();
$definition->addOption(new InputOption('--profile', null, InputOption::VALUE_NONE, 'Display timing and memory usage information')); $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.')); $definition->addOption(new InputOption('--working-dir', '-d', InputOption::VALUE_REQUIRED, 'If specified, use the given directory as working directory.'));
return $definition; return $definition;
@ -332,4 +338,24 @@ class Application extends BaseApplication
return $helperSet; return $helperSet;
} }
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;
}
} }

View File

@ -289,7 +289,11 @@ class Factory
$this->createDefaultInstallers($im, $composer, $io); $this->createDefaultInstallers($im, $composer, $io);
if ($fullLoad) { 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); $pm = $this->createPluginManager($io, $composer, $globalComposer);
$composer->setPluginManager($pm); $composer->setPluginManager($pm);
@ -351,15 +355,11 @@ class Factory
* @param Config $config * @param Config $config
* @return Composer|null * @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; $composer = null;
try { 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) { } catch (\Exception $e) {
if ($io->isDebug()) { if ($io->isDebug()) {
$io->writeError('Failed to initialize global composer: '.$e->getMessage()); $io->writeError('Failed to initialize global composer: '.$e->getMessage());
@ -488,4 +488,16 @@ class Factory
return $factory->createComposer($io, $config, $disablePlugins); return $factory->createComposer($io, $config, $disablePlugins);
} }
/**
* @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);
}
} }

View File

@ -0,0 +1,32 @@
<?php
/*
* This file is part of Composer.
*
* (c) Nils Adermann <naderman@naderman.de>
* Jordi Boggiano <j.boggiano@seld.be>
*
* 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é <jeremy@derusse.com>
*/
interface CommandsProviderInterface
{
/**
* Retreives list of commands
*
* @return array
*/
public function getCommands();
}

View File

@ -0,0 +1,22 @@
<?php
namespace Installer;
use Composer\Composer;
use Composer\IO\IOInterface;
use Composer\Plugin\PluginInterface;
use Composer\Plugin\CommandsProviderInterface;
class Plugin implements PluginInterface, CommandsProviderInterface
{
public $version = 'installer-v5';
public function activate(Composer $composer, IOInterface $io)
{
}
public function getCommands()
{
return null;
}
}

View File

@ -0,0 +1,14 @@
{
"name": "plugin-v5",
"version": "5.0.0",
"type": "composer-plugin",
"autoload": { "psr-0": { "Installer": "" } },
"extra": {
"class": [
"Installer\\Plugin"
]
},
"require": {
"composer-plugin-api": "1.0.0"
}
}

View File

@ -37,7 +37,7 @@ class PluginInstallerTest extends \PHPUnit_Framework_TestCase
$loader = new JsonLoader(new ArrayLoader()); $loader = new JsonLoader(new ArrayLoader());
$this->packages = array(); $this->packages = array();
$this->directory = sys_get_temp_dir() . '/' . uniqid(); $this->directory = sys_get_temp_dir() . '/' . uniqid();
for ($i = 1; $i <= 4; $i++) { for ($i = 1; $i <= 5; $i++) {
$filename = '/Fixtures/plugin-v'.$i.'/composer.json'; $filename = '/Fixtures/plugin-v'.$i.'/composer.json';
mkdir(dirname($this->directory . $filename), 0777, true); mkdir(dirname($this->directory . $filename), 0777, true);
$this->packages[] = $loader->load(__DIR__ . $filename); $this->packages[] = $loader->load(__DIR__ . $filename);