Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Progress bar overwrites previous lines if format is multiline. #19133

Closed
rquadling opened this issue Jun 21, 2016 · 0 comments
Closed

Progress bar overwrites previous lines if format is multiline. #19133

rquadling opened this issue Jun 21, 2016 · 0 comments

Comments

@rquadling
Copy link
Contributor

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
rquadling added a commit to rquadling/symfony that referenced this issue Jun 21, 2016
Fixes symfony#19133

When a progress bar is first displayed, if it is multi-line, previously output lines are erased, depending upon the number of lines in the progress bar.

This patch fixes that be distinguishing between the first display (no erasing of previous output) and subsequent displays of the progress bar.
fabpot added a commit that referenced this issue Jun 23, 2016
…lays (rquadling)

This PR was merged into the 2.7 branch.

Discussion
----------

Distinguish between first and subsequent progress bar displays

| Q             | A
| ------------- | ---
| Branch?       | 2.7
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #19133
| License       | MIT
| Doc PR        | reference to the documentation PR, if any

Fixes #19133

When a progress bar is first displayed, if it is multi-line, previously output lines are erased, depending upon the number of lines in the progress bar.

This patch fixes that be distinguishing between the first display (no erasing of previous output) and subsequent displays of the progress bar.

Commits
-------

3871e1a Differentiate between the first time a progress bar is displayed and subsequent times
@fabpot fabpot closed this as completed Jun 23, 2016
symfony-splitter pushed a commit to symfony/console that referenced this issue Jun 23, 2016
…lays (rquadling)

This PR was merged into the 2.7 branch.

Discussion
----------

Distinguish between first and subsequent progress bar displays

| Q             | A
| ------------- | ---
| Branch?       | 2.7
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #19133
| License       | MIT
| Doc PR        | reference to the documentation PR, if any

Fixes symfony/symfony#19133

When a progress bar is first displayed, if it is multi-line, previously output lines are erased, depending upon the number of lines in the progress bar.

This patch fixes that be distinguishing between the first display (no erasing of previous output) and subsequent displays of the progress bar.

Commits
-------

3871e1a Differentiate between the first time a progress bar is displayed and subsequent times
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants