Drush is a command-line shell and scripting interface for Drupal, a veritable Swiss Army knife designed to make life easier for those who spend their working hours hacking away at the command prompt.
Describe the bug
In some deployment scripts, we're disabling TTY when running a remote Drush command, using
a config override (drush -D or drush --define). Example: drush -Dssh.tty=0 @live cr
This used to work in Drush 11. In Drush 12, symfony/process was updated and now requires a boolean value for setTty(). The config override however passes the value as string, which causes an error.
To Reproduce
This can be checked using simple commands, e.g. drush -Dssh.tty=0 @live cr or drush -Dssh.tty=0 @live status
Expected behavior
Command is run and does not throw errors.
Actual behavior
An error is thrown due to invalid type:
PHP Fatal error: Uncaught TypeError: Symfony\Component\Process\Process::setTty(): Argument #1 ($tty) must be of type bool, string given, called in /app/vendor/drush/drush/src/Runtime/RedispatchHook.php on line 94 and defined in /app/vendor/symfony/process/Process.php:1016
Stack trace:
#0 /app/vendor/drush/drush/src/Runtime/RedispatchHook.php(94): Symfony\Component\Process\Process->setTty('0')
#1 /app/vendor/drush/drush/src/Runtime/RedispatchHook.php(66): Drush\Runtime\RedispatchHook->redispatch(Object(Symfony\Component\Console\Input\ArgvInput))
#2 /app/vendor/drush/drush/src/Runtime/RedispatchHook.php(54): Drush\Runtime\RedispatchHook->redispatchIfRemote(Object(Symfony\Component\Console\Input\ArgvInput))
#3 /app/vendor/consolidation/annotated-command/src/Hooks/Dispatchers/InitializeHookDispatcher.php(44): Drush\Runtime\RedispatchHook->initialize(Object(Symfony\Component\Console\Input\ArgvInput), Object(Consolidation\AnnotatedCommand\AnnotationData))
#4 /app/vendor/consolidation/annotated-command/src/Hooks/Dispatchers/InitializeHookDispatcher.php(36): Consolidation\AnnotatedCommand\Hooks\Dispatchers\InitializeHookDispatcher->doInitializeHook(Object(Drush\Runtime\RedispatchHook), Object(Symfony\Component\Console\Input\ArgvInput), Object(Consolidation\AnnotatedCommand\AnnotationData))
#5 /app/vendor/consolidation/annotated-command/src/Hooks/Dispatchers/InitializeHookDispatcher.php(29): Consolidation\AnnotatedCommand\Hooks\Dispatchers\InitializeHookDispatcher->callInitializeHook(Object(Drush\Runtime\RedispatchHook), Object(Symfony\Component\Console\Input\ArgvInput), Object(Consolidation\AnnotatedCommand\AnnotationData))
#6 /app/vendor/consolidation/annotated-command/src/CommandProcessor.php(145): Consolidation\AnnotatedCommand\Hooks\Dispatchers\InitializeHookDispatcher->initialize(Object(Symfony\Component\Console\Input\ArgvInput), Object(Consolidation\AnnotatedCommand\AnnotationData))
#7 /app/vendor/consolidation/annotated-command/src/AnnotatedCommand.php(376): Consolidation\AnnotatedCommand\CommandProcessor->initializeHook(Object(Symfony\Component\Console\Input\ArgvInput), Array, Object(Consolidation\AnnotatedCommand\AnnotationData))
#8 /app/vendor/symfony/console/Command/Command.php(292): Consolidation\AnnotatedCommand\AnnotatedCommand->initialize(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#9 /app/vendor/symfony/console/Application.php(1081): Symfony\Component\Console\Command\Command->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#10 /app/vendor/symfony/console/Application.php(320): Symfony\Component\Console\Application->doRunCommand(Object(Consolidation\AnnotatedCommand\AnnotatedCommand), Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#11 /app/vendor/symfony/console/Application.php(174): Symfony\Component\Console\Application->doRun(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#12 /app/vendor/drush/drush/src/Runtime/Runtime.php(110): Symfony\Component\Console\Application->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#13 /app/vendor/drush/drush/src/Runtime/Runtime.php(40): Drush\Runtime\Runtime->doRun(Array, Object(Symfony\Component\Console\Output\ConsoleOutput))
#14 /app/vendor/drush/drush/drush.php(139): Drush\Runtime\Runtime->run(Array)
#15 /app/vendor/drush/drush/drush(4): require('/app/vendor/dru...')
#16 /app/vendor/bin/drush(119): include('/app/vendor/dru...')
#17 {main}
thrown in /app/vendor/symfony/process/Process.php on line 1016
Workaround
Is there another way to disable TTY on the command line (not in drush.yml or similar)?
Maybe the setTty() calls should be typecasted?
System Configuration
Q
A
Drush version?
12.4.1.0
Drupal version?
10.1.5
PHP version
8.1
OS?
Linux
Additional information
As mentioned the reason is that symfony/process 5 (used in Drush 12) requires boolean arguments for setTty(), while symfony/process 4 (used in Drush 11) does implicit typecasting.
Describe the bug In some deployment scripts, we're disabling TTY when running a remote Drush command, using a config override (drush -D or drush --define). Example:
drush -Dssh.tty=0 @live cr
This used to work in Drush 11. In Drush 12, symfony/process was updated and now requires a boolean value for setTty(). The config override however passes the value as string, which causes an error.To Reproduce This can be checked using simple commands, e.g.
drush -Dssh.tty=0 @live cr
ordrush -Dssh.tty=0 @live status
Expected behavior Command is run and does not throw errors.
Actual behavior An error is thrown due to invalid type:
Workaround
System Configuration
Additional information As mentioned the reason is that symfony/process 5 (used in Drush 12) requires boolean arguments for setTty(), while symfony/process 4 (used in Drush 11) does implicit typecasting.