Skip to content

Commit 2e4af9c

Browse files
committed
fix(console): fix progress bar messing output in section when there is an EOL
1 parent 799445d commit 2e4af9c

File tree

2 files changed

+84
-0
lines changed

2 files changed

+84
-0
lines changed

Helper/ProgressBar.php

+9
Original file line numberDiff line numberDiff line change
@@ -486,12 +486,21 @@ private function overwrite(string $message): void
486486
if ($this->output instanceof ConsoleSectionOutput) {
487487
$messageLines = explode("\n", $this->previousMessage);
488488
$lineCount = \count($messageLines);
489+
490+
$lastLineWithoutDecoration = Helper::removeDecoration($this->output->getFormatter(), end($messageLines) ?? '');
491+
492+
// When the last previous line is empty (without formatting) it is already cleared by the section output, so we don't need to clear it again
493+
if ('' === $lastLineWithoutDecoration) {
494+
--$lineCount;
495+
}
496+
489497
foreach ($messageLines as $messageLine) {
490498
$messageLineLength = Helper::width(Helper::removeDecoration($this->output->getFormatter(), $messageLine));
491499
if ($messageLineLength > $this->terminal->getWidth()) {
492500
$lineCount += floor($messageLineLength / $this->terminal->getWidth());
493501
}
494502
}
503+
495504
$this->output->clear($lineCount);
496505
} else {
497506
$lineCount = substr_count($this->previousMessage, "\n");

Tests/Helper/ProgressBarTest.php

+75
Original file line numberDiff line numberDiff line change
@@ -416,6 +416,81 @@ public function testOverwriteWithSectionOutput()
416416
);
417417
}
418418

419+
public function testOverwriteWithSectionOutputAndEol()
420+
{
421+
$sections = [];
422+
$stream = $this->getOutputStream(true);
423+
$output = new ConsoleSectionOutput($stream->getStream(), $sections, $stream->getVerbosity(), $stream->isDecorated(), new OutputFormatter());
424+
425+
$bar = new ProgressBar($output, 50, 0);
426+
$bar->setFormat('[%bar%] %percent:3s%%' . PHP_EOL . '%message%' . PHP_EOL);
427+
$bar->setMessage('');
428+
$bar->start();
429+
$bar->display();
430+
$bar->setMessage('Doing something...');
431+
$bar->advance();
432+
$bar->setMessage('Doing something foo...');
433+
$bar->advance();
434+
435+
rewind($output->getStream());
436+
$this->assertEquals(escapeshellcmd(
437+
'[>---------------------------] 0%'.\PHP_EOL.\PHP_EOL.
438+
"\x1b[2A\x1b[0J".'[>---------------------------] 2%'.\PHP_EOL. 'Doing something...' . \PHP_EOL .
439+
"\x1b[2A\x1b[0J".'[=>--------------------------] 4%'.\PHP_EOL. 'Doing something foo...' . \PHP_EOL),
440+
escapeshellcmd(stream_get_contents($output->getStream()))
441+
);
442+
}
443+
444+
public function testOverwriteWithSectionOutputAndEolWithEmptyMessage()
445+
{
446+
$sections = [];
447+
$stream = $this->getOutputStream(true);
448+
$output = new ConsoleSectionOutput($stream->getStream(), $sections, $stream->getVerbosity(), $stream->isDecorated(), new OutputFormatter());
449+
450+
$bar = new ProgressBar($output, 50, 0);
451+
$bar->setFormat('[%bar%] %percent:3s%%' . PHP_EOL . '%message%');
452+
$bar->setMessage('Start');
453+
$bar->start();
454+
$bar->display();
455+
$bar->setMessage('');
456+
$bar->advance();
457+
$bar->setMessage('Doing something...');
458+
$bar->advance();
459+
460+
rewind($output->getStream());
461+
$this->assertEquals(escapeshellcmd(
462+
'[>---------------------------] 0%'.\PHP_EOL.'Start'.\PHP_EOL.
463+
"\x1b[2A\x1b[0J".'[>---------------------------] 2%'.\PHP_EOL .
464+
"\x1b[1A\x1b[0J".'[=>--------------------------] 4%'.\PHP_EOL. 'Doing something...' . \PHP_EOL),
465+
escapeshellcmd(stream_get_contents($output->getStream()))
466+
);
467+
}
468+
469+
public function testOverwriteWithSectionOutputAndEolWithEmptyMessageComment()
470+
{
471+
$sections = [];
472+
$stream = $this->getOutputStream(true);
473+
$output = new ConsoleSectionOutput($stream->getStream(), $sections, $stream->getVerbosity(), $stream->isDecorated(), new OutputFormatter());
474+
475+
$bar = new ProgressBar($output, 50, 0);
476+
$bar->setFormat('[%bar%] %percent:3s%%' . PHP_EOL . '<comment>%message%</comment>');
477+
$bar->setMessage('Start');
478+
$bar->start();
479+
$bar->display();
480+
$bar->setMessage('');
481+
$bar->advance();
482+
$bar->setMessage('Doing something...');
483+
$bar->advance();
484+
485+
rewind($output->getStream());
486+
$this->assertEquals(escapeshellcmd(
487+
'[>---------------------------] 0%'.\PHP_EOL."\x1b[33mStart\x1b[39m".\PHP_EOL.
488+
"\x1b[2A\x1b[0J".'[>---------------------------] 2%'.\PHP_EOL .
489+
"\x1b[1A\x1b[0J".'[=>--------------------------] 4%'.\PHP_EOL. "\x1b[33mDoing something...\x1b[39m" . \PHP_EOL),
490+
escapeshellcmd(stream_get_contents($output->getStream()))
491+
);
492+
}
493+
419494
public function testOverwriteWithAnsiSectionOutput()
420495
{
421496
// output has 43 visible characters plus 2 invisible ANSI characters

0 commit comments

Comments
 (0)