8000 bug #48897 [Console] fix clear of section with question (maxbeckers) · symfony/symfony@57901a1 · GitHub
[go: up one dir, main page]

Skip to content

Commit 57901a1

Browse files
committed
bug #48897 [Console] fix clear of section with question (maxbeckers)
This PR was merged into the 6.2 branch. Discussion ---------- [Console] fix clear of section with question | Q | A | ------------- | --- | Branch? | 6.2 | Bug fix? | yes | New feature? | no | Deprecations? | no | Tickets | Fix #47411 | License | MIT | Doc PR | n/a This PR fixes the problems to clear a section with a question included. Example Code: ``` protected function execute(InputInterface $input, OutputInterface $output) { $section1 = $output->section(); $io = new SymfonyStyle($input, $section1); $output->writeln("foo"); $countdown = 3; while ($countdown > 0) { $section1->clear(); $io->writeln('start ' . $countdown); $io->write('foo'); $io->write(' and bar'.\PHP_EOL); $givenAnswer = $io->ask('Dummy question?'); $section1->write('bar'); $countdown--; } return self::SUCCESS; } ``` Output loop 1: ![Screenshot 2023-01-06 142630](https://user-images.githubusercontent.com/11738128/211021767-e4109951-0519-4763-bdd0-6504ee875b46.png) Output loop 1: ![Screenshot 2023-01-06 142653](https://user-images.githubusercontent.com/11738128/211021793-db987c4a-1ac5-422d-a8b9-f6c3f4a23c7f.png) There was already a fix #48089 to be merged in 6.1, but the problem was that there were some changes in 6.2, so it was not possible to merge it into 6.2. So this fix is only working for 6.2, but perhaps we could find a solution as well for the older versions. But because of the changes of console it was not possible to find a solution working for all versions. `@chalasr` this fix is still with the newline always `true` https://github.com/symfony/symfony/blob/4cf9855debc26e4323429ac8d87f02df582e2893/src/Symfony/Component/Console/Output/ConsoleSectionOutput.php#L181 A change of the newline to `$newline` would change the behavior. Maybe we could change that in symfony 7. To make it easier to test is here a zip with 2 testcommands in the root and the changed vendors. [test-48089.zip](https://github.com/symfony/symfony/files/10360423/test-48089.zip) Commits ------- f4c5518 [Console] fix clear of section with question
2 parents 570776e + f4c5518 commit 57901a1

File tree

3 files changed

+59
-1
lines changed

3 files changed

+59
-1
lines changed

src/Symfony/Component/Console/Output/ConsoleSectionOutput.php

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,8 @@ public function addContent(string $input, bool $newline = true): int
115115
// re-add the line break (that has been removed in the above `explode()` for
116116
// - every line that is not the last line
117117
// - if $newline is required, also add it to the last line
118-
if ($i < $count || $newline) {
118+
// - if it's not new line, but input ending with `\PHP_EOL`
119+
if ($i < $count || $newline || str_ends_with($input, \PHP_EOL)) {
119120
$lineContent .= \PHP_EOL;
120121
}
121122

@@ -149,6 +150,15 @@ public function addContent(string $input, bool $newline = true): int
149150
return $linesAdded;
150151
}
151152

