[Console] Default hidden question to 1 attempt for non-tty session

This commit is contained in:
Gabriel Ostrolucký 2020-04-27 05:08:14 +02:00
parent 2d7b0b8dad
commit ee7fc5544e
No known key found for this signature in database
GPG Key ID: 0B618B95BA22CEEF
2 changed files with 38 additions and 1 deletions

View File

@ -437,7 +437,7 @@ class QuestionHelper extends Helper
if (false !== $shell = $this->getShell()) {
$readCmd = 'csh' === $shell ? 'set mypassword = $<' : 'read -r mypassword';
$command = sprintf("/usr/bin/env %s -c 'stty -echo; %s; stty echo; echo \$mypassword'", $shell, $readCmd);
$command = sprintf("/usr/bin/env %s -c 'stty -echo; %s; stty echo; echo \$mypassword' 2> /dev/null", $shell, $readCmd);
$sCommand = shell_exec($command);
$value = $trimmable ? rtrim($sCommand) : $sCommand;
$output->writeln('');
@ -461,6 +461,11 @@ class QuestionHelper extends Helper
{
$error = null;
$attempts = $question->getMaxAttempts();
if (null === $attempts && !$this->isTty()) {
$attempts = 1;
}
while (null === $attempts || $attempts--) {
if (null !== $error) {
$this->writeError($output, $error);
@ -503,4 +508,19 @@ class QuestionHelper extends Helper
return self::$shell;
}
private function isTty(): bool
{
$inputStream = !$this->inputStream && \defined('STDIN') ? STDIN : $this->inputStream;
if (\function_exists('stream_isatty')) {
return stream_isatty($inputStream);
}
if (!\function_exists('posix_isatty')) {
return posix_isatty($inputStream);
}
return true;
}
}

View File

@ -726,6 +726,23 @@ class QuestionHelperTest extends AbstractQuestionHelperTest
$dialog->ask($this->createStreamableInputInterfaceMock($this->getInputStream('')), $this->createOutputInterface(), $question);
}
public function testAskThrowsExceptionFromValidatorEarlyWhenTtyIsMissing()
{
$this->expectException('Exception');
$this->expectExceptionMessage('Bar, not Foo');
$output = $this->getMockBuilder('\Symfony\Component\Console\Output\OutputInterface')->getMock();
$output->expects($this->once())->method('writeln');
(new QuestionHelper())->ask(
$this->createStreamableInputInterfaceMock($this->getInputStream('Foo'), true),
$output,
(new Question('Q?'))->setHidden(true)->setValidator(function ($input) {
throw new \Exception("Bar, not $input");
})
);
}
public function testEmptyChoices()
{
$this->expectException('LogicException');