Browse Source

Merge remote-tracking branch 'jderusse/plugin-with-commands'

Jordi Boggiano 9 years ago
parent
commit
a9df4acd7d

+ 26 - 0
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;
+    }
 }

+ 19 - 7
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);
         }

+ 32 - 0
src/Composer/Plugin/CommandsProviderInterface.php

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

+ 13 - 0
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
     }
 }

+ 22 - 0
tests/Composer/Test/Plugin/Fixtures/plugin-v8/Installer/Plugin8.php

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

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

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

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

@@ -70,7 +70,7 @@ class PluginInstallerTest extends TestCase
         $loader = new JsonLoader(new ArrayLoader());
         $this->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);