Skip to content

Commit

Permalink
[Console] Add Placeholders to ProgressBar for exactly times
Browse files Browse the repository at this point in the history
  • Loading branch information
maxbeckers committed Oct 9, 2023
1 parent 3147082 commit b553dd9
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 49 deletions.
51 changes: 31 additions & 20 deletions src/Symfony/Component/Console/Helper/Helper.php
Original file line number Diff line number Diff line change
Expand Up @@ -94,33 +94,44 @@ public static function substr(?string $string, int $from, int $length = null): s
/**
* @return string
*/
public static function formatTime(int|float $secs)
public static function formatTime(int|float $secs, int $precision = 1)
{
$secs = (int) floor($secs);

if (0 === $secs) {
return '< 1 sec';
}

static $timeFormats = [
[0, '< 1 sec'],
[1, '1 sec'],
[2, 'secs', 1],
[60, '1 min'],
[120, 'mins', 60],
[3600, '1 hr'],
[7200, 'hrs', 3600],
[86400, '1 day'],
[172800, 'days', 86400],
[1, '1 sec', 'secs'],
[60, '1 min', 'mins'],
[3600, '1 hr', 'hrs'],
[86400, '1 day', 'days'],
];

$times = [];
foreach ($timeFormats as $index => $format) {
if ($secs >= $format[0]) {
if ((isset($timeFormats[$index + 1]) && $secs < $timeFormats[$index + 1][0])
|| $index == \count($timeFormats) - 1
) {
if (2 == \count($format)) {
return $format[1];
}

return floor($secs / $format[2]).' '.$format[1];
}
$seconds = isset($timeFormats[$index + 1]) ? $secs % $timeFormats[$index + 1][0] : $secs;

if (isset($times[$index - $precision])) {
unset($times[$index - $precision]);
}

if (0 === $seconds) {
continue;
}

$unitCount = ($seconds / $format[0]);
$times[$index] = 1 === $unitCount ? $format[1] : $unitCount.' '.$format[2];

if ($secs === $seconds) {
break;
}

$secs -= $seconds;
}

return implode(', ', array_reverse($times));
}

/**
Expand Down
6 changes: 3 additions & 3 deletions src/Symfony/Component/Console/Helper/ProgressBar.php
Original file line number Diff line number Diff line change
Expand Up @@ -540,20 +540,20 @@ private static function initPlaceholderFormatters(): array

return $display;
},
'elapsed' => fn (self $bar) => Helper::formatTime(time() - $bar->getStartTime()),
'elapsed' => fn (self $bar) => Helper::formatTime(time() - $bar->getStartTime(), 2),
'remaining' => function (self $bar) {
if (!$bar->getMaxSteps()) {
throw new LogicException('Unable to display the remaining time if the maximum number of steps is not set.');
}

return Helper::formatTime($bar->getRemaining());
return Helper::formatTime($bar->getRemaining(), 2);
},
'estimated' => function (self $bar) {
if (!$bar->getMaxSteps()) {
throw new LogicException('Unable to display the estimated time if the maximum number of steps is not set.');
}

return Helper::formatTime($bar->getEstimated());
return Helper::formatTime($bar->getEstimated(), 2);
},
'memory' => fn (self $bar) => Helper::formatMemory(memory_get_usage(true)),
'current' => fn (self $bar) => str_pad($bar->getProgress(), $bar->getStepWidth(), ' ', \STR_PAD_LEFT),
Expand Down
2 changes: 1 addition & 1 deletion src/Symfony/Component/Console/Helper/ProgressIndicator.php
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ private static function initPlaceholderFormatters(): array
return [
'indicator' => fn (self $indicator) => $indicator->indicatorValues[$indicator->indicatorCurrent % \count($indicator->indicatorValues)],
'message' => fn (self $indicator) => $indicator->message,
'elapsed' => fn (self $indicator) => Helper::formatTime(time() - $indicator->startTime),
'elapsed' => fn (self $indicator) => Helper::formatTime(time() - $indicator->startTime, 2),
'memory' => fn () => Helper::formatMemory(memory_get_usage(true)),
];
}
Expand Down
52 changes: 27 additions & 25 deletions src/Symfony/Component/Console/Tests/Helper/HelperTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,26 +20,31 @@ class HelperTest extends TestCase
public static function formatTimeProvider()
{
return [
[0, '< 1 sec'],
[1, '1 sec'],
[2, '2 secs'],
[59, '59 secs'],
[60, '1 min'],
[61, '1 min'],
[119, '1 min'],
[120, '2 mins'],
[121, '2 mins'],
[3599, '59 mins'],
[3600, '1 hr'],
[7199, '1 hr'],
[7200, '2 hrs'],
[7201, '2 hrs'],
[86399, '23 hrs'],
[86400, '1 day'],
[86401, '1 day'],
[172799, '1 day'],
[172800, '2 days'],
[172801, '2 days'],
[0, '< 1 sec', 1],
[0.95, '< 1 sec', 1],
[1, '1 sec', 1],
[2, '2 secs', 2],
[59, '59 secs', 1],
[59.21, '59 secs', 1],
[60, '1 min', 2],
[61, '1 min, 1 sec', 2],
[119, '1 min, 59 secs', 2],
[120, '2 mins', 2],
[121, '2 mins, 1 sec', 2],
[3599, '59 mins, 59 secs', 2],
[3600, '1 hr', 2],
[7199, '1 hr, 59 mins', 2],
[7200, '2 hrs', 2],
[7201, '2 hrs', 2],
[86399, '23 hrs, 59 mins', 2],
[86399, '23 hrs, 59 mins, 59 secs', 3],
[86400, '1 day', 2],
[86401, '1 day', 2],
[172799, '1 day, 23 hrs', 2],
[172799, '1 day, 23 hrs, 59 mins, 59 secs', 4],
[172800, '2 days', 2],
[172801, '2 days', 2],
[172801, '2 days, 1 sec', 4],
];
}

Expand All @@ -55,13 +60,10 @@ public static function decoratedTextProvider()

/**
* @dataProvider formatTimeProvider
*
* @param int $secs
* @param string $expectedFormat
*/
public function testFormatTime($secs, $expectedFormat)
public function testFormatTime(int|float $secs, string $expectedFormat, int $precision)
{
$this->assertEquals($expectedFormat, Helper::formatTime($secs));
$this->assertEquals($expectedFormat, Helper::formatTime($secs, $precision));
}

/**
Expand Down
12 changes: 12 additions & 0 deletions src/Symfony/Component/Console/Tests/Helper/ProgressBarTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1005,6 +1005,18 @@ public function testSetFormat()
);
}

public function testSetFormatWithTimes()
{
$bar = new ProgressBar($output = $this->getOutputStream(), 15, 0);
$bar->setFormat('%current%/%max% [%bar%] %percent:3s%% %elapsed:6s%/%estimated:-6s%/%remaining:-6s%');
$bar->start();
rewind($output->getStream());
$this->assertEquals(
' 0/15 [>---------------------------] 0% < 1 sec/< 1 sec/< 1 sec',
stream_get_contents($output->getStream())
);
}

public function testUnicode()
{
$bar = new ProgressBar($output = $this->getOutputStream(), 10, 0);
Expand Down

0 comments on commit b553dd9

Please sign in to comment.