8000 [Console] Add Placeholders to ProgressBar for exactly times · symfony/symfony@1eecd3b · GitHub
[go: up one dir, main page]

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)
0