protected function initializeBinDir() { parent::initializeBinDir(); file_put_contents($this->binDir . '/composer-php', $this->generateUnixyPhpProxyCode()); @chmod($this->binDir . '/composer-php', 0777); file_put_contents($this->binDir . '/composer-php.bat', $this->generateWindowsPhpProxyCode()); @chmod($this->binDir . '/composer-php.bat', 0777); }
/** * Triggers the listeners of an event. * * @param Event $event The event object to pass to the event handlers/listeners. * @throws \RuntimeException|\Exception * @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 */ protected function doDispatch(Event $event) { $pathStr = 'PATH'; if (!isset($_SERVER[$pathStr]) && isset($_SERVER['Path'])) { $pathStr = 'Path'; } // add the bin dir to the PATH to make local binaries of deps usable in scripts $binDir = $this->composer->getConfig()->get('bin-dir'); if (is_dir($binDir)) { $binDir = realpath($binDir); if (isset($_SERVER[$pathStr]) && !preg_match('{(^|' . PATH_SEPARATOR . ')' . preg_quote($binDir) . '($|' . PATH_SEPARATOR . ')}', $_SERVER[$pathStr])) { $_SERVER[$pathStr] = $binDir . PATH_SEPARATOR . getenv($pathStr); putenv($pathStr . '=' . $_SERVER[$pathStr]); } } $listeners = $this->getListeners($event); $this->pushEvent($event); $return = 0; foreach ($listeners as $callable) { if (!is_string($callable) && is_callable($callable)) { $event = $this->checkListenerExpectedEvent($callable, $event); $return = false === call_user_func($callable, $event) ? 1 : 0; } elseif ($this->isComposerScript($callable)) { $this->io->writeError(sprintf('> %s: %s', $event->getName(), $callable), true, IOInterface::VERBOSE); $scriptName = substr($callable, 1); $args = $event->getArguments(); $flags = $event->getFlags(); if (substr($callable, 0, 10) === '@composer ') { $finder = new PhpExecutableFinder(); $phpPath = $finder->find(); if (!$phpPath) { throw new \RuntimeException('Failed to locate PHP binary to execute ' . $scriptName); } $exec = $phpPath . ' ' . realpath($_SERVER['argv'][0]) . substr($callable, 9); 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())); throw new ScriptExecutionException('Error Output: ' . $this->process->getErrorOutput(), $exitCode); } } else { if (!$this->getListeners(new Event($scriptName))) { $this->io->writeError(sprintf('<warning>You made a reference to a non-existent script %s</warning>', $callable)); } $return = $this->dispatch($scriptName, new Script\Event($scriptName, $event->getComposer(), $event->getIO(), $event->isDevMode(), $args, $flags)); } } elseif ($this->isPhpScript($callable)) { $className = substr($callable, 0, strpos($callable, '::')); $methodName = substr($callable, strpos($callable, '::') + 2); if (!class_exists($className)) { $this->io->writeError('<warning>Class ' . $className . ' is not autoloadable, can not call ' . $event->getName() . ' script</warning>'); continue; } if (!is_callable($callable)) { $this->io->writeError('<warning>Method ' . $callable . ' is not callable, can not call ' . $event->getName() . ' script</warning>'); continue; } try { $return = false === $this->executeEventPhpScript($className, $methodName, $event) ? 1 : 0; } catch (\Exception $e) { $message = "Script %s handling the %s event terminated with an exception"; $this->io->writeError('<error>' . sprintf($message, $callable, $event->getName()) . '</error>'); throw $e; } } else { $args = implode(' ', array_map(array('Composer\\Util\\ProcessExecutor', 'escape'), $event->getArguments())); $exec = $callable . ($args === '' ? '' : ' ' . $args); if ($this->io->isVerbose()) { $this->io->writeError(sprintf('> %s: %s', $event->getName(), $exec)); } else { $this->io->writeError(sprintf('> %s', $exec)); } $possibleLocalBinaries = $this->composer->getPackage()->getBinaries(); if ($possibleLocalBinaries) { foreach ($possibleLocalBinaries as $localExec) { if (preg_match('{\\b' . preg_quote($callable) . '$}', $localExec)) { $caller = BinaryInstaller::determineBinaryCaller($localExec); $exec = preg_replace('{^' . preg_quote($callable) . '}', $caller . ' ' . $localExec, $exec); break; } } } 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())); throw new ScriptExecutionException('Error Output: ' . $this->process->getErrorOutput(), $exitCode); } } if ($event->isPropagationStopped()) { break; } } $this->popEvent(); return $return; }