From 9e2727d628be64d5a1d8a730d2c3c7be9608cf34 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Mon, 3 Mar 2014 10:38:50 +0100 Subject: [PATCH] added documentation for the new Symfony 2.5 progress bar --- components/console/helpers/index.rst | 1 + components/console/helpers/map.rst.inc | 1 + components/console/helpers/progressbar.rst | 322 ++++++++++++++++++ components/console/helpers/progresshelper.rst | 11 +- images/components/console/progressbar.gif | Bin 0 -> 29016 bytes 5 files changed, 333 insertions(+), 2 deletions(-) create mode 100644 components/console/helpers/progressbar.rst create mode 100644 images/components/console/progressbar.gif diff --git a/components/console/helpers/index.rst b/components/console/helpers/index.rst index 1c95bc47057..35e9e56d4e3 100644 --- a/components/console/helpers/index.rst +++ b/components/console/helpers/index.rst @@ -9,6 +9,7 @@ The Console Helpers dialoghelper formatterhelper + progressbar progresshelper tablehelper diff --git a/components/console/helpers/map.rst.inc b/components/console/helpers/map.rst.inc index 60b32c03975..034af6fd43b 100644 --- a/components/console/helpers/map.rst.inc +++ b/components/console/helpers/map.rst.inc @@ -1,4 +1,5 @@ * :doc:`/components/console/helpers/dialoghelper` * :doc:`/components/console/helpers/formatterhelper` +* :doc:`/components/console/helpers/progressbar` * :doc:`/components/console/helpers/progresshelper` * :doc:`/components/console/helpers/tablehelper` diff --git a/components/console/helpers/progressbar.rst b/components/console/helpers/progressbar.rst new file mode 100644 index 00000000000..0cd119a0a9b --- /dev/null +++ b/components/console/helpers/progressbar.rst @@ -0,0 +1,322 @@ +.. index:: + single: Console Helpers; Progress Bar + +Progress Bar +============ + +.. versionadded:: 2.5 + The Progress Bar feature was introduced in Symfony 2.5 as a replacement for + the :doc:`Progress Helper `. + +When executing longer-running commands, it may be helpful to show progress +information, which updates as your command runs: + +.. image:: /images/components/console/progressbar.gif + +To display progress details, use the +:class:`Symfony\\Component\\Console\\Helper\\ProgressBar`, pass it a total +number of units, and advance the progress as the command executes:: + + use Symfony\Component\Console\Helper\ProgressBar; + + // create a new progress bar (50 units) + $progress = new ProgressBar($output, 50); + + // start and displays the progress bar + $progress->start(); + + $i = 0; + while ($i++ < 50) { + // ... do some work + + // advance the progress bar 1 unit + $progress->advance(); + + // you can also advance the progress bar by more than 1 unit + // $progress->advance(3); + } + + // ensure that the progress bar is at 100% + $progress->finish(); + +Instead of advancing the bar by a number of steps (with the +:method:`Symfony\\Component\\Console\\Helper\\ProgressBar::advance` method), +you can also set the current progress by calling the +:method:`Symfony\\Component\\Console\\Helper\\ProgressBar::setCurrent` method. + +.. caution:: + + The progress bar only works if your platform supports ANSI codes; on other + platforms, no output is generated. + +If you don't know the number of steps in advance, just omit the steps argument +when creating the :class:`Symfony\\Component\\Console\\Helper\\ProgressBar` +instance:: + + $progress = new ProgressBar($output); + +The progress will then be displayed as a throbber:: + +.. code-block:: text + + # no max steps (displays it like a throbber) + 0 [>---------------------------] + 5 [----->----------------------] + 5 [============================] + + # max steps defined + 0/3 [>---------------------------] 0% + 1/3 [=========>------------------] 33% + 3/3 [============================] 100% + +Whenever your task is finished, don't forget to call +:method:`Symfony\\Component\\Console\\Helper\\ProgressBar::finish` to ensure +that the progress bar display is refreshed with a 100% completion. + +.. note:: + + If you want to output something while the progress bar is running, + call :method:`Symfony\\Component\\Console\\Helper\\ProgressBar::clear` first. + After you're done, call + :method:`Symfony\\Component\\Console\\Helper\\ProgressBar::display` + to show the progress bar again. + +Customizing the Progress Bar +---------------------------- + +Built-in Formats +~~~~~~~~~~~~~~~~ + +By default, the information rendered on a progress bar depends on the current +level of verbosity of the ``OutputInterface`` instance: + +.. code-block:: text + + # OutputInterface::VERBOSITY_NORMAL (CLI with no verbosity flag) + 0/3 [>---------------------------] 0% + 1/3 [=========>------------------] 33% + 3/3 [============================] 100% + + # OutputInterface::VERBOSITY_VERBOSE (-v) + 0/3 [>---------------------------] 0% 1 sec + 1/3 [=========>------------------] 33% 1 sec + 3/3 [============================] 100% 1 sec + + # OutputInterface::VERBOSITY_VERY_VERBOSE (-vv) + 0/3 [>---------------------------] 0% 1 sec + 1/3 [=========>------------------] 33% 1 sec + 3/3 [============================] 100% 1 sec + + # OutputInterface::VERBOSITY_DEBUG (-vvv) + 0/3 [>---------------------------] 0% 1 sec/1 sec 1.0 MB + 1/3 [=========>------------------] 33% 1 sec/1 sec 1.0 MB + 3/3 [============================] 100% 1 sec/1 sec 1.0 MB + +.. note:: + + If you call a command with the quiet flag (``-q``), the progress bar won't + be displayed. + +Instead of relying on the verbosity mode of the current command, you can also +force a format via ``setFormat()``:: + + $bar->setFormat('verbose'); + +The built-in formats are the following: + +* ``normal`` +* ``verbose`` +* ``very_verbose`` +* ``debug`` + +If you don't set the number of steps for your progress bar, use the ``_nomax`` +variants: + +* ``normal_nomax`` +* ``verbose_nomax`` +* ``very_verbose_nomax`` +* ``debug_nomax`` + +Custom Formats +~~~~~~~~~~~~~~ + +Instead of using the built-in formats, you can also set your own:: + + $bar->setFormat('%bar%'); + +This sets the format to only display the progress bar itself: + +.. code-block:: text + + >--------------------------- + =========>------------------ + ============================ + +A progress bar format is a string that contains specific placeholders (a name +enclosed with the ``%`` character); the placeholders are replaced based on the +current progress of the bar. Here is a list of the built-in placeholders: + +* ``current``: The current step; +* ``max``: The maximum number of steps (or 0 if no max is defined); +* ``bar``: The bar itself; +* ``percent``: The percentage of completion (not available if no max is defined); +* ``elapsed``: The time elapsed since the start of the progress bar; +* ``remaining``: The remaining time to complete the task (not available if no max is defined); +* ``estimated``: The estimated time to complete the task (not available if no max is defined); +* ``memory``: The current memory usage; +* ``message``: The current message attached to the progress bar. + +For instance, here is how you could set the format to be the same as the +``debug`` one:: + + $bar->setFormat(' %current%/%max% [%bar%] %percent:3s%% %elapsed:6s%/%estimated:-6s% %memory:6s%'); + +Notice the ``:6s`` part added to some placeholders? That's how you can tweak +the appearance of the bar (formatting and alignment). The part after the colon +(``:``) is used to set the ``sprintf`` format of the string. + +The ``message`` placeholder is a bit special as you must set the value +yourself:: + + $bar->setMessage('Task starts'); + $bar->start(); + + $bar->setMessage('Task in progress...'); + $bar->advance(); + + // ... + + $bar->setMessage('Task is finished'); + $bar->finish(); + +Instead of setting the format for a given instance of a progress bar, you can +also define global formats:: + + ProgressBar::setFormatDefinition('minimal', 'Progress: %percent%%'); + + $bar = new ProgressBar($output, 3); + $bar->setFormat('minimal'); + +This code defines a new ``minimal`` format that you can then use for your +progress bars: + +.. code-block:: text + + Progress: 0% + Progress: 33% + Progress: 100% + +.. tip:: + + It is almost always better to redefine built-in formats instead of creating + new ones as that allows the display to automatically vary based on the + verbosity flag of the command. + +When defining a new style that contains placeholders that are only available +when the maximum number of steps is known, you should create a ``_nomax`` +variant:: + + ProgressBar::setFormatDefinition('minimal', '%percent%% %remaining%'); + ProgressBar::setFormatDefinition('minimal_nomax', '%percent%%'); + + $bar = new ProgressBar($output); + $bar->setFormat('minimal'); + +When displaying the progress bar, the format will automatically be set to +``minimal_nomax`` if the bar does not have a maximum number of steps like in +the example above. + +.. tip:: + + A format can contain any valid ANSI codes and can also use the + Symfony-specific way to set colors:: + + ProgressBar::setFormatDefinition( + 'minimal', + '%percent%\033[32m%\033[0m %remaining%' + ); + +.. note:: + + A format can span more than one line; that's very useful when you want to + display more contextual information alongside the progress bar (see the + example at the beginning of this article). + +Bar Settings +~~~~~~~~~~~~ + +Amongst the placeholders, ``bar`` is a bit special as all the characters used +to display it can be customized:: + + // the finished part of the bar + $progress->setBarCharacter('='); + + // the unfinished part of the bar + $progress->setEmptyBarCharacter(' '); + + // the progress character + $progress->setProgressCharacter('|'); + + // the bar width + $progress->setBarWidth(50); + +.. caution:: + + For performance reasons, be careful if you set the total number of steps + to a high number. For example, if you're iterating over a large number of + items, consider setting the redraw frequency to a higher value by calling + :method:`Symfony\\Component\\Console\\Helper\\ProgressHelper::setRedrawFrequency`, + so it updates on only some iterations:: + + $progress->start($output, 50000); + + // update every 100 iterations + $progress->setRedrawFrequency(100); + + $i = 0; + while ($i++ < 50000) { + // ... do some work + + $progress->advance(); + } + +Custom Placeholders +~~~~~~~~~~~~~~~~~~~ + +If you want to display some information that depends on the progress bar +display that are not available in the list of built-in placeholders, you can +create your own. Let's see how you can create a ``remaining_steps`` placeholder +that displays the number of remaining steps:: + + ProgressBar::setPlaceholderFormatter( + '%remaining_steps%', + function (ProgressBar $bar, OutputInterface $output) { + return $bar->getMaxSteps() - $bar->getStep(); + } + ); + +Custom Messages +~~~~~~~~~~~~~~~ + +The ``%message%`` placeholder allows you to specify a custom message to be +displayed with the progress bar. But if you need more than one, just define +your own:: + + $bar->setMessage('Task starts'); + $bar->setMessage('', 'filename'); + $bar->start(); + + $bar->setMessage('Task is in progress...'); + while ($file = array_pop($files)) { + $bar->setMessage($filename, 'filename'); + $bar->advance(); + } + + $bar->setMessage('Task is finished'); + $bar->setMessage('', 'filename'); + $bar->finish(); + +For the ``filename`` to be part of the progress bar, just add the +``%filename%`` placeholder in your format:: + + $bar->setFormat(" %message%\n %step%/%max%\n Working on %filename%"); diff --git a/components/console/helpers/progresshelper.rst b/components/console/helpers/progresshelper.rst index 9ee76b694cb..3722b3fe213 100644 --- a/components/console/helpers/progresshelper.rst +++ b/components/console/helpers/progresshelper.rst @@ -10,6 +10,13 @@ Progress Helper .. versionadded:: 2.4 The ``clear`` method was added in Symfony 2.4. +.. caution:: + + The Progress Helper was deprecated in Symfony 2.5 and will be removed in + Symfony 3.0. You should now use the + :doc:`Progress Bar ` instead which + is more powerful. + When executing longer-running commands, it may be helpful to show progress information, which updates as your command runs: @@ -25,7 +32,7 @@ pass it a total number of units, and advance the progress as your command execut while ($i++ < 50) { // ... do some work - // advance the progress bar 1 unit + // advances the progress bar 1 unit $progress->advance(); } @@ -79,7 +86,7 @@ To see other available options, check the API documentation for $progress->start($output, 50000); - // update every 100 iterations + // updates every 100 iterations $progress->setRedrawFrequency(100); $i = 0; diff --git a/images/components/console/progressbar.gif b/images/components/console/progressbar.gif new file mode 100644 index 0000000000000000000000000000000000000000..6c80e6e897f670d0a53a1dc115bbe34a71fa1568 GIT binary patch literal 29016 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
ZeTPcbORBHACKVq0VF$~>Ex^4p#$>AvyurY zAfPS-h#l zDl)&xcvEusa7ra3^(hljLqIu(-HZX$&~F`-(=!ZoV)E-7@|!yVK~$KN01$GZ7E?@P z77wu4%BYc1(%QooN53-->^4jzgI$FgV6dw&jny^9DZi^QopoL8{u%(pfi_IzAcKv? z89*Cmn5~0=_yTLVt&Q0>l+8xr_4z;{<}VNjIxzqc?>r53VtTrOAVeMj#QQp#f7>t& z*1!OBaAx#BI%s~HF*(cv3Nj-M*8K2rU(KHq3>%BTnHirQ21+n&GR|a9j^zkg=u z1729kISGF|5L5^S)2R1x?J^1$>`Pujog|zrg}&OkjFqu`5yYoU*z9Z%3avjmEA54o zQYGd4Imcd)Tg?7L1q9OZn=ULkA$Mf=iA%zMrP zw1b~t_t(N@6Iq*&TUA@El`|hq`09z*D?6uOX|PwDkIpgQHo5IobZXbl?SMOn4}I#^ z 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 literal 0 HcmV?d00001