Skip to content
Permalink
Browse files

feature #29753 [Console] Add an iterate method to the ProgressBar cla…

…ss (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
-------

eb35531 Add an iterate method to the ProgressBar class
  • Loading branch information...
chalasr committed Jan 31, 2019
2 parents 25fcc3e + eb35531 commit 9429face979c7194a9e7ccdcdc8e029be994c9fa
@@ -32,7 +32,8 @@
"symfony/polyfill-ctype": "~1.8",
"symfony/polyfill-intl-icu": "~1.0",
"symfony/polyfill-mbstring": "~1.0",
"symfony/polyfill-php72": "~1.5"
"symfony/polyfill-php72": "~1.5",
"symfony/polyfill-php73": "^1.8"
},
"replace": {
"symfony/asset": "self.version",
@@ -5,6 +5,7 @@ CHANGELOG
-----

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

4.2.0
-----
@@ -243,6 +243,24 @@ public function setRedrawFrequency(int $freq)
$this->redrawFreq = max($freq, 1);
}
/**
* Returns an iterator that will automatically update the progress bar when iterated.
*
* @param int|null $max Number of steps to complete the bar (0 if indeterminate), if null it will be inferred from $iterable
*/
public function iterate(iterable $iterable, ?int $max = null): iterable
{
$this->start($max ?? (\is_countable($iterable) ? \count($iterable) : 0));
foreach ($iterable as $key => $value) {
yield $key => $value;
$this->advance();
}
$this->finish();
}
/**
* Starts the progress output.
*
@@ -867,6 +867,41 @@ public function provideFormat()
];
}
public function testIterate(): void
{
$bar = new ProgressBar($output = $this->getOutputStream());
$this->assertEquals([1, 2], \iterator_to_array($bar->iterate([1, 2])));
rewind($output->getStream());
$this->assertEquals(
' 0/2 [>---------------------------] 0%'.
$this->generateOutput(' 1/2 [==============>-------------] 50%').
$this->generateOutput(' 2/2 [============================] 100%').
$this->generateOutput(' 2/2 [============================] 100%'),
stream_get_contents($output->getStream())
);
}
public function testIterateUncountable(): void
{
$bar = new ProgressBar($output = $this->getOutputStream());
$this->assertEquals([1, 2], \iterator_to_array($bar->iterate((function () {
yield 1;
yield 2;
})())));
rewind($output->getStream());
$this->assertEquals(
' 0 [>---------------------------]'.
$this->generateOutput(' 1 [->--------------------------]').
$this->generateOutput(' 2 [-->-------------------------]').
$this->generateOutput(' 2 [============================]'),
stream_get_contents($output->getStream())
);
}
protected function getOutputStream($decorated = true, $verbosity = StreamOutput::VERBOSITY_NORMAL)
{
return new StreamOutput(fopen('php://memory', 'r+', false), $verbosity, $decorated);
@@ -18,7 +18,8 @@
"require": {
"php": "^7.1.3",
"symfony/contracts": "^1.0",
"symfony/polyfill-mbstring": "~1.0"
"symfony/polyfill-mbstring": "~1.0",
"symfony/polyfill-php73": "^1.8"
},
"require-dev": {
"symfony/config": "~3.4|~4.0",

0 comments on commit 9429fac

Please sign in to comment.
You can’t perform that action at this time.