Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 53fcf72

Browse filesBrowse files
bug #33897 [Console] Consider STDIN interactive (ostrolucky)
This PR was submitted for the master branch but it was merged into the 4.4 branch instead. Discussion ---------- [Console] Consider STDIN interactive | Q | A | ------------- | --- | Branch? |4.4 | Bug fix? | yes | New feature? | no | Deprecations? | no | Tickets | Fix #30726, supersedes #30796 | License | MIT | Doc PR | - As demonstrated with `yes | bin/console foo` in #30726, original assumption made in #1699 was wrong. Then, #8452 was merged which solved bug #8079 -> this was a use case when application hangs with `--no-interaction` flag - nobody probably realized that application can be in "non-interactive" mode, without using this flag and not hang. Then, there was #14102 which was poor man's fix for problem caused by this. So already plenty issues this behaviour causes. Looks like a mess to me. Application should be considered non-interactive only when explicitly specified so (--no-interactive flag), otherwise it doesn't hang. ### What this change means? It only changes one case: When doing `echo foo | bin/console bar`, `yes | bin/console bar`, `bin/console bar < foo`, etc. Redirecting stdout is not affected, as application in that case was considered interactive before too. With stdin, this opens possibility to control symfony/console based application by default via stdin, including via `proc_open`. Additionally, not only it allows to control the input for questions, it also makes the question and answers to display on screen. So before, user had no idea what questions are happening and what answers (defaults) are being used. ### About a BC break I'm not really aware of a valid use case this can break. Can you help find any? 1. Since symfony/console components were NOT interactive with stdin before, stdin couldn't be used to control them - so there this change breaks nothing, because it didn't make sense to pass stdin there instead of specifying -n flag. 1. If application uses internal logic where it relies on STDIN disregarding `Output::isInteractive` flag, this doesn't change anything for these either - they will keep using STDIN disregarding result of this flag. 1. What if application uses internal logic for stdin AND console components like QuestionHelper? To me, that doesn't make much sense, because with previous behaviour, such questions would result always into defaults. It might make sense in case application supports both modes - either stdin, or user supplied input and just use default answers with stdin. But I cannot figure out example of such use - what would be the case where application allows user to control something via stdin, but at the same time forbids them to set certain aspects (answers to questions given)? 1. What about `SHELL_INTERACTIVE` env variable? Only way to utilize it was to force enable interactive mode, but since it will be interactive now by default, it will do nothing and no behaviour changes. 1. Preventing stdin control was much bigger potential BC break. Despite that, it was disallowed in minor Symfony version. And as far as I can see, I saw no backlash. Finally, this targets Symfony 5.0 to be extra sure anyways, so I think it's ok, but feel free to suggest documenting this in upgrade guide or changelog. I would even target 4.4, but chose 5.0 as it's easier to push through there. Commits ------- ef157d5 [Console] Consider STDIN interactive
2 parents cd2dec3 + ef157d5 commit 53fcf72
Copy full SHA for 53fcf72

File tree

3 files changed

+29
-19
lines changed
Filter options

3 files changed

+29
-19
lines changed

‎src/Symfony/Component/Console/Application.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Console/Application.php
-11Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@
3636
use Symfony\Component\Console\Input\InputDefinition;
3737
use Symfony\Component\Console\Input\InputInterface;
3838
use Symfony\Component\Console\Input\InputOption;
39-
use Symfony\Component\Console\Input\StreamableInputInterface;
4039
use Symfony\Component\Console\Output\ConsoleOutput;
4140
use Symfony\Component\Console\Output\ConsoleOutputInterface;
4241
use Symfony\Component\Console\Output\OutputInterface;
@@ -947,16 +946,6 @@ protected function configureIO(InputInterface $input, OutputInterface $output)
947946

948947
if (true === $input->hasParameterOption(['--no-interaction', '-n'], true)) {
949948
$input->setInteractive(false);
950-
} elseif (\function_exists('posix_isatty')) {
951-
$inputStream = null;
952-
953-
if ($input instanceof StreamableInputInterface) {
954-
$inputStream = $input->getStream();
955-
}
956-
957-
if (!@posix_isatty($inputStream) && false === getenv('SHELL_INTERACTIVE')) {
958-
$input->setInteractive(false);
959-
}
960949
}
961950

962951
switch ($shellVerbosity = (int) getenv('SHELL_VERBOSITY')) {

‎src/Symfony/Component/Console/Tester/ApplicationTester.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Console/Tester/ApplicationTester.php
+1-8Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -59,19 +59,12 @@ public function run(array $input, $options = [])
5959
$this->input->setInteractive($options['interactive']);
6060
}
6161

62-
$shellInteractive = getenv('SHELL_INTERACTIVE');
63-
6462
if ($this->inputs) {
6563
$this->input->setStream(self::createStream($this->inputs));
66-
putenv('SHELL_INTERACTIVE=1');
6764
}
6865

6966
$this->initOutput($options);
7067

71-
$this->statusCode = $this->application->run($this->input, $this->output);
72-
73-
putenv($shellInteractive ? "SHELL_INTERACTIVE=$shellInteractive" : 'SHELL_INTERACTIVE');
74-
75-
return $this->statusCode;
68+
return $this->statusCode = $this->application->run($this->input, $this->output);
7669
}
7770
}
+28Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
--STDIN--
2+
Hello World
3+
--FILE--
4+
<?php
5+
6+
use Symfony\Component\Console\Application;
7+
use Symfony\Component\Console\Helper\QuestionHelper;
8+
use Symfony\Component\Console\Input\InputInterface;
9+
use Symfony\Component\Console\Output\OutputInterface;
10+
use Symfony\Component\Console\Question\Question;
11+
12+
$vendor = __DIR__;
13+
while (!file_exists($vendor.'/vendor')) {
14+
$vendor = \dirname($vendor);
15+
}
16+
require $vendor.'/vendor/autoload.php';
17+
18+
(new Application())
19+
->register('app')
20+
->setCode(function(InputInterface $input, OutputInterface $output) {
21+
$output->writeln((new QuestionHelper())->ask($input, $output, new Question('Foo?')));
22+
})
23+
->getApplication()
24+
->setDefaultCommand('app', true)
25+
->run()
26+
;
27+
--EXPECT--
28+
Foo?Hello World

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.