Skip to content

Commit 1eecd3b

Browse files
committed
[Console] Add Placeholders to ProgressBar for exactly times
1 parent 6ee2b44 commit 1eecd3b

File tree

4 files changed

+111
-0
lines changed

4 files changed

+111
-0
lines changed

src/Symfony/Component/Console/Helper/Helper.php

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,42 @@ public static function formatTime(int|float $secs)
123123
}
124124
}
125125

126+
public static function formatTimeExactly(int|float $secs): string
127+
{
128+
$secs = (int) floor($secs);
129+
130+
if (0 === $secs) {
131+
return '< 1 sec';
132+
}
133+
134+
static $timeFormats = [
135+
[1, '1 sec', 'secs'],
136+
[60, '1 min', 'mins'],
137+
[3600, '1 hr', 'hrs'],
138+
[86400, '1 day', 'days'],
139+
];
140+
141+
$times = [];
142+
foreach ($timeFormats as $index => $format) {
143+
$seconds = isset($timeFormats[$index + 1]) ? $secs % $timeFormats[$index + 1][0] : $secs;
144+
145+
if (0 === $seconds) {
146+
continue;
147+
}
148+
149+
$unitCount = ($seconds / $format[0]);
150+
$times[] = 1 === $unitCount ? $format[1] : $unitCount.' '.$format[2];
151+
152+
if ($secs === $seconds) {
153+
break;
154+
}
155+
156+
$secs -= $seconds;
157+
}
158+
159+
return implode(', ', array_reverse($times));
160+
}
161+
126162
/**
127163
* @return string
128164
*/

src/Symfony/Component/Console/Helper/ProgressBar.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -535,20 +535,35 @@ private static function initPlaceholderFormatters(): array
535535
return $display;
536536
},
537537
'elapsed' => fn (self $bar) => Helper::formatTime(time() - $bar->getStartTime()),
538+
'elapsed_time_exactly' => fn (self $bar) => Helper::formatTimeExactly(time() - $bar->getStartTime()),
538539
'remaining' => function (self $bar) {
539540
if (!$bar->getMaxSteps()) {
540541
throw new LogicException('Unable to display the remaining time if the maximum number of steps is not set.');
541542
}
542543

543544
return Helper::formatTime($bar->getRemaining());
544545
},
546+
'remaining_time_exactly' => function (self $bar) {
547+
if (!$bar->getMaxSteps()) {
548+
throw new LogicException('Unable to display the remaining time if the maximum number of steps is not set.');
549+
}
550+
551+
return Helper::formatTimeExactly($bar->getRemaining());
552+
},
545553
'estimated' => function (self $bar) {
546554
if (!$bar->getMaxSteps()) {
547555
throw new LogicException('Unable to display the estimated time if the maximum number of steps is not set.');
548556
}
549557

550558
return Helper::formatTime($bar->getEstimated());
551559
},
560+
'estimated_time_exactly' => function (self $bar) {
561+
if (!$bar->getMaxSteps()) {
562+
throw new LogicException('Unable to display the estimated time if the maximum number of steps is not set.');
563+
}
564+
565+
return Helper::formatTimeExactly($bar->getEstimated());
566+
},
552567
'memory' => fn (self $bar) => Helper::formatMemory(memory_get_usage(true)),
553568
'current' => fn (self $bar) => str_pad($bar->getProgress(), $bar->getStepWidth(), ' ', \STR_PAD_LEFT),
554569
'max' => fn (self $bar) => $bar->getMaxSteps(),

src/Symfony/Component/Console/Tests/Helper/HelperTest.php

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,34 @@ public static function formatTimeProvider()
4343
];
4444
}
4545

46+
public static function formatTimeExactlyProvider()
47+
{
48+
return [
49+
[0, '< 1 sec'],
50+
[0.95, '< 1 sec'],
51+
[1, '1 sec'],
52+
[2, '2 secs'],
53+
[59, '59 secs'],
54+
[59.21, '59 secs'],
55+
[60, '1 min'],
56+
[61, '1 min, 1 sec'],
57+
[119, '1 min, 59 secs'],
58+
[120, '2 mins'],
59+
[121, '2 mins, 1 sec'],
60+
[3599, '59 mins, 59 secs'],
61+
[3600, '1 hr'],
62+
[7199, '1 hr, 59 mins, 59 secs'],
63+
[7200, '2 hrs'],
64+
[7201, '2 hrs, 1 sec'],
65+
[86399, '23 hrs, 59 mins, 59 secs'],
66+
[86400, '1 day'],
67+
[86401, '1 day, 1 sec'],
68+
[172799, '1 day, 23 hrs, 59 mins, 59 secs'],
69+
[172800, '2 days'],
70+
[172801, '2 days, 1 sec'],
71+
];
72+
}
73+
4674
public static function decoratedTextProvider()
4775
{
4876
return [
@@ -64,6 +92,17 @@ public function testFormatTime($secs, $expectedFormat)
6492
$this->assertEquals($expectedFormat, Helper::formatTime($secs));
6593
}
6694

95+
/**
96+
* @dataProvider formatTimeExactlyProvider
97+
*
98+
* @param int $secs
99+
* @param string $expectedFormat
100+
*/
101+
public function testFormatTimeExactly($secs, $expectedFormat)
102+
{
103+
$this->assertEquals($expectedFormat, Helper::formatTimeExactly($secs));
104+
}
105+
67106
/**
68107
* @dataProvider decoratedTextProvider
69108
*/

src/Symfony/Component/Console/Tests/Helper/ProgressBarTest.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1005,6 +1005,27 @@ 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+
$bar = new ProgressBar($output = $this->getOutputStream(), 15, 0);
1020+
$bar->setFormat('%current%/%max% [%bar%] %percent:3s%% %elapsed_time_exactly%/%estimated_time_exactly%/%remaining_time_exactly%');
1021+
$bar->start();
1022+
rewind($output->getStream());
1023+
$this->assertEquals(
1024+
' 0/15 [>---------------------------] 0% < 1 sec/< 1 sec/< 1 sec',
1025+
stream_get_contents($output->getStream())
1026+
);
1027+
}
1028+
10081029
public function testUnicode()
10091030
{
10101031
$bar = new ProgressBar($output = $this->getOutputStream(), 10, 0);

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy