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.pull/5612/head
parent
0aec42521b
commit
2c84be47c2
|
@ -45,9 +45,10 @@ class ExecCommand extends BaseCommand
|
||||||
$binDir = $composer->getConfig()->get('bin-dir');
|
$binDir = $composer->getConfig()->get('bin-dir');
|
||||||
if ($input->getOption('list') || !$input->getArgument('binary')) {
|
if ($input->getOption('list') || !$input->getArgument('binary')) {
|
||||||
$bins = glob($binDir . '/*');
|
$bins = glob($binDir . '/*');
|
||||||
|
$bins = array_merge($bins, array_map(function($e) { return "$e (local)"; }, $composer->getPackage()->getBinaries()));
|
||||||
|
|
||||||
if (!$bins) {
|
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(<<<EOT
|
$this->getIO()->write(<<<EOT
|
||||||
|
|
|
@ -220,6 +220,17 @@ class EventDispatcher
|
||||||
} else {
|
} else {
|
||||||
$this->io->writeError(sprintf('> %s', $exec));
|
$this->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))) {
|
if (0 !== ($exitCode = $this->process->execute($exec))) {
|
||||||
$this->io->writeError(sprintf('<error>Script %s handling the %s event returned with error code '.$exitCode.'</error>', $callable, $event->getName()));
|
$this->io->writeError(sprintf('<error>Script %s handling the %s event returned with error code '.$exitCode.'</error>', $callable, $event->getName()));
|
||||||
|
|
||||||
|
|
|
@ -351,6 +351,8 @@ class EventDispatcherTest extends TestCase
|
||||||
$composer = new Composer;
|
$composer = new Composer;
|
||||||
$config = new Config;
|
$config = new Config;
|
||||||
$composer->setConfig($config);
|
$composer->setConfig($config);
|
||||||
|
$package = $this->getMock('Composer\Package\RootPackageInterface');
|
||||||
|
$composer->setPackage($package);
|
||||||
|
|
||||||
return $composer;
|
return $composer;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue