-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[Console] progress bar fix #16490
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
[Console] progress bar fix #16490
Changes from all commits
4edfabc
3a55e6b
77b92da
6a77dbe
066f391
efb2b7d
0dea4e8
846f1be
cc14c56
ac3ad46
c89d24f
cf0e411
eb8a58d
885e4ea
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,6 +14,7 @@ | |
use Symfony\Component\Console\Output\ConsoleOutputInterface; | ||
use Symfony\Component\Console\Output\OutputInterface; | ||
use Symfony\Component\Console\Exception\LogicException; | ||
use Symfony\Component\Console\Terminal\TerminalDimensionsProvider; | ||
|
||
/** | ||
* The ProgressBar provides helpers to display progress output. | ||
|
@@ -50,19 +51,24 @@ class ProgressBar | |
private static $formats; | ||
|
||
/** | ||
* Constructor. | ||
* | ||
* @param OutputInterface $output An OutputInterface instance | ||
* @param int $max Maximum steps (0 if unknown) | ||
* @var TerminalDimensionsProvider | ||
*/ | ||
private $terminalDimensionsProvider; | ||
|
||
/** | ||
* @param OutputInterface $output An OutputInterface instance | ||
* @param int $max Maximum steps (0 if unknown) | ||
* @param TerminalDimensionsProvider $terminalDimensionsProvider | ||
*/ | ||
public function __construct(OutputInterface $output, $max = 0) | ||
public function __construct(OutputInterface $output, $max = 0, TerminalDimensionsProvider $terminalDimensionsProvider = null) | ||
{ | ||
if ($output instanceof ConsoleOutputInterface) { | ||
$output = $output->getErrorOutput(); | ||
} | ||
|
||
$this->output = $output; | ||
$this->setMaxSteps($max); | ||
$this->terminalDimensionsProvider = $terminalDimensionsProvider ?: new TerminalDimensionsProvider(); | ||
|
||
if (!$this->output->isDecorated()) { | ||
// disable overwrite when output does not support ANSI codes. | ||
|
@@ -210,7 +216,7 @@ public function getProgressPercent() | |
*/ | ||
public function setBarWidth($size) | ||
{ | ||
$this->barWidth = (int) $size; | ||
$this->barWidth = max(1, (int) $size); | ||
} | ||
|
||
/** | ||
|
@@ -405,21 +411,9 @@ public function display() | |
$this->setRealFormat($this->internalFormat ?: $this->determineBestFormat()); | ||
} | ||
|
||
$this->overwrite(preg_replace_callback("{%([a-z\-_]+)(?:\:([^%]+))?%}i", function ($matches) { | ||
if ($formatter = $this::getPlaceholderFormatterDefinition($matches[1])) { | ||
$text = call_user_func($formatter, $this, $this->output); | ||
} elseif (isset($this->messages[$matches[1]])) { | ||
$text = $this->messages[$matches[1]]; | ||
} else { | ||
return $matches[0]; | ||
} | ||
|
||
if (isset($matches[2])) { | ||
$text = sprintf('%'.$matches[2], $text); | ||
} | ||
|
||
return $text; | ||
}, $this->format)); | ||
$line = $this->buildLine(); | ||
$line = $this->adjustLineWidthToTerminalWidth($line); | ||
$this->overwrite($line); | ||
} | ||
|
||
/** | ||
|
@@ -600,4 +594,45 @@ private static function initFormats() | |
'debug_nomax' => ' %current% [%bar%] %elapsed:6s% %memory:6s%', | ||
); | ||
} | ||
|
||
/** | ||
* @return string | ||
*/ | ||
private function buildLine() | ||
{ | ||
return preg_replace_callback("{%([a-z\-_]+)(?:\:([^%]+))?%}i", function ($matches) { | ||
if ($formatter = $this::getPlaceholderFormatterDefinition($matches[1])) { | ||
$text = call_user_func($formatter, $this, $this->output); | ||
} elseif (isset($this->messages[$matches[1]])) { | ||
$text = $this->messages[$matches[1]]; | ||
} else { | ||
return $matches[0]; | ||
} | ||
|
||
if (isset($matches[2])) { | ||
$text = sprintf('%'.$matches[2], $text); | ||
} | ||
|
||
return $text; | ||
}, $this->format); | ||
} | ||
|
||
/** | ||
* @param string $line | ||
* | ||
* @return bool | ||
*/ | ||
private function adjustLineWidthToTerminalWidth($line) | ||
{ | ||
$lineLength = Helper::strlenWithoutDecoration($this->output->getFormatter(), $line); | ||
$terminalWidth = $this->terminalDimensionsProvider->getTerminalWidth(); | ||
if ($lineLength > $terminalWidth) { | ||
$newBarWidth = $this->barWidth - $lineLength + $terminalWidth; | ||
$this->setBarWidth($newBarWidth); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The new width should be checked for negative values. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've added check to the It should be always positive number. |
||
|
||
return $this->buildLine(); | ||
} | ||
|
||
return $line; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
getTerminalHeight
?