Skip to content

Commit 58add01

Browse files
author
Robin Chalas
committed
feature #29753 [Console] Add an iterate method to the ProgressBar class (jvasseur)
This PR was merged into the 4.3-dev branch. Discussion ---------- [Console] Add an iterate method to the ProgressBar class | Q | A | ------------- | --- | Branch? | master | Bug fix? | no | New feature? | yes | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | | License | MIT | Doc PR | symfony/symfony-docs#10949 Add an iterate method to the `ProgressBar` class that simplify updating the progress bar when iterating over an `iterable`. Before: ```php $bar->start(); foreach ($iterable as $value) { // Process $value $bar->advance(); } $bar->finish(); ``` After: ```php foreach ($bar->iterate($iterable) as $value) { // Process $value } ``` Additionally if `$iterable` is countable, the progress bar max step will automatically set to its count. If it isn't countable, nothing is done (instead of setting it to 0) to allow passing a max independently before calling `iterate`. I will try to do the doc PR soon. Commits ------- eb355314b0 Add an iterate method to the ProgressBar class
2 parents 3089ec9 + 87da272 commit 58add01

File tree

4 files changed

+56
-1
lines changed

4 files changed

+56
-1
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ CHANGELOG
55
-----
66

77
* added support for hyperlinks
8+
* added `ProgressBar::iterate()` method that simplify updating the progress bar when iterating
89

910
4.2.0
1011
-----

Helper/ProgressBar.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,24 @@ public function setRedrawFrequency(int $freq)
243243
$this->redrawFreq = max($freq, 1);
244244
}
245245

246+
/**
247+
* Returns an iterator that will automatically update the progress bar when iterated.
248+
*
249+
* @param int|null $max Number of steps to complete the bar (0 if indeterminate), if null it will be inferred from $iterable
250+
*/
251+
public function iterate(iterable $iterable, ?int $max = null): iterable
252+
{
253+
$this->start($max ?? (\is_countable($iterable) ? \count($iterable) : 0));
254+
255+
foreach ($iterable as $key => $value) {
256+
yield $key => $value;
257+
258+
$this->advance();
259+
}
260+
261+
$this->finish();
262+
}
263+
246264
/**
247265
* Starts the progress output.
248266
*

Tests/Helper/ProgressBarTest.php

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -867,6 +867,41 @@ public function provideFormat()
867867
];
868868
}
869869

870+
public function testIterate(): void
871+
{
872+
$bar = new ProgressBar($output = $this->getOutputStream());
873+
874+
$this->assertEquals([1, 2], \iterator_to_array($bar->iterate([1, 2])));
875+
876+
rewind($output->getStream());
877+
$this->assertEquals(
878+
' 0/2 [>---------------------------] 0%'.
879+
$this->generateOutput(' 1/2 [==============>-------------] 50%').
880+
$this->generateOutput(' 2/2 [============================] 100%').
881+
$this->generateOutput(' 2/2 [============================] 100%'),
882+
stream_get_contents($output->getStream())
883+
);
884+
}
885+
886+
public function testIterateUncountable(): void
887+
{
888+
$bar = new ProgressBar($output = $this->getOutputStream());
889+
890+
$this->assertEquals([1, 2], \iterator_to_array($bar->iterate((function () {
891+
yield 1;
892+
yield 2;
893+
})())));
894+
895+
rewind($output->getStream());
896+
$this->assertEquals(
897+
' 0 [>---------------------------]'.
898+
$this->generateOutput(' 1 [->--------------------------]').
899+
$this->generateOutput(' 2 [-->-------------------------]').
900+
$this->generateOutput(' 2 [============================]'),
901+
stream_get_contents($output->getStream())
902+
);
903+
}
904+
870905
protected function getOutputStream($decorated = true, $verbosity = StreamOutput::VERBOSITY_NORMAL)
871906
{
872907
return new StreamOutput(fopen('php://memory', 'r+', false), $verbosity, $decorated);

composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@
1818
"require": {
1919
"php": "^7.1.3",
2020
"symfony/contracts": "^1.0",
21-
"symfony/polyfill-mbstring": "~1.0"
21+
"symfony/polyfill-mbstring": "~1.0",
22+
"symfony/polyfill-php73": "^1.8"
2223
},
2324
"require-dev": {
2425
"symfony/config": "~3.4|~4.0",

0 commit comments

Comments
 (0)