فهرست منبع

Avoid duplicate commands, and pass plugin to ctor args for capabilities, refs #3377

Jordi Boggiano 9 سال پیش
والد
کامیت
ba909d8795

+ 9 - 3
src/Composer/Console/Application.php

@@ -178,7 +178,7 @@ class Application extends BaseApplication
                     foreach ($composer['scripts'] as $script => $dummy) {
                         if (!defined('Composer\Script\ScriptEvents::'.str_replace('-', '_', strtoupper($script)))) {
                             if ($this->has($script)) {
-                                $io->writeError('<warning>A script named '.$script.' would override a native Composer function and has been skipped</warning>');
+                                $io->writeError('<warning>A script named '.$script.' would override a Composer command and has been skipped</warning>');
                             } else {
                                 $this->add(new Command\ScriptAliasCommand($script));
                             }
@@ -195,7 +195,13 @@ class Application extends BaseApplication
             }
 
             if (!$input->hasParameterOption('--no-plugins')) {
-                $this->addCommands($this->getPluginCommands());
+                foreach ($this->getPluginCommands() as $command) {
+                    if ($this->has($command->getName())) {
+                        $io->writeError('<warning>Plugin command '.$command->getName().' ('.get_class($command).') would override a Composer command and has been skipped</warning>');
+                    } else {
+                        $this->add($command);
+                    }
+                }
             }
 
             $result = parent::doRun($input, $output);
@@ -395,7 +401,7 @@ class Application extends BaseApplication
 
         if (null !== $composer) {
             $pm = $composer->getPluginManager();
-            foreach ($pm->getPluginCapabilities('Composer\Plugin\Capability\CommandProvider') as $capability) {
+            foreach ($pm->getPluginCapabilities('Composer\Plugin\Capability\CommandProvider', array('composer' => $composer, 'io' => $this->io)) as $capability) {
                 $newCommands = $capability->getCommands();
                 if (!is_array($newCommands)) {
                     throw new \UnexpectedValueException('Plugin capability '.get_class($capability).' failed to return an array from getCommands');

+ 5 - 0
src/Composer/Plugin/Capability/CommandProvider.php

@@ -15,6 +15,11 @@ namespace Composer\Plugin\Capability;
 /**
  * Commands Provider Interface
  *
+ * This capability will receive an array with 'composer' and 'io' keys as
+ * constructor argument. Those contain Composer\Composer and Composer\IO\IOInterface
+ * instances. It also contains a 'plugin' key containing the plugin instance that
+ * created the capability.
+ *
  * @author Jérémy Derussé <jeremy@derusse.com>
  */
 interface CommandProvider extends Capability

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

@@ -362,6 +362,7 @@ class PluginManager
                 throw new \RuntimeException("Cannot instantiate Capability, as class $capabilityClass from plugin ".get_class($plugin)." does not exist.");
             }
 
+            $ctorArgs['plugin'] = $plugin;
             $capabilityObj = new $capabilityClass($ctorArgs);
 
             // FIXME these could use is_a and do the check *before* instantiating once drop support for php<5.3.9

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

@@ -11,6 +11,15 @@ class CommandProvider implements CommandProvider
 {
     public function __construct(array $args)
     {
+        if (!$args['composer'] instanceof \Composer\Composer) {
+            throw new \RuntimeException('Expected a "composer" key');
+        }
+        if (!$args['io'] instanceof \Composer\IO\IOInterface) {
+            throw new \RuntimeException('Expected an "io" key');
+        }
+        if (!$args['plugin'] instanceof Plugin8) {
+            throw new \RuntimeException('Expected a "plugin" key with my own plugin');
+        }
     }
 
     public function getCommands()
@@ -28,6 +37,8 @@ class Command extends BaseCommand
 
     protected function execute(InputInterface $input, OutputInterface $output)
     {
+        $output->writeln('Executing');
+
         return 5;
     }
 }

+ 2 - 2
tests/Composer/Test/Plugin/PluginInstallerTest.php

@@ -306,7 +306,7 @@ class PluginInstallerTest extends TestCase
         $installer = new PluginInstaller($this->io, $this->composer);
         $this->pm->loadInstalledPlugins();
 
-        $caps = $this->pm->getPluginCapabilities('Composer\Plugin\Capability\CommandProvider');
+        $caps = $this->pm->getPluginCapabilities('Composer\Plugin\Capability\CommandProvider', array('composer' => $this->composer, 'io' => $this->io));
         $this->assertCount(1, $caps);
         $this->assertInstanceOf('Composer\Plugin\Capability\CommandProvider', $caps[0]);
 
@@ -341,7 +341,7 @@ class PluginInstallerTest extends TestCase
 
         $this->assertInstanceOf($capabilityApi, $capability);
         $this->assertInstanceOf($capabilityImplementation, $capability);
-        $this->assertSame(array('a' => 1, 'b' => 2), $capability->args);
+        $this->assertSame(array('a' => 1, 'b' => 2, 'plugin' => $plugin), $capability->args);
     }
 
     public function invalidImplementationClassNames()