diff --git a/doc/articles/scripts.md b/doc/articles/scripts.md index a93f2f205..79ea01519 100644 --- a/doc/articles/scripts.md +++ b/doc/articles/scripts.md @@ -63,6 +63,9 @@ Composer fires the following named events during its execution process: - **pre-file-download**: occurs before files are downloaded and allows you to manipulate the `RemoteFilesystem` object prior to downloading files based on the URL to be downloaded. +- **pre-command-run**: occurs before a command is executed and allows you to + manipulate the `InputInterface` object's options and arguments to tweak + a command's behavior. > **Note:** Composer makes no assumptions about the state of your dependencies > prior to `install` or `update`. Therefore, you should not specify scripts diff --git a/src/Composer/Command/BaseCommand.php b/src/Composer/Command/BaseCommand.php index d6b695ca8..052c17213 100644 --- a/src/Composer/Command/BaseCommand.php +++ b/src/Composer/Command/BaseCommand.php @@ -15,8 +15,11 @@ namespace Composer\Command; use Composer\Composer; use Composer\Config; use Composer\Console\Application; +use Composer\Factory; use Composer\IO\IOInterface; use Composer\IO\NullIO; +use Composer\Plugin\PreCommandRunEvent; +use Composer\Plugin\PluginEvents; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Command\Command; @@ -123,6 +126,14 @@ abstract class BaseCommand extends Command */ protected function initialize(InputInterface $input, OutputInterface $output) { + // initialize a plugin-enabled Composer instance, either local or global + $composer = $this->getComposer(false, false); + if (null === $composer) { + $composer = Factory::createGlobal($this->getIO(), false); + } + $preCommandRunEvent = new PreCommandRunEvent(PluginEvents::PRE_COMMAND_RUN, $input); + $composer->getEventDispatcher()->dispatch($preCommandRunEvent->getName(), $preCommandRunEvent); + if (true === $input->hasParameterOption(array('--no-ansi')) && $input->hasOption('no-progress')) { $input->setOption('no-progress', true); } diff --git a/src/Composer/Plugin/PluginEvents.php b/src/Composer/Plugin/PluginEvents.php index 0304ebb9a..1fb368baf 100644 --- a/src/Composer/Plugin/PluginEvents.php +++ b/src/Composer/Plugin/PluginEvents.php @@ -48,4 +48,14 @@ class PluginEvents * @var string */ const PRE_FILE_DOWNLOAD = 'pre-file-download'; + + /** + * The PRE_COMMAND_RUN event occurs before a command is executed and lets you modify the input arguments/options + * + * The event listener method receives a + * Composer\Plugin\PreCommandRunEvent instance. + * + * @var string + */ + const PRE_COMMAND_RUN = 'pre-command-run'; } diff --git a/src/Composer/Plugin/PreCommandRunEvent.php b/src/Composer/Plugin/PreCommandRunEvent.php new file mode 100644 index 000000000..ab2b035a1 --- /dev/null +++ b/src/Composer/Plugin/PreCommandRunEvent.php @@ -0,0 +1,51 @@ + + * Jordi Boggiano + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Composer\Plugin; + +use Composer\EventDispatcher\Event; +use Symfony\Component\Console\Input\InputInterface; + +/** + * The pre command run event. + * + * @author Jordi Boggiano + */ +class PreCommandRunEvent extends Event +{ + /** + * @var InputInterface + */ + private $input; + + /** + * Constructor. + * + * @param string $name The event name + * @param InputInterface $input + */ + public function __construct($name, InputInterface $input) + { + parent::__construct($name); + $this->input = $input; + } + + /** + * Returns the console input + * + * @return InputInterface + */ + public function getInput() + { + return $this->input; + } +}