Closed
Description
If you have a progress bar whose format is across multiple lines, previously outputted content gets overwritten.
Using Symfony/Console v2.8.7.
<?php
use Symfony\Component\Console\Helper\ProgressBar;
use Symfony\Component\Console\Output\ConsoleOutput;
require_once __DIR__ . '/vendor/autoload.php';
$output = new ConsoleOutput();
$output->writeln('Line 1');
$output->writeln('Line 2');
$output->writeln('Line 3');
$bar = new ProgressBar($output);
$bar->setFormat(
implode(
"\n",
[
'Processing Loop',
' Progress : [%bar%]',
' Lines Read : %linesRead:10s%',
]
)
);
foreach(range(1, 10) as $linesRead => $line){
$bar->setMessage(number_format(1+ $linesRead), 'linesRead');
$bar->advance();
}
$bar->finish();
outputs
Line 1
Processing Loop
Progress : [============================]
Lines Read : 10
In looking at the code, \Symfony\Component\Console\Helper\ProgressBar::overwrite()
wants to clear lines based upon the number of lines in the progress bar format. That is fine, except on the first run.
A hack could be to not "overwrite" on the first call.
/**
* Overwrites a previous message to the output.
*
* @param string $message The message
*/
private function overwrite($message)
{
static $firstTime = true;
if ($this->overwrite) {
if (!$firstTime) {
// Move the cursor to the beginning of the line
$this->output->write("\x0D");
// Erase the line
$this->output->write("\x1B[2K");
// Erase previous lines
if ($this->formatLineCount > 0) {
$this->output->write(str_repeat("\x1B[1A\x1B[2K", $this->formatLineCount));
}
}
} elseif ($this->step > 0) {
$this->output->writeln('');
}
$firstTime = false;
$this->output->write($message);
}
This now makes my code display correctly.
Line 1
Line 2
Line 3
Processing Loop
Progress : [============================]
Lines Read : 10
Metadata
Metadata
Assignees
Labels
No labels