153+
/**
154+
* @internal
155+
*/
156+
public function addNewLineOfInputSubmit()
157+
{
158+
$this->content[] = \PHP_EOL;
159+
++$this->lines;
160+
}
161+
152162
protected function doWrite(string $message, bool $newline)
153163
{
154164
if (!$this->isDecorated()) {

src/Symfony/Component/Console/Style/SymfonyStyle.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
use Symfony\Component\Console\Helper\TableSeparator;
2424
use Symfony\Component\Console\Input\InputInterface;
2525
use Symfony\Component\Console\Output\ConsoleOutputInterface;
26+
use Symfony\Component\Console\Output\ConsoleSectionOutput;
2627
use Symfony\Component\Console\Output\OutputInterface;
2728
use Symfony\Component\Console\Output\TrimmedBufferOutput;
2829
use Symfony\Component\Console\Question\ChoiceQuestion;
@@ -298,6 +299,11 @@ public function askQuestion(Question $question): mixed
298299
$answer = $this->questionHelper->ask($this->input, $this, $question);
299300

300301
if ($this->input->isInteractive()) {
302+
if ($this->output instanceof ConsoleSectionOutput) {
303+
// add the new line of the `return` to submit the input to ConsoleSectionOutput, because ConsoleSectionOutput is holding all it's lines.
304+
// this is relevant when a `ConsoleSectionOutput::clear` is called.
305+
$this->output->addNewLineOfInputSubmit();
306+
}
301307
$this->newLine();
302308
$this->bufferedOutput->write("\n");
303309
}

src/Symfony/Component/Console/Tests/Style/SymfonyStyleTest.php

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,13 @@
1616
use Symfony\Component\Console\Exception\RuntimeException;
1717
use Symfony\Component\Console\Formatter\OutputFormatter;
1818
use Symfony\Component\Console\Input\ArrayInput;
19+
use Symfony\Component\Console\Input\Input;
1920
use Symfony\Component\Console\Input\InputInterface;
2021
use Symfony\Component\Console\Output\ConsoleOutputInterface;
2122
use Symfony\Component\Console\Output\ConsoleSectionOutput;
2223
use Symfony\Component\Console\Output\NullOutput;
2324
use Symfony\Component\Console\Output\OutputInterface;
25+
use Symfony\Component\Console\Output\StreamOutput;
2426
use Symfony\Component\Console\Style\SymfonyStyle;
2527
use Symfony\Component\Console\Tester\CommandTester;
2628

@@ -181,4 +183,44 @@ public function testMemoryConsumption()
181183

182184
$this->assertSame(0, memory_get_usage() - $start);
183185
}
186+
187+
public function testAskAndClearExpectFullSectionCleared()
188+
{
189+
$answer = 'Answer';
190+
$inputStream = fopen('php://memory', 'r+');
191+
fwrite($inputStream, $answer.\PHP_EOL);
192+
rewind($inputStream);
193+
$input = $this->createMock(Input::class);
194+
$sections = [];
195+
$output = new ConsoleSectionOutput(fopen('php://memory', 'r+', false), $sections, StreamOutput::VERBOSITY_NORMAL, true, new OutputFormatter());
196+
$input
197+
->method('isInteractive')
198+
->willReturn(true);
199+
$input
200+
->method('getStream')
201+
->willReturn($inputStream);
202+
203+
$style = new SymfonyStyle($input, $output);
204+
205+
$style->writeln('start');
206+
$style->write('foo');
207+
$style->writeln(' and bar');
208+
$givenAnswer = $style->ask('Dummy question?');
209+
$style->write('foo2'.\PHP_EOL);
210+
$output->write('bar2');
211+
$output->clear();
212+
213+
rewind($output->getStream());
214+
$this->assertEquals($answer, $givenAnswer);
215+
$this->assertEquals(
216+
'start'.\PHP_EOL. // write start
217+
'foo'.\PHP_EOL. // write foo
218+
"\x1b[1A\x1b[0Jfoo and bar".\PHP_EOL. // complete line
219+
\PHP_EOL.\PHP_EOL." \033[32mDummy question?\033[39m:".\PHP_EOL.' > '.\PHP_EOL.\PHP_EOL.\PHP_EOL. // question
220+
'foo2'.\PHP_EOL.\PHP_EOL. // write foo2
221+
'bar2'.\PHP_EOL. // write bar
222+
"\033[12A\033[0J", // clear 12 lines (11 output lines and one from the answer input return)
223+< 4227 /span>
stream_get_contents($output->getStream())
224+
);
225+
}
184226
}

0 commit comments

Comments
 (0)
0