summaryrefslogtreecommitdiff
path: root/vendor/symfony/console/Helper/ProgressBar.php
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/symfony/console/Helper/ProgressBar.php')
-rw-r--r--vendor/symfony/console/Helper/ProgressBar.php621
1 files changed, 621 insertions, 0 deletions
diff --git a/vendor/symfony/console/Helper/ProgressBar.php b/vendor/symfony/console/Helper/ProgressBar.php
new file mode 100644
index 00000000..e7717a52
--- /dev/null
+++ b/vendor/symfony/console/Helper/ProgressBar.php
@@ -0,0 +1,621 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Helper;
+
+use Symfony\Component\Console\Output\ConsoleOutputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Exception\LogicException;
+
+/**
+ * The ProgressBar provides helpers to display progress output.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ * @author Chris Jones <leeked@gmail.com>
+ */
+class ProgressBar
+{
+ // options
+ private $barWidth = 28;
+ private $barChar;
+ private $emptyBarChar = '-';
+ private $progressChar = '>';
+ private $format;
+ private $internalFormat;
+ private $redrawFreq = 1;
+
+ /**
+ * @var OutputInterface
+ */
+ private $output;
+ private $step = 0;
+ private $max;
+ private $startTime;
+ private $stepWidth;
+ private $percent = 0.0;
+ private $formatLineCount;
+ private $messages;
+ private $overwrite = true;
+
+ private static $formatters;
+ private static $formats;
+
+ /**
+ * Constructor.
+ *
+ * @param OutputInterface $output An OutputInterface instance
+ * @param int $max Maximum steps (0 if unknown)
+ */
+ public function __construct(OutputInterface $output, $max = 0)
+ {
+ if ($output instanceof ConsoleOutputInterface) {
+ $output = $output->getErrorOutput();
+ }
+
+ $this->output = $output;
+ $this->setMaxSteps($max);
+
+ if (!$this->output->isDecorated()) {
+ // disable overwrite when output does not support ANSI codes.
+ $this->overwrite = false;
+
+ // set a reasonable redraw frequency so output isn't flooded
+ $this->setRedrawFrequency($max / 10);
+ }
+
+ $this->startTime = time();
+ }
+
+ /**
+ * Sets a placeholder formatter for a given name.
+ *
+ * This method also allow you to override an existing placeholder.
+ *
+ * @param string $name The placeholder name (including the delimiter char like %)
+ * @param callable $callable A PHP callable
+ */
+ public static function setPlaceholderFormatterDefinition($name, $callable)
+ {
+ if (!self::$formatters) {
+ self::$formatters = self::initPlaceholderFormatters();
+ }
+
+ self::$formatters[$name] = $callable;
+ }
+
+ /**
+ * Gets the placeholder formatter for a given name.
+ *
+ * @param string $name The placeholder name (including the delimiter char like %)
+ *
+ * @return callable|null A PHP callable
+ */
+ public static function getPlaceholderFormatterDefinition($name)
+ {
+ if (!self::$formatters) {
+ self::$formatters = self::initPlaceholderFormatters();
+ }
+
+ return isset(self::$formatters[$name]) ? self::$formatters[$name] : null;
+ }
+
+ /**
+ * Sets a format for a given name.
+ *
+ * This method also allow you to override an existing format.
+ *
+ * @param string $name The format name
+ * @param string $format A format string
+ */
+ public static function setFormatDefinition($name, $format)
+ {
+ if (!self::$formats) {
+ self::$formats = self::initFormats();
+ }
+
+ self::$formats[$name] = $format;
+ }
+
+ /**
+ * Gets the format for a given name.
+ *
+ * @param string $name The format name
+ *
+ * @return string|null A format string
+ */
+ public static function getFormatDefinition($name)
+ {
+ if (!self::$formats) {
+ self::$formats = self::initFormats();
+ }
+
+ return isset(self::$formats[$name]) ? self::$formats[$name] : null;
+ }
+
+ public function setMessage($message, $name = 'message')
+ {
+ $this->messages[$name] = $message;
+ }
+
+ public function getMessage($name = 'message')
+ {
+ return $this->messages[$name];
+ }
+
+ /**
+ * Gets the progress bar start time.
+ *
+ * @return int The progress bar start time
+ */
+ public function getStartTime()
+ {
+ return $this->startTime;
+ }
+
+ /**
+ * Gets the progress bar maximal steps.
+ *
+ * @return int The progress bar max steps
+ */
+ public function getMaxSteps()
+ {
+ return $this->max;
+ }
+
+ /**
+ * Gets the progress bar step.
+ *
+ * @deprecated since version 2.6, to be removed in 3.0. Use {@link getProgress()} instead.
+ *
+ * @return int The progress bar step
+ */
+ public function getStep()
+ {
+ @trigger_error('The '.__METHOD__.' method is deprecated since version 2.6 and will be removed in 3.0. Use the getProgress() method instead.', E_USER_DEPRECATED);
+
+ return $this->getProgress();
+ }
+
+ /**
+ * Gets the current step position.
+ *
+ * @return int The progress bar step
+ */
+ public function getProgress()
+ {
+ return $this->step;
+ }
+
+ /**
+ * Gets the progress bar step width.
+ *
+ * @internal This method is public for PHP 5.3 compatibility, it should not be used.
+ *
+ * @return int The progress bar step width
+ */
+ public function getStepWidth()
+ {
+ return $this->stepWidth;
+ }
+
+ /**
+ * Gets the current progress bar percent.
+ *
+ * @return float The current progress bar percent
+ */
+ public function getProgressPercent()
+ {
+ return $this->percent;
+ }
+
+ /**
+ * Sets the progress bar width.
+ *
+ * @param int $size The progress bar size
+ */
+ public function setBarWidth($size)
+ {
+ $this->barWidth = (int) $size;
+ }
+
+ /**
+ * Gets the progress bar width.
+ *
+ * @return int The progress bar size
+ */
+ public function getBarWidth()
+ {
+ return $this->barWidth;
+ }
+
+ /**
+ * Sets the bar character.
+ *
+ * @param string $char A character
+ */
+ public function setBarCharacter($char)
+ {
+ $this->barChar = $char;
+ }
+
+ /**
+ * Gets the bar character.
+ *
+ * @return string A character
+ */
+ public function getBarCharacter()
+ {
+ if (null === $this->barChar) {
+ return $this->max ? '=' : $this->emptyBarChar;
+ }
+
+ return $this->barChar;
+ }
+
+ /**
+ * Sets the empty bar character.
+ *
+ * @param string $char A character
+ */
+ public function setEmptyBarCharacter($char)
+ {
+ $this->emptyBarChar = $char;
+ }
+
+ /**
+ * Gets the empty bar character.
+ *
+ * @return string A character
+ */
+ public function getEmptyBarCharacter()
+ {
+ return $this->emptyBarChar;
+ }
+
+ /**
+ * Sets the progress bar character.
+ *
+ * @param string $char A character
+ */
+ public function setProgressCharacter($char)
+ {
+ $this->progressChar = $char;
+ }
+
+ /**
+ * Gets the progress bar character.
+ *
+ * @return string A character
+ */
+ public function getProgressCharacter()
+ {
+ return $this->progressChar;
+ }
+
+ /**
+ * Sets the progress bar format.
+ *
+ * @param string $format The format
+ */
+ public function setFormat($format)
+ {
+ $this->format = null;
+ $this->internalFormat = $format;
+ }
+
+ /**
+ * Sets the redraw frequency.
+ *
+ * @param int|float $freq The frequency in steps
+ */
+ public function setRedrawFrequency($freq)
+ {
+ $this->redrawFreq = max((int) $freq, 1);
+ }
+
+ /**
+ * Starts the progress output.
+ *
+ * @param int|null $max Number of steps to complete the bar (0 if indeterminate), null to leave unchanged
+ */
+ public function start($max = null)
+ {
+ $this->startTime = time();
+ $this->step = 0;
+ $this->percent = 0.0;
+
+ if (null !== $max) {
+ $this->setMaxSteps($max);
+ }
+
+ $this->display();
+ }
+
+ /**
+ * Advances the progress output X steps.
+ *
+ * @param int $step Number of steps to advance
+ *
+ * @throws LogicException
+ */
+ public function advance($step = 1)
+ {
+ $this->setProgress($this->step + $step);
+ }
+
+ /**
+ * Sets the current progress.
+ *
+ * @deprecated since version 2.6, to be removed in 3.0. Use {@link setProgress()} instead.
+ *
+ * @param int $step The current progress
+ *
+ * @throws LogicException
+ */
+ public function setCurrent($step)
+ {
+ @trigger_error('The '.__METHOD__.' method is deprecated since version 2.6 and will be removed in 3.0. Use the setProgress() method instead.', E_USER_DEPRECATED);
+
+ $this->setProgress($step);
+ }
+
+ /**
+ * Sets whether to overwrite the progressbar, false for new line.
+ *
+ * @param bool $overwrite
+ */
+ public function setOverwrite($overwrite)
+ {
+ $this->overwrite = (bool) $overwrite;
+ }
+
+ /**
+ * Sets the current progress.
+ *
+ * @param int $step The current progress
+ *
+ * @throws LogicException
+ */
+ public function setProgress($step)
+ {
+ $step = (int) $step;
+ if ($step < $this->step) {
+ throw new LogicException('You can\'t regress the progress bar.');
+ }
+
+ if ($this->max && $step > $this->max) {
+ $this->max = $step;
+ }
+
+ $prevPeriod = (int) ($this->step / $this->redrawFreq);
+ $currPeriod = (int) ($step / $this->redrawFreq);
+ $this->step = $step;
+ $this->percent = $this->max ? (float) $this->step / $this->max : 0;
+ if ($prevPeriod !== $currPeriod || $this->max === $step) {
+ $this->display();
+ }
+ }
+
+ /**
+ * Finishes the progress output.
+ */
+ public function finish()
+ {
+ if (!$this->max) {
+ $this->max = $this->step;
+ }
+
+ if ($this->step === $this->max && !$this->overwrite) {
+ // prevent double 100% output
+ return;
+ }
+
+ $this->setProgress($this->max);
+ }
+
+ /**
+ * Outputs the current progress string.
+ */
+ public function display()
+ {
+ if (OutputInterface::VERBOSITY_QUIET === $this->output->getVerbosity()) {
+ return;
+ }
+
+ if (null === $this->format) {
+ $this->setRealFormat($this->internalFormat ?: $this->determineBestFormat());
+ }
+
+ // these 3 variables can be removed in favor of using $this in the closure when support for PHP 5.3 will be dropped.
+ $self = $this;
+ $output = $this->output;
+ $messages = $this->messages;
+ $this->overwrite(preg_replace_callback("{%([a-z\-_]+)(?:\:([^%]+))?%}i", function ($matches) use ($self, $output, $messages) {
+ if ($formatter = $self::getPlaceholderFormatterDefinition($matches[1])) {
+ $text = call_user_func($formatter, $self, $output);
+ } elseif (isset($messages[$matches[1]])) {
+ $text = $messages[$matches[1]];
+ } else {
+ return $matches[0];
+ }
+
+ if (isset($matches[2])) {
+ $text = sprintf('%'.$matches[2], $text);
+ }
+
+ return $text;
+ }, $this->format));
+ }
+
+ /**
+ * Removes the progress bar from the current line.
+ *
+ * This is useful if you wish to write some output
+ * while a progress bar is running.
+ * Call display() to show the progress bar again.
+ */
+ public function clear()
+ {
+ if (!$this->overwrite) {
+ return;
+ }
+
+ if (null === $this->format) {
+ $this->setRealFormat($this->internalFormat ?: $this->determineBestFormat());
+ }
+
+ $this->overwrite('');
+ }
+
+ /**
+ * Sets the progress bar format.
+ *
+ * @param string $format The format
+ */
+ private function setRealFormat($format)
+ {
+ // try to use the _nomax variant if available
+ if (!$this->max && null !== self::getFormatDefinition($format.'_nomax')) {
+ $this->format = self::getFormatDefinition($format.'_nomax');
+ } elseif (null !== self::getFormatDefinition($format)) {
+ $this->format = self::getFormatDefinition($format);
+ } else {
+ $this->format = $format;
+ }
+
+ $this->formatLineCount = substr_count($this->format, "\n");
+ }
+
+ /**
+ * Sets the progress bar maximal steps.
+ *
+ * @param int $max The progress bar max steps
+ */
+ private function setMaxSteps($max)
+ {
+ $this->max = max(0, (int) $max);
+ $this->stepWidth = $this->max ? Helper::strlen($this->max) : 4;
+ }
+
+ /**
+ * Overwrites a previous message to the output.
+ *
+ * @param string $message The message
+ */
+ private function overwrite($message)
+ {
+ if ($this->overwrite) {
+ // 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('');
+ }
+
+ $this->output->write($message);
+ }
+
+ private function determineBestFormat()
+ {
+ switch ($this->output->getVerbosity()) {
+ // OutputInterface::VERBOSITY_QUIET: display is disabled anyway
+ case OutputInterface::VERBOSITY_VERBOSE:
+ return $this->max ? 'verbose' : 'verbose_nomax';
+ case OutputInterface::VERBOSITY_VERY_VERBOSE:
+ return $this->max ? 'very_verbose' : 'very_verbose_nomax';
+ case OutputInterface::VERBOSITY_DEBUG:
+ return $this->max ? 'debug' : 'debug_nomax';
+ default:
+ return $this->max ? 'normal' : 'normal_nomax';
+ }
+ }
+
+ private static function initPlaceholderFormatters()
+ {
+ return array(
+ 'bar' => function (ProgressBar $bar, OutputInterface $output) {
+ $completeBars = floor($bar->getMaxSteps() > 0 ? $bar->getProgressPercent() * $bar->getBarWidth() : $bar->getProgress() % $bar->getBarWidth());
+ $display = str_repeat($bar->getBarCharacter(), $completeBars);
+ if ($completeBars < $bar->getBarWidth()) {
+ $emptyBars = $bar->getBarWidth() - $completeBars - Helper::strlenWithoutDecoration($output->getFormatter(), $bar->getProgressCharacter());
+ $display .= $bar->getProgressCharacter().str_repeat($bar->getEmptyBarCharacter(), $emptyBars);
+ }
+
+ return $display;
+ },
+ 'elapsed' => function (ProgressBar $bar) {
+ return Helper::formatTime(time() - $bar->getStartTime());
+ },
+ 'remaining' => function (ProgressBar $bar) {
+ if (!$bar->getMaxSteps()) {
+ throw new LogicException('Unable to display the remaining time if the maximum number of steps is not set.');
+ }
+
+ if (!$bar->getProgress()) {
+ $remaining = 0;
+ } else {
+ $remaining = round((time() - $bar->getStartTime()) / $bar->getProgress() * ($bar->getMaxSteps() - $bar->getProgress()));
+ }
+
+ return Helper::formatTime($remaining);
+ },
+ 'estimated' => function (ProgressBar $bar) {
+ if (!$bar->getMaxSteps()) {
+ throw new LogicException('Unable to display the estimated time if the maximum number of steps is not set.');
+ }
+
+ if (!$bar->getProgress()) {
+ $estimated = 0;
+ } else {
+ $estimated = round((time() - $bar->getStartTime()) / $bar->getProgress() * $bar->getMaxSteps());
+ }
+
+ return Helper::formatTime($estimated);
+ },
+ 'memory' => function (ProgressBar $bar) {
+ return Helper::formatMemory(memory_get_usage(true));
+ },
+ 'current' => function (ProgressBar $bar) {
+ return str_pad($bar->getProgress(), $bar->getStepWidth(), ' ', STR_PAD_LEFT);
+ },
+ 'max' => function (ProgressBar $bar) {
+ return $bar->getMaxSteps();
+ },
+ 'percent' => function (ProgressBar $bar) {
+ return floor($bar->getProgressPercent() * 100);
+ },
+ );
+ }
+
+ private static function initFormats()
+ {
+ return array(
+ 'normal' => ' %current%/%max% [%bar%] %percent:3s%%',
+ 'normal_nomax' => ' %current% [%bar%]',
+
+ 'verbose' => ' %current%/%max% [%bar%] %percent:3s%% %elapsed:6s%',
+ 'verbose_nomax' => ' %current% [%bar%] %elapsed:6s%',
+
+ 'very_verbose' => ' %current%/%max% [%bar%] %percent:3s%% %elapsed:6s%/%estimated:-6s%',
+ 'very_verbose_nomax' => ' %current% [%bar%] %elapsed:6s%',
+
+ 'debug' => ' %current%/%max% [%bar%] %percent:3s%% %elapsed:6s%/%estimated:-6s% %memory:6s%',
+ 'debug_nomax' => ' %current% [%bar%] %elapsed:6s% %memory:6s%',
+ );
+ }
+}