diff --git a/Helper/ProcessHelper.php b/Helper/ProcessHelper.php index 944c59395..40842799c 100644 --- a/Helper/ProcessHelper.php +++ b/Helper/ProcessHelper.php @@ -36,6 +36,10 @@ class ProcessHelper extends Helper */ public function run(OutputInterface $output, $cmd, string $error = null, callable $callback = null, int $verbosity = OutputInterface::VERBOSITY_VERY_VERBOSE): Process { + if (!class_exists(Process::class)) { + throw new \LogicException('The ProcessHelper cannot be run as the Process component is not installed. Try running "compose require symfony/process".'); + } + if ($output instanceof ConsoleOutputInterface) { $output = $output->getErrorOutput(); } diff --git a/Helper/QuestionHelper.php b/Helper/QuestionHelper.php index 3a663866b..87437250a 100644 --- a/Helper/QuestionHelper.php +++ b/Helper/QuestionHelper.php @@ -33,7 +33,7 @@ class QuestionHelper extends Helper { private $inputStream; private static $shell; - private static $stty; + private static $stty = true; /** * Asks a question to the user. @@ -107,7 +107,7 @@ private function doAsk(OutputInterface $output, Question $question) $inputStream = $this->inputStream ?: STDIN; $autocomplete = $question->getAutocompleterCallback(); - if (null === $autocomplete || !Terminal::hasSttyAvailable()) { + if (null === $autocomplete || !self::$stty || !Terminal::hasSttyAvailable()) { $ret = false; if ($question->isHidden()) { try { @@ -415,7 +415,7 @@ private function getHiddenResponse(OutputInterface $output, $inputStream, bool $ return $value; } - if (Terminal::hasSttyAvailable()) { + if (self::$stty && Terminal::hasSttyAvailable()) { $sttyMode = shell_exec('stty -g'); shell_exec('stty -echo'); diff --git a/Tests/Helper/QuestionHelperTest.php b/Tests/Helper/QuestionHelperTest.php index f4689bc81..ddb0c90e1 100644 --- a/Tests/Helper/QuestionHelperTest.php +++ b/Tests/Helper/QuestionHelperTest.php @@ -11,6 +11,7 @@ namespace Symfony\Component\Console\Tests\Helper; +use Symfony\Component\Console\Exception\InvalidArgumentException; use Symfony\Component\Console\Formatter\OutputFormatter; use Symfony\Component\Console\Helper\FormatterHelper; use Symfony\Component\Console\Helper\HelperSet; @@ -783,6 +784,35 @@ public function testTraversableAutocomplete() $this->assertEquals('FooBundle', $dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question)); } + public function testDisableSttby() + { + if (!Terminal::hasSttyAvailable()) { + $this->markTestSkipped('`stty` is required to test autocomplete functionality'); + } + + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage('invalid'); + + QuestionHelper::disableStty(); + $dialog = new QuestionHelper(); + $dialog->setHelperSet(new HelperSet([new FormatterHelper()])); + + $question = new ChoiceQuestion('Please select a bundle', [1 => 'AcmeDemoBundle', 4 => 'AsseticBundle']); + $question->setMaxAttempts(1); + + // + // Gives `AcmeDemoBundle` with stty + $inputStream = $this->getInputStream("\033[A\033[A\n\033[B\033[B\n"); + + try { + $dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question); + } finally { + $reflection = new \ReflectionProperty(QuestionHelper::class, 'stty'); + $reflection->setAccessible(true); + $reflection->setValue(null, true); + } + } + public function testTraversableMultiselectAutocomplete() { //