Browse Source

Add support for TTY mode on Linux/OSX in script handlers when running in interactive mode, fixes #5856, fixes #3299, closes #4036

Jordi Boggiano 5 years ago
parent
commit
f572636628

+ 2 - 2
src/Composer/EventDispatcher/EventDispatcher.php

@@ -174,7 +174,7 @@ class EventDispatcher
                 $flags = $event->getFlags();
                 if (substr($callable, 0, 10) === '@composer ') {
                     $exec = $this->getPhpExecCommand() . ' ' . ProcessExecutor::escape(getenv('COMPOSER_BINARY')) . ' ' . implode(' ', $args);
-                    if (0 !== ($exitCode = $this->process->execute($exec))) {
+                    if (0 !== ($exitCode = $this->process->execute($exec, $ignoredOutput, null, $this->io->isInteractive()))) {
                         $this->io->writeError(sprintf('<error>Script %s handling the %s event returned with error code '.$exitCode.'</error>', $callable, $event->getName()), true, IOInterface::QUIET);
 
                         throw new ScriptExecutionException('Error Output: '.$this->process->getErrorOutput(), $exitCode);
@@ -248,7 +248,7 @@ class EventDispatcher
                     }
                 }
 
-                if (0 !== ($exitCode = $this->process->execute($exec))) {
+                if (0 !== ($exitCode = $this->process->execute($exec, $ignoredOutput, null, $this->io->isInteractive()))) {
                     $this->io->writeError(sprintf('<error>Script %s handling the %s event returned with error code '.$exitCode.'</error>', $callable, $event->getName()), true, IOInterface::QUIET);
 
                     throw new ScriptExecutionException('Error Output: '.$this->process->getErrorOutput(), $exitCode);

+ 4 - 1
src/Composer/Util/ProcessExecutor.php

@@ -41,7 +41,7 @@ class ProcessExecutor
      * @param  string $cwd     the working directory
      * @return int    statuscode
      */
-    public function execute($command, &$output = null, $cwd = null)
+    public function execute($command, &$output = null, $cwd = null, $tty = false)
     {
         if ($this->io && $this->io->isDebug()) {
             $safeCommand = preg_replace_callback('{://(?P<user>[^:/\s]+):(?P<password>[^@\s/]+)@}i', function ($m) {
@@ -70,6 +70,9 @@ class ProcessExecutor
         } else {
             $process = new Process($command, $cwd, null, null, static::getTimeout());
         }
+        if (!Platform::isWindows() && $tty) {
+            $process->setTty(true);
+        }
 
         $callback = is_callable($output) ? $output : array($this, 'outputHandler');
         $process->run($callback);