From 2c84be47c29377b906c24a613c360e184cb9c458 Mon Sep 17 00:00:00 2001 From: David Jack Wange Olrik Date: Sat, 20 Aug 2016 15:49:50 +0200 Subject: [PATCH] Add support for seamless execution of local binaries Projects that add binaries to `vendor-bin` can now execute those via the same command as projects that consume them without installing them first. In list overview local commands have a `(local)` tag to distinguish them from commands installed in `vendor-bin`. Local binaries take precedence over `vendor-bin` which takes precedence over binaries in path. --- src/Composer/Command/ExecCommand.php | 3 ++- src/Composer/EventDispatcher/EventDispatcher.php | 11 +++++++++++ .../Test/EventDispatcher/EventDispatcherTest.php | 2 ++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/Composer/Command/ExecCommand.php b/src/Composer/Command/ExecCommand.php index 34d1362e5..892baf746 100644 --- a/src/Composer/Command/ExecCommand.php +++ b/src/Composer/Command/ExecCommand.php @@ -45,9 +45,10 @@ class ExecCommand extends BaseCommand $binDir = $composer->getConfig()->get('bin-dir'); if ($input->getOption('list') || !$input->getArgument('binary')) { $bins = glob($binDir . '/*'); + $bins = array_merge($bins, array_map(function($e) { return "$e (local)"; }, $composer->getPackage()->getBinaries())); if (!$bins) { - throw new \RuntimeException("No binaries found in bin-dir ($binDir)"); + throw new \RuntimeException("No binaries found in composer.json or in bin-dir ($binDir)"); } $this->getIO()->write(<<io->writeError(sprintf('> %s', $exec)); } + + $possibleLocalBinaries = $this->composer->getPackage()->getBinaries(); + if ( $possibleLocalBinaries ) { + foreach ( $possibleLocalBinaries as $localExec ) { + if ( preg_match("/\b${callable}$/", $localExec)) { + $exec = str_replace($callable, $localExec, $exec); + break; + } + } + } + if (0 !== ($exitCode = $this->process->execute($exec))) { $this->io->writeError(sprintf('Script %s handling the %s event returned with error code '.$exitCode.'', $callable, $event->getName())); diff --git a/tests/Composer/Test/EventDispatcher/EventDispatcherTest.php b/tests/Composer/Test/EventDispatcher/EventDispatcherTest.php index fc1c9ce86..d893810e1 100644 --- a/tests/Composer/Test/EventDispatcher/EventDispatcherTest.php +++ b/tests/Composer/Test/EventDispatcher/EventDispatcherTest.php @@ -351,6 +351,8 @@ class EventDispatcherTest extends TestCase $composer = new Composer; $config = new Config; $composer->setConfig($config); + $package = $this->getMock('Composer\Package\RootPackageInterface'); + $composer->setPackage($package); return $composer; }