1
0
Fork 0

Add support for local binaries in scripts, refs #2516

pull/3142/head
Jordi Boggiano 2014-07-20 19:46:51 +02:00
parent 33cedda708
commit d9d8d09fe1
2 changed files with 44 additions and 24 deletions

View File

@ -12,6 +12,7 @@
namespace Composer\Command; namespace Composer\Command;
use Composer\Script\CommandEvent;
use Composer\Script\ScriptEvents; use Composer\Script\ScriptEvents;
use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Input\InputOption;
@ -75,16 +76,22 @@ EOT
} }
} }
$hasListeners = $this->getComposer()->getEventDispatcher()->hasEventListeners(new \Composer\Script\CommandEvent($script, $this->getComposer(), $this->getIO())); $composer = $this->getComposer();
$hasListeners = $composer->getEventDispatcher()->hasEventListeners(new CommandEvent($script, $composer, $this->getIO()));
if (!$hasListeners) {
throw new \InvalidArgumentException(sprintf('Script "%s" is not defined in this package', $script));
}
if(!$hasListeners) { // add the bin dir to the PATH to make local binaries of deps usable in scripts
throw new \InvalidArgumentException(sprintf('Script "%s" does not exist', $script)); $binDir = $composer->getConfig()->get('bin-dir');
if (is_dir($binDir)) {
putenv('PATH='.realpath($binDir).PATH_SEPARATOR.getenv('PATH'));
} }
if (in_array($script, $this->commandEvents)) { if (in_array($script, $this->commandEvents)) {
$this->getComposer()->getEventDispatcher()->dispatchCommandEvent($script, $input->getOption('dev') || !$input->getOption('no-dev')); return $composer->getEventDispatcher()->dispatchCommandEvent($script, $input->getOption('dev') || !$input->getOption('no-dev'));
} else {
$this->getComposer()->getEventDispatcher()->dispatchScript($script, $input->getOption('dev') || !$input->getOption('no-dev'));
} }
return $composer->getEventDispatcher()->dispatchScript($script, $input->getOption('dev') || !$input->getOption('no-dev'));
} }
} }

View File

@ -57,8 +57,10 @@ class EventDispatcher
/** /**
* Dispatch an event * Dispatch an event
* *
* @param string $eventName An event name * @param string $eventName An event name
* @param Event $event * @param Event $event
* @return int return code of the executed script if any, for php scripts a false return
* value is changed to 1, anything else to 0
*/ */
public function dispatch($eventName, Event $event = null) public function dispatch($eventName, Event $event = null)
{ {
@ -66,47 +68,55 @@ class EventDispatcher
$event = new Event($eventName); $event = new Event($eventName);
} }
$this->doDispatch($event); return $this->doDispatch($event);
} }
/** /**
* Dispatch a script event. * Dispatch a script event.
* *
* @param string $eventName The constant in ScriptEvents * @param string $eventName The constant in ScriptEvents
* @param Script\Event $event * @param Script\Event $event
* @return int return code of the executed script if any, for php scripts a false return
* value is changed to 1, anything else to 0
*/ */
public function dispatchScript($eventName, $devMode = false) public function dispatchScript($eventName, $devMode = false)
{ {
$this->doDispatch(new Script\Event($eventName, $this->composer, $this->io, $devMode)); return $this->doDispatch(new Script\Event($eventName, $this->composer, $this->io, $devMode));
} }
/** /**
* Dispatch a package event. * Dispatch a package event.
* *
* @param string $eventName The constant in ScriptEvents * @param string $eventName The constant in ScriptEvents
* @param boolean $devMode Whether or not we are in dev mode * @param boolean $devMode Whether or not we are in dev mode
* @param OperationInterface $operation The package being installed/updated/removed * @param OperationInterface $operation The package being installed/updated/removed
* @return int return code of the executed script if any, for php scripts a false return
* value is changed to 1, anything else to 0
*/ */
public function dispatchPackageEvent($eventName, $devMode, OperationInterface $operation) public function dispatchPackageEvent($eventName, $devMode, OperationInterface $operation)
{ {
$this->doDispatch(new PackageEvent($eventName, $this->composer, $this->io, $devMode, $operation)); return $this->doDispatch(new PackageEvent($eventName, $this->composer, $this->io, $devMode, $operation));
} }
/** /**
* Dispatch a command event. * Dispatch a command event.
* *
* @param string $eventName The constant in ScriptEvents * @param string $eventName The constant in ScriptEvents
* @param boolean $devMode Whether or not we are in dev mode * @param boolean $devMode Whether or not we are in dev mode
* @return int return code of the executed script if any, for php scripts a false return
* value is changed to 1, anything else to 0
*/ */
public function dispatchCommandEvent($eventName, $devMode) public function dispatchCommandEvent($eventName, $devMode)
{ {
$this->doDispatch(new CommandEvent($eventName, $this->composer, $this->io, $devMode)); return $this->doDispatch(new CommandEvent($eventName, $this->composer, $this->io, $devMode));
} }
/** /**
* Triggers the listeners of an event. * Triggers the listeners of an event.
* *
* @param Event $event The event object to pass to the event handlers/listeners. * @param Event $event The event object to pass to the event handlers/listeners.
* @return int return code of the executed script if any, for php scripts a false return
* value is changed to 1, anything else to 0
* @throws \RuntimeException * @throws \RuntimeException
* @throws \Exception * @throws \Exception
*/ */
@ -114,9 +124,10 @@ class EventDispatcher
{ {
$listeners = $this->getListeners($event); $listeners = $this->getListeners($event);
$return = 0;
foreach ($listeners as $callable) { foreach ($listeners as $callable) {
if (!is_string($callable) && is_callable($callable)) { if (!is_string($callable) && is_callable($callable)) {
call_user_func($callable, $event); $return = false === call_user_func($callable, $event) ? 1 : 0;
} elseif ($this->isPhpScript($callable)) { } elseif ($this->isPhpScript($callable)) {
$className = substr($callable, 0, strpos($callable, '::')); $className = substr($callable, 0, strpos($callable, '::'));
$methodName = substr($callable, strpos($callable, '::') + 2); $methodName = substr($callable, strpos($callable, '::') + 2);
@ -131,7 +142,7 @@ class EventDispatcher
} }
try { try {
$this->executeEventPhpScript($className, $methodName, $event); $return = false === $this->executeEventPhpScript($className, $methodName, $event) ? 1 : 0;
} catch (\Exception $e) { } catch (\Exception $e) {
$message = "Script %s handling the %s event terminated with an exception"; $message = "Script %s handling the %s event terminated with an exception";
$this->io->write('<error>'.sprintf($message, $callable, $event->getName()).'</error>'); $this->io->write('<error>'.sprintf($message, $callable, $event->getName()).'</error>');
@ -149,6 +160,8 @@ class EventDispatcher
break; break;
} }
} }
return $return;
} }
/** /**
@ -158,7 +171,7 @@ class EventDispatcher
*/ */
protected function executeEventPhpScript($className, $methodName, Event $event) protected function executeEventPhpScript($className, $methodName, Event $event)
{ {
$className::$methodName($event); return $className::$methodName($event);
} }
/** /**
@ -219,14 +232,14 @@ class EventDispatcher
/** /**
* Checks if an event has listeners registered * Checks if an event has listeners registered
* *
* @param Event $event * @param Event $event
* @return boolean * @return boolean
*/ */
public function hasEventListeners(Event $event) public function hasEventListeners(Event $event)
{ {
$listeners = $this->getListeners($event); $listeners = $this->getListeners($event);
return (sizeof($listeners) > 0); return count($listeners) > 0;
} }
/** /**