Skip to content

Commit 2d5e1d6

Browse files
committed
[Console] Add Placeholders to ProgressBar for exactly times
1 parent b65b268 commit 2d5e1d6

File tree

5 files changed

+74
-49
lines changed

5 files changed

+74
-49
lines changed

Helper/Helper.php

+31-20
Original file line numberDiff line numberDiff line change
@@ -94,33 +94,44 @@ public static function substr(?string $string, int $from, int $length = null): s
9494
/**
9595
* @return string
9696
*/
97-
public static function formatTime(int|float $secs)
97+
public static function formatTime(int|float $secs, int $precision = 1)
9898
{
99+
$secs = (int) floor($secs);
100+
101+
if (0 === $secs) {
102+
return '< 1 sec';
103+
}
104+
99105
static $timeFormats = [
100-
[0, '< 1 sec'],
101-
[1, '1 sec'],
102-
[2, 'secs', 1],
103-
[60, '1 min'],
104-
[120, 'mins', 60],
105-
[3600, '1 hr'],
106-
[7200, 'hrs', 3600],
107-
[86400, '1 day'],
108-
[172800, 'days', 86400],
106+
[1, '1 sec', 'secs'],
107+
[60, '1 min', 'mins'],
108+
[3600, '1 hr', 'hrs'],
109+
[86400, '1 day', 'days'],
109110
];
110111

112+
$times = [];
111113
foreach ($timeFormats as $index => $format) {
112-
if ($secs >= $format[0]) {
113-
if ((isset($timeFormats[$index + 1]) && $secs < $timeFormats[$index + 1][0])
114-
|| $index == \count($timeFormats) - 1
115-
) {
116-
if (2 == \count($format)) {
117-
return $format[1];
118-
}
119-
120-
return floor($secs / $format[2]).' '.$format[1];
121-
}
114+
$seconds = isset($timeFormats[$index + 1]) ? $secs % $timeFormats[$index + 1][0] : $secs;
115+
116+
if (isset($times[$index - $precision])) {
117+
unset($times[$index - $precision]);
118+
}
119+
120+
if (0 === $seconds) {
121+
continue;
122122
}
123+
124+
$unitCount = ($seconds / $format[0]);
125+
$times[$index] = 1 === $unitCount ? $format[1] : $unitCount.' '.$format[2];
126+
127+
if ($secs === $seconds) {
128+
break;
129+
}
130+
131+
$secs -= $seconds;
123132
}
133+
134+
return implode(', ', array_reverse($times));
124135
}
125136

126137
/**

Helper/ProgressBar.php

+3-3
Original file line numberDiff line numberDiff line change
@@ -540,20 +540,20 @@ private static function initPlaceholderFormatters(): array
540540

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

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

556-
return Helper::formatTime($bar->getEstimated());
556+
return Helper::formatTime($bar->getEstimated(), 2);
557557
},
558558
'memory' => fn (self $bar) => Helper::formatMemory(memory_get_usage(true)),
559559
'current' => fn (self $bar) => str_pad($bar->getProgress(), $bar->getStepWidth(), ' ', \STR_PAD_LEFT),

Helper/ProgressIndicator.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ private static function initPlaceholderFormatters(): array
228228
return [
229229
'indicator' => fn (self $indicator) => $indicator->indicatorValues[$indicator->indicatorCurrent % \count($indicator->indicatorValues)],
230230
'message' => fn (self $indicator) => $indicator->message,
231-
'elapsed' => fn (self $indicator) => Helper::formatTime(time() - $indicator->startTime),
231+
'elapsed' => fn (self $indicator) => Helper::formatTime(time() - $indicator->startTime, 2),
232232
'memory' => fn () => Helper::formatMemory(memory_get_usage(true)),
233233
];
234234
}

Tests/Helper/HelperTest.php

+27-25
Original file line numberDiff line numberDiff line change
@@ -20,26 +20,31 @@ class HelperTest extends TestCase
2020
public static function formatTimeProvider()
2121
{
2222
return [
23-
[0, '< 1 sec'],
24-
[1, '1 sec'],
25-
[2, '2 secs'],
26-
[59, '59 secs'],
27-
[60, '1 min'],
28-
[61, '1 min'],
29-
[119, '1 min'],
30-
[120, '2 mins'],
31-
[121, '2 mins'],
32-
[3599, '59 mins'],
33-
[3600, '1 hr'],
34-
[7199, '1 hr'],
35-
[7200, '2 hrs'],
36-
[7201, '2 hrs'],
37-
[86399, '23 hrs'],
38-
[86400, '1 day'],
39-
[86401, '1 day'],
40-
[172799, '1 day'],
41-
[172800, '2 days'],
42-
[172801, '2 days'],
23+
[0, '< 1 sec', 1],
24+
[0.95, '< 1 sec', 1],
25+
[1, '1 sec', 1],
26+
[2, '2 secs', 2],
27+
[59, '59 secs', 1],
28+
[59.21, '59 secs', 1],
29+
[60, '1 min', 2],
30+
[61, '1 min, 1 sec', 2],
31+
[119, '1 min, 59 secs', 2],
32+
[120, '2 mins', 2],
33+
[121, '2 mins, 1 sec', 2],
34+
[3599, '59 mins, 59 secs', 2],
35+
[3600, '1 hr', 2],
36+
[7199, '1 hr, 59 mins', 2],
37+
[7200, '2 hrs', 2],
38+
[7201, '2 hrs', 2],
39+
[86399, '23 hrs, 59 mins', 2],
40+
[86399, '23 hrs, 59 mins, 59 secs', 3],
41+
[86400, '1 day', 2],
42+
[86401, '1 day', 2],
43+
[172799, '1 day, 23 hrs', 2],
44+
[172799, '1 day, 23 hrs, 59 mins, 59 secs', 4],
45+
[172800, '2 days', 2],
46+
[172801, '2 days', 2],
47+
[172801, '2 days, 1 sec', 4],
4348
];
4449
}
4550

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

5661
/**
5762
* @dataProvider formatTimeProvider
58-
*
59-
* @param int $secs
60-
* @param string $expectedFormat
6163
*/
62-
public function testFormatTime($secs, $expectedFormat)
64+
public function testFormatTime(int|float $secs, string $expectedFormat, int $precision)
6365
{
64-
$this->assertEquals($expectedFormat, Helper::formatTime($secs));
66+
$this->assertEquals($expectedFormat, Helper::formatTime($secs, $precision));
6567
}
6668

6769
/**

Tests/Helper/ProgressBarTest.php

+12
Original file line numberDiff line numberDiff line change
@@ -1005,6 +1005,18 @@ public function testSetFormat()
10051005
);
10061006
}
10071007

1008+
public function testSetFormatWithTimes()
1009+
{
1010+
$bar = new ProgressBar($output = $this->getOutputStream(), 15, 0);
1011+
$bar->setFormat('%current%/%max% [%bar%] %percent:3s%% %elapsed:6s%/%estimated:-6s%/%remaining:-6s%');
1012+
$bar->start();
1013+
rewind($output->getStream());
1014+
$this->assertEquals(
1015+
' 0/15 [>---------------------------] 0% < 1 sec/< 1 sec/< 1 sec',
1016+
stream_get_contents($output->getStream())
1017+
);
1018+
}
1019+
10081020
public function testUnicode()
10091021
{
10101022
$bar = new ProgressBar($output = $this->getOutputStream(), 10, 0);

0 commit comments

Comments
 (0)