Skip to content

Commit 4fc2c74

Browse files
author
Stefano Sala
committed
[Console][ProgressBar] Developer experience: - Removed barCharOriginal - getProgressPercent should return float instead of int. - Minor refactoring
1 parent 2ad7142 commit 4fc2c74

File tree

2 files changed

+108
-96
lines changed

2 files changed

+108
-96
lines changed

Helper/ProgressBar.php

Lines changed: 64 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ class ProgressBar
2424
{
2525
// options
2626
private $barWidth = 28;
27-
private $barChar = '=';
27+
private $barChar;
2828
private $emptyBarChar = '-';
2929
private $progressChar = '>';
3030
private $format = null;
@@ -34,13 +34,12 @@ class ProgressBar
3434
* @var OutputInterface
3535
*/
3636
private $output;
37-
private $step;
37+
private $step = 0;
3838
private $max;
3939
private $startTime;
4040
private $stepWidth;
41-
private $percent;
42-
private $lastMessagesLength;
43-
private $barCharOriginal;
41+
private $percent = 0.0;
42+
private $lastMessagesLength = 0;
4443
private $formatLineCount;
4544
private $messages;
4645

@@ -52,30 +51,16 @@ class ProgressBar
5251
*
5352
* @param OutputInterface $output An OutputInterface instance
5453
* @param int $max Maximum steps (0 if unknown)
55-
*
56-
* @throws \InvalidArgumentException
5754
*/
5855
public function __construct(OutputInterface $output, $max = 0)
5956
{
6057
// Disabling output when it does not support ANSI codes as it would result in a broken display anyway.
6158
$this->output = $output->isDecorated() ? $output : new NullOutput();
6259
$this->setMaxSteps($max);
6360

64-
if (!self::$formatters) {
65-
self::$formatters = self::initPlaceholderFormatters();
66-
}
67-
68-
if (!self::$formats) {
69-
self::$formats = self::initFormats();
70-
}
71-
7261
$this->setFormat($this->determineBestFormat());
7362

7463
$this->startTime = time();
75-
$this->step = 0;
76-
$this->percent = 0;
77-
$this->lastMessagesLength = 0;
78-
$this->barCharOriginal = '';
7964
}
8065

8166
/**
@@ -164,25 +149,6 @@ public function getStartTime()
164149
return $this->startTime;
165150
}
166151

167-
/**
168-
* Sets the progress bar maximal steps.
169-
*
170-
* @param int The progress bar max steps
171-
*
172-
* @throws \InvalidArgumentException
173-
*/
174-
public function setMaxSteps($max)
175-
{
176-
$max = (int) $max;
177-
178-
if ($max < 0) {
179-
throw new \InvalidArgumentException('Max steps should be a positive integer, 0 or null. Got "%s".', $max);
180-
}
181-
182-
$this->max = $max;
183-
$this->stepWidth = $this->max > 0 ? Helper::strlen($this->max) : 4;
184-
}
185-
186152
/**
187153
* Gets the progress bar maximal steps.
188154
*
@@ -196,29 +162,29 @@ public function getMaxSteps()
196162
/**
197163
* Gets the progress bar step.
198164
*
199-
* @deprecated since 2.6, to be removed in 3.0. Use {@link getCurrent()} instead.
165+
* @deprecated since 2.6, to be removed in 3.0. Use {@link getProgress()} instead.
200166
*
201167
* @return int The progress bar step
202168
*/
203169
public function getStep()
204170
{
205-
return $this->getCurrent();
171+
return $this->getProgress();
206172
}
207173

208174
/**
209-
* Gets the progress bar step.
175+
* Gets the current step position.
210176
*
211177
* @return int The progress bar step
212178
*/
213-
public function getCurrent()
179+
public function getProgress()
214180
{
215181
return $this->step;
216182
}
217183

218184
/**
219185
* Gets the progress bar step width.
220186
*
221-
* @deprecated since 2.6, it will be marked private from 3.0.
187+
* @internal This method is public for PHP 5.3 compatibility, it should not be used.
222188
*
223189
* @return int The progress bar step width
224190
*/
@@ -230,7 +196,7 @@ public function getStepWidth()
230196
/**
231197
* Gets the current progress bar percent.
232198
*
233-
* @return int The current progress bar percent
199+
* @return float The current progress bar percent
234200
*/
235201
public function getProgressPercent()
236202
{
@@ -274,6 +240,10 @@ public function setBarCharacter($char)
274240
*/
275241
public function getBarCharacter()
276242
{
243+
if (null === $this->barChar) {
244+
return $this->max ? '=' : $this->emptyBarChar;
245+
}
246+
277247
return $this->barChar;
278248
}
279249

@@ -325,10 +295,10 @@ public function getProgressCharacter()
325295
public function setFormat($format)
326296
{
327297
// try to use the _nomax variant if available
328-
if (!$this->max && isset(self::$formats[$format.'_nomax'])) {
329-
$this->format = self::$formats[$format.'_nomax'];
330-
} elseif (isset(self::$formats[$format])) {
331-
$this->format = self::$formats[$format];
298+
if (!$this->max && null !== self::getFormatDefinition($format.'_nomax')) {
299+
$this->format = self::getFormatDefinition($format.'_nomax');
300+
} elseif (null !== self::getFormatDefinition($format)) {
301+
$this->format = self::getFormatDefinition($format);
332302
} else {
333303
$this->format = $format;
334304
}
@@ -349,17 +319,16 @@ public function setRedrawFrequency($freq)
349319
/**
350320
* Starts the progress output.
351321
*
352-
* @param int $max Maximum Step (0 if unknown)
322+
* @param int|null $max Number of steps to complete the bar (0 if indeterminate), null to leave unchanged
353323
*/
354-
public function start($max = 0)
324+
public function start($max = null)
355325
{
356-
if (0 !== $max) {
357-
$this->setMaxSteps($max);
358-
}
326+
$this->startTime = time();
327+
$this->step = 0;
328+
$this->percent = 0.0;
359329

360-
if (!$this->max) {
361-
$this->barCharOriginal = $this->barChar;
362-
$this->barChar = $this->emptyBarChar;
330+
if (null !== $max) {
331+
$this->setMaxSteps($max);
363332
}
364333

365334
$this->display();
@@ -374,31 +343,45 @@ public function start($max = 0)
374343
*/
375344
public function advance($step = 1)
376345
{
377-
$this->setCurrent($this->step + $step);
346+
$this->setProgress($this->step + $step);
378347
}
379348

380349
/**
381350
* Sets the current progress.
382351
*
352+
* @deprecated since 2.6, to be removed in 3.0. Use {@link setProgress()} instead.
353+
*
383354
* @param int $step The current progress
384355
*
385356
* @throws \LogicException
386357
*/
387358
public function setCurrent($step)
359+
{
360+
$this->setProgress($step);
361+
}
362+
363+
/**
364+
* Sets the current progress.
365+
*
366+
* @param int $step The current progress
367+
*
368+
* @throws \LogicException
369+
*/
370+
public function setProgress($step)
388371
{
389372
$step = (int) $step;
390373
if ($step < $this->step) {
391374
throw new \LogicException('You can\'t regress the progress bar.');
392375
}
393376

394-
if ($this->max > 0 && $step > $this->max) {
377+
if ($this->max && $step > $this->max) {
395378
$this->max = $step;
396379
}
397380

398381
$prevPeriod = intval($this->step / $this->redrawFreq);
399382
$currPeriod = intval($step / $this->redrawFreq);
400383
$this->step = $step;
401-
$this->percent = $this->max > 0 ? (float) $this->step / $this->max : 0;
384+
$this->percent = $this->max ? (float) $this->step / $this->max : 0;
402385
if ($prevPeriod !== $currPeriod || $this->max === $step) {
403386
$this->display();
404387
}
@@ -410,22 +393,14 @@ public function setCurrent($step)
410393
public function finish()
411394
{
412395
if (!$this->max) {
413-
$this->barChar = $this->barCharOriginal;
414396
$this->max = $this->step;
415-
$this->setCurrent($this->max);
416-
$this->max = 0;
417-
$this->barChar = $this->emptyBarChar;
418-
} else {
419-
$this->setCurrent($this->max);
420397
}
421398

422-
$this->startTime = null;
399+
$this->setProgress($this->max);
423400
}
424401

425402
/**
426403
* Outputs the current progress string.
427-
*
428-
* @throws \LogicException
429404
*/
430405
public function display()
431406
{
@@ -466,6 +441,17 @@ public function clear()
466441
$this->overwrite(str_repeat("\n", $this->formatLineCount));
467442
}
468443

444+
/**
445+
* Sets the progress bar maximal steps.
446+
*
447+
* @param int The progress bar max steps
448+
*/
449+
private function setMaxSteps($max)
450+
{
451+
$this->max = max(0, (int) $max);
452+
$this->stepWidth = $this->max ? Helper::strlen($this->max) : 4;
453+
}
454+
469455
/**
470456
* Overwrites a previous message to the output.
471457
*
@@ -505,21 +491,21 @@ private function determineBestFormat()
505491
switch ($this->output->getVerbosity()) {
506492
// OutputInterface::VERBOSITY_QUIET: display is disabled anyway
507493
case OutputInterface::VERBOSITY_VERBOSE:
508-
return $this->max > 0 ? 'verbose' : 'verbose_nomax';
494+
return $this->max ? 'verbose' : 'verbose_nomax';
509495
case OutputInterface::VERBOSITY_VERY_VERBOSE:
510-
return $this->max > 0 ? 'very_verbose' : 'very_verbose_nomax';
496+
return $this->max ? 'very_verbose' : 'very_verbose_nomax';
511497
case OutputInterface::VERBOSITY_DEBUG:
512-
return $this->max > 0 ? 'debug' : 'debug_nomax';
498+
return $this->max ? 'debug' : 'debug_nomax';
513499
default:
514-
return $this->max > 0 ? 'normal' : 'normal_nomax';
500+
return $this->max ? 'normal' : 'normal_nomax';
515501
}
516502
}
517503

518504
private static function initPlaceholderFormatters()
519505
{
520506
return array(
521507
'bar' => function (ProgressBar $bar, OutputInterface $output) {
522-
$completeBars = floor($bar->getMaxSteps() > 0 ? $bar->getProgressPercent() * $bar->getBarWidth() : $bar->getStep() % $bar->getBarWidth());
508+
$completeBars = floor($bar->getMaxSteps() > 0 ? $bar->getProgressPercent() * $bar->getBarWidth() : $bar->getProgress() % $bar->getBarWidth());
523509
$display = str_repeat($bar->getBarCharacter(), $completeBars);
524510
if ($completeBars < $bar->getBarWidth()) {
525511
$emptyBars = $bar->getBarWidth() - $completeBars - Helper::strlenWithoutDecoration($output->getFormatter(), $bar->getProgressCharacter());
@@ -536,10 +522,10 @@ private static function initPlaceholderFormatters()
536522
throw new \LogicException('Unable to display the remaining time if the maximum number of steps is not set.');
537523
}
538524

539-
if (!$bar->getStep()) {
525+
if (!$bar->getProgress()) {
540526
$remaining = 0;
541527
} else {
542-
$remaining = round((time() - $bar->getStartTime()) / $bar->getStep() * ($bar->getMaxSteps() - $bar->getStep()));
528+
$remaining = round((time() - $bar->getStartTime()) / $bar->getProgress() * ($bar->getMaxSteps() - $bar->getProgress()));
543529
}
544530

545531
return Helper::formatTime($remaining);
@@ -549,10 +535,10 @@ private static function initPlaceholderFormatters()
549535
throw new \LogicException('Unable to display the estimated time if the maximum number of steps is not set.');
550536
}
551537

552-
if (!$bar->getStep()) {
538+
if (!$bar->getProgress()) {
553539
$estimated = 0;
554540
} else {
555-
$estimated = round((time() - $bar->getStartTime()) / $bar->getStep() * $bar->getMaxSteps());
541+
$estimated = round((time() - $bar->getStartTime()) / $bar->getProgress() * $bar->getMaxSteps());
556542
}
557543

558544
return Helper::formatTime($estimated);
@@ -561,7 +547,7 @@ private static function initPlaceholderFormatters()
561547
return Helper::formatMemory(memory_get_usage(true));
562548
},
563549
'current' => function (ProgressBar $bar) {
564-
return str_pad($bar->getStep(), $bar->getStepWidth(), ' ', STR_PAD_LEFT);
550+
return str_pad($bar->getProgress(), $bar->getStepWidth(), ' ', STR_PAD_LEFT);
565551
},
566552
'max' => function (ProgressBar $bar) {
567553
return $bar->getMaxSteps();

0 commit comments

Comments
 (0)