1
0
Fork 0

Adjust the CommandProvider to use plugin capabilities and test actual command creation, refs #3377

pull/5267/head
Jordi Boggiano 2016-04-28 20:37:34 +01:00
parent 4319435154
commit 090295dbcb
8 changed files with 92 additions and 30 deletions

View File

@ -27,7 +27,6 @@ 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
@ -395,10 +394,18 @@ class Application extends BaseApplication
}
if (null !== $composer) {
foreach ($composer->getPluginManager()->getPlugins() as $plugin) {
if ($plugin instanceof CommandsProviderInterface) {
$commands = array_merge($commands, $plugin->getCommands());
$pm = $composer->getPluginManager();
foreach ($pm->getPluginCapabilities('Composer\Plugin\Capability\CommandProvider') as $capability) {
$newCommands = $capability->getCommands();
if (!is_array($newCommands)) {
throw new \UnexpectedValueException('Plugin capability '.get_class($capability).' failed to return an array from getCommands');
}
foreach ($newCommands as $command) {
if (!$command instanceof Command\BaseCommand) {
throw new \UnexpectedValueException('Plugin capability '.get_class($capability).' returned an invalid value, we expected an array of Composer\Command\BaseCommand objects');
}
}
$commands = array_merge($commands, $newCommands);
}
}

View File

@ -10,23 +10,19 @@
* file that was distributed with this source code.
*/
namespace Composer\Plugin;
use Composer\Composer;
use Composer\IO\IOInterface;
namespace Composer\Plugin\Capability;
/**
* Commands Provider Interface
*
* @author Jérémy Derussé <jeremy@derusse.com>
*/
interface CommandsProviderInterface
interface CommandProvider extends Capability
{
/**
* Retreives list of commands
* Retreives an array of commands
*
* @return array
* @return Composer\Command\BaseCommand[]
*/
public function getCommands();
}

View File

@ -374,4 +374,23 @@ class PluginManager
return $capabilityObj;
}
}
/**
* @param string $capabilityClassName The fully qualified name of the API interface which the plugin may provide
* an implementation of.
* @param array $ctorArgs Arguments passed to Capability's constructor.
* Keeping it an array will allow future values to be passed w\o changing the signature.
* @return Capability[]
*/
public function getPluginCapabilities($capabilityClassName, array $ctorArgs = array())
{
$capabilities = array();
foreach ($this->getPlugins() as $plugin) {
if ($capability = $this->getPluginCapability($plugin, $capabilityClassName, $ctorArgs)) {
$capabilities[] = $capability;
}
}
return $capabilities;
}
}

View File

@ -1,6 +1,5 @@
{
"name": "plugin-v5",
<<<<<<< HEAD
"version": "1.0.0",
"type": "composer-plugin",
"autoload": { "psr-0": { "Installer": "" } },
@ -9,17 +8,5 @@
},
"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
}
}

View File

@ -0,0 +1,33 @@
<?php
namespace Installer;
use Composer\Plugin\Capability\CommandProvider;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Composer\Command\BaseCommand;
class CommandProvider implements CommandProvider
{
public function __construct(array $args)
{
}
public function getCommands()
{
return array(new Command);
}
}
class Command extends BaseCommand
{
protected function configure()
{
$this->setName('custom-plugin-command');
}
protected function execute(InputInterface $input, OutputInterface $output)
{
return 5;
}
}

View File

@ -5,9 +5,9 @@ namespace Installer;
use Composer\Composer;
use Composer\IO\IOInterface;
use Composer\Plugin\PluginInterface;
use Composer\Plugin\CommandsProviderInterface;
use Composer\Plugin\Capable;
class Plugin8 implements PluginInterface, CommandsProviderInterface
class Plugin8 implements PluginInterface, Capable
{
public $version = 'installer-v8';
@ -15,8 +15,10 @@ class Plugin8 implements PluginInterface, CommandsProviderInterface
{
}
public function getCommands()
public function getCapabilities()
{
return null;
return array(
'Composer\Plugin\Capability\CommandProvider' => 'Installer\CommandProvider',
);
}
}

View File

@ -9,6 +9,6 @@
]
},
"require": {
"composer-plugin-api": "1.0.0"
"composer-plugin-api": "1.1.0"
}
}

View File

@ -297,6 +297,24 @@ class PluginInstallerTest extends TestCase
$this->assertCount(0, $this->pm->getPlugins());
}
public function testCommandProviderCapability()
{
$this->repository
->expects($this->exactly(2))
->method('getPackages')
->will($this->returnValue(array($this->packages[7])));
$installer = new PluginInstaller($this->io, $this->composer);
$this->pm->loadInstalledPlugins();
$caps = $this->pm->getPluginCapabilities('Composer\Plugin\Capability\CommandProvider');
$this->assertCount(1, $caps);
$this->assertInstanceOf('Composer\Plugin\Capability\CommandProvider', $caps[0]);
$commands = $caps[0]->getCommands();
$this->assertCount(1, $commands);
$this->assertInstanceOf('Composer\Command\BaseCommand', $commands[0]);
}
public function testIncapablePluginIsCorrectlyDetected()
{
$plugin = $this->getMockBuilder('Composer\Plugin\PluginInterface')