Skip to content

Commit

Permalink
Merge pull request #6618 from cakephp/progress-bar
Browse files Browse the repository at this point in the history
Implement Progress bar Helper
  • Loading branch information
lorenzo committed May 28, 2015
2 parents 85a8f8a + 7349342 commit a4f5190
Show file tree
Hide file tree
Showing 9 changed files with 415 additions and 50 deletions.
5 changes: 4 additions & 1 deletion src/Console/ConsoleIo.php
Expand Up @@ -399,7 +399,10 @@ public function helper($name, array $settings = [])
*/
public function __call($method, $args)
{
$helper = $this->helper($method, $args);
$helper = $this->helper($method);
if (count($args) === 1 && isset($args[0]) && is_array($args[0])) {
$args = $args[0];
}
return $helper->output($args);
}
}
131 changes: 131 additions & 0 deletions src/Shell/Helper/ProgressHelper.php
@@ -0,0 +1,131 @@
<?php
/**
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP Project
* @since 3.1.0
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
namespace Cake\Shell\Helper;

use Cake\Console\Helper;
use RuntimeException;

/**
* Create a progress bar using a supplied callback.
*/
class ProgressHelper extends Helper
{
/**
* The current progress.
*
* @var int
*/
protected $_progress = 0;

/**
* The total number of 'items' to progress through.
*
* @var int
*/
protected $_total = 0;

/**
* The width of the bar.
*
* @var int
*/
protected $_width = 0;

/**
* Output a progress bar.
*
* Takes a number of options to customize the behavior:
*
* - `total` The total number of items in the progress bar. Defaults
* to 100.
* - `width` The width of the progress bar. Defaults to 80.
* - `callback` The callback that will be called in a loop to advance the progress bar.
*
* @param array $args The arguments/options to use when outputing the progress bar.
* @return void
*/
public function output($args)
{
$args += ['callback' => null];
if (isset($args[0])) {
$args['callback'] = $args[0];
}
if (!$args['callback'] || !is_callable($args['callback'])) {
throw new RuntimeException('Callback option must be a callable.');
}
$this->init($args);

$callback = $args['callback'];
while ($this->_progress < $this->_total) {
$callback($this);
$this->draw();
}
$this->_io->out('');
}

/**
* Initialize the progress bar for use.
*
* - `total` The total number of items in the progress bar. Defaults
* to 100.
* - `width` The width of the progress bar. Defaults to 80.
*
* @param array $args The initialization data.
* @return void
*/
public function init(array $args = [])
{
$args += ['total' => 100, 'width' => 80];
$this->_progress = 0;
$this->_width = $args['width'];
$this->_total = $args['total'];
}

/**
* Increment the progress bar.
*
* @param int $num The amount of progress to advance by.
* @return void
*/
public function increment($num = 1)
{
$this->_progress = min(max(0, $this->_progress + $num), $this->_total);
}

/**
* Render the progress bar based on the current state.
*
* @return void
*/
public function draw()
{
$numberLen = strlen(' 100%');
$complete = round($this->_progress / $this->_total, 2);
$barLen = ($this->_width - $numberLen) * ($this->_progress / $this->_total);
$bar = '';
if ($barLen > 1) {
$bar = str_repeat('=', $barLen - 1) . '>';
}

$pad = $this->_width - $numberLen - $barLen;
if ($pad > 0) {
$bar .= str_repeat(' ', $pad);
}
$percent = ($complete * 100) . '%';
$bar .= str_pad($percent, $numberLen, ' ', STR_PAD_LEFT);

$this->_io->overwrite($bar, 0);
}
}
3 changes: 0 additions & 3 deletions src/Shell/Helper/TableHelper.php
Expand Up @@ -83,9 +83,6 @@ protected function _render($row, $widths)
*/
public function output($rows)
{
if (count($rows) === 1) {
$rows = $rows[0];
}
$widths = $this->_calculateWidths($rows);

$this->_rowSeparator($widths);
Expand Down
12 changes: 11 additions & 1 deletion src/Shell/Task/ExtractTask.php
Expand Up @@ -349,9 +349,15 @@ public function getOptionParser()
*/
protected function _extractTokens()
{
$progress = $this->_io->helper('progress');
$progress->init(['total' => count($this->_files)]);
$isVerbose = $this->param('verbose');

foreach ($this->_files as $file) {
$this->_file = $file;
$this->out(sprintf('Processing %s...', $file), 1, Shell::VERBOSE);
if ($isVerbose) {
$this->out(sprintf('Processing %s...', $file), 1, Shell::VERBOSE);
}

$code = file_get_contents($file);
$allTokens = token_get_all($code);
Expand All @@ -372,6 +378,10 @@ protected function _extractTokens()
$this->_parse('__dx', ['domain', 'context', 'singular']);
$this->_parse('__dxn', ['domain', 'context', 'singular', 'plural']);

if (!$isVerbose) {
$progress->increment(1);
$progress->draw();
}
}
}

Expand Down
63 changes: 63 additions & 0 deletions src/TestSuite/Stub/ConsoleOutput.php
@@ -0,0 +1,63 @@
<?php
/**
* CakePHP : Rapid Development Framework (http://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP Project
* @since 3.1.0
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
namespace Cake\TestSuite\Stub;

use Cake\Console\ConsoleOutput as ConsoleOutputBase;

/**
* StubOutput makes testing shell commands/shell helpers easier.
*
* You can use this class by injecting it into a ConsoleIo instance
* that your command/task/helper uses:
*
* ```
* use Cake\Console\ConsoleIo;
* use Cake\TestSuite\Stub\ConsoleOutput;
*
* $output = new ConsoleOutput();
* $io = new ConsoleIo($output);
* ```
*/
class ConsoleOutput extends ConsoleOutputBase
{
/**
* Buffered messages.
*
* @var array
*/
protected $_out = [];

/**
* Write output to the buffer.
*
* @param string $message The message to write.
* @param int $newlines Unused.
* @return void
*/
public function write($message, $newlines = 1)
{
$this->_out[] = $message;
}

/**
* Get the buffered output.
*
* @return array
*/
public function messages()
{
return $this->_out;
}
}
9 changes: 7 additions & 2 deletions tests/TestCase/Console/ConsoleIoTest.php
Expand Up @@ -380,9 +380,14 @@ public function testHelper()
*/
public function testHelperCall()
{
$this->out->expects($this->once())
$this->out->expects($this->at(0))
->method('write')
->with('It works!well ish');
$this->out->expects($this->at(1))
->method('write')
->with('It works!well ish');
$helper = $this->io->simple('well', 'ish');

$this->io->simple('well', 'ish');
$this->io->simple(['well', 'ish']);
}
}

0 comments on commit a4f5190

Please sign in to comment.