Jelajahi Sumber

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

Jordi Boggiano 9 tahun lalu
induk
melakukan
090295dbcb

+ 11 - 4
src/Composer/Console/Application.php

@@ -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);
             }
         }
 

+ 4 - 8
src/Composer/Plugin/CommandsProviderInterface.php → src/Composer/Plugin/Capability/CommandProvider.php

@@ -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();
 }

+ 19 - 0
src/Composer/Plugin/PluginManager.php

@@ -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;
+    }
 }

+ 0 - 13
tests/Composer/Test/Plugin/Fixtures/plugin-v5/composer.json

@@ -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
     }
 }

+ 33 - 0
tests/Composer/Test/Plugin/Fixtures/plugin-v8/Installer/CommandProvider.php

@@ -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;
+    }
+}

+ 6 - 4
tests/Composer/Test/Plugin/Fixtures/plugin-v8/Installer/Plugin8.php

@@ -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',
+        );
     }
 }

+ 1 - 1
tests/Composer/Test/Plugin/Fixtures/plugin-v8/composer.json

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

+ 18 - 0
tests/Composer/Test/Plugin/PluginInstallerTest.php

@@ -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')