From 223a23254516e0f50f07322fc8799fab5076e390 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Vasseur?= Date: Thu, 3 Jan 2019 00:00:39 +0100 Subject: [PATCH] Add an iterate method to the ProgressBar class --- composer.json | 3 +- src/Symfony/Component/Console/CHANGELOG.md | 1 + .../Component/Console/Helper/ProgressBar.php | 18 ++++++++++ .../Console/Tests/Helper/ProgressBarTest.php | 35 +++++++++++++++++++ src/Symfony/Component/Console/composer.json | 3 +- 5 files changed, 58 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index cd0975a681f06..a497252d45e4f 100644 --- a/composer.json +++ b/composer.json @@ -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.0" }, "replace": { "symfony/asset": "self.version", diff --git a/src/Symfony/Component/Console/CHANGELOG.md b/src/Symfony/Component/Console/CHANGELOG.md index e014a4e2f3c30..ff7973319c04c 100644 --- a/src/Symfony/Component/Console/CHANGELOG.md +++ b/src/Symfony/Component/Console/CHANGELOG.md @@ -5,6 +5,7 @@ CHANGELOG ----- * added support for hyperlinks + * added `ProgressBar::iterate()` method that simplify updating the progress bar when iterating 4.2.0 ----- diff --git a/src/Symfony/Component/Console/Helper/ProgressBar.php b/src/Symfony/Component/Console/Helper/ProgressBar.php index b68d9fe389a17..f768b21c568e6 100644 --- a/src/Symfony/Component/Console/Helper/ProgressBar.php +++ b/src/Symfony/Component/Console/Helper/ProgressBar.php @@ -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. * diff --git a/src/Symfony/Component/Console/Tests/Helper/ProgressBarTest.php b/src/Symfony/Component/Console/Tests/Helper/ProgressBarTest.php index d4aa3e9f367c6..5eac776452603 100644 --- a/src/Symfony/Component/Console/Tests/Helper/ProgressBarTest.php +++ b/src/Symfony/Component/Console/Tests/Helper/ProgressBarTest.php @@ -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); diff --git a/src/Symfony/Component/Console/composer.json b/src/Symfony/Component/Console/composer.json index 6a6805367ec30..b450d5ab5c6c1 100644 --- a/src/Symfony/Component/Console/composer.json +++ b/src/Symfony/Component/Console/composer.json @@ -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.0" }, "require-dev": { "symfony/config": "~3.4|~4.0",