[Console] implemented helpers and moved formatter and ask* methods to their own helpers
This commit is contained in:
parent
7074036924
commit
e7dfdab05f
|
@ -7,8 +7,10 @@ use Symfony\Components\Console\Input\InputOption;
|
|||
use Symfony\Components\Console\Input\InputArgument;
|
||||
use Symfony\Components\Console\Input\InputInterface;
|
||||
use Symfony\Components\Console\Output\OutputInterface;
|
||||
use Symfony\Components\Console\Output\Formatter;
|
||||
use Symfony\Components\Console\Application;
|
||||
use Symfony\Components\Console\Helper\HelperSet;
|
||||
use Symfony\Components\Console\Helper\FormatterHelper;
|
||||
use Symfony\Components\Console\Helper\InteractHelper;
|
||||
|
||||
/*
|
||||
* This file is part of the symfony framework.
|
||||
|
@ -42,15 +44,27 @@ class Command
|
|||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $name
|
||||
* @param HelperSet $helperSet A helper set instance
|
||||
*/
|
||||
public function __construct($name = null)
|
||||
public function __construct($name = null, HelperSet $helperSet = null)
|
||||
{
|
||||
$this->definition = new InputDefinition();
|
||||
$this->ignoreValidationErrors = false;
|
||||
$this->applicationDefinitionMerged = false;
|
||||
$this->formatter = new Formatter();
|
||||
$this->aliases = array();
|
||||
|
||||
if (null === $helperSet)
|
||||
{
|
||||
$helperSet = new HelperSet(array(
|
||||
new FormatterHelper(),
|
||||
new InteractHelper(),
|
||||
));
|
||||
}
|
||||
|
||||
$this->setHelperSet($helperSet);
|
||||
|
||||
if (null !== $name)
|
||||
{
|
||||
$this->setName($name);
|
||||
|
@ -389,90 +403,39 @@ class Command
|
|||
}
|
||||
|
||||
/**
|
||||
* Asks a question to the user.
|
||||
* Set a helper set to be used with the command.
|
||||
*
|
||||
* @param OutputInterface $output
|
||||
* @param string|array $question The question to ask
|
||||
* @param string $default The default answer if none is given by the user
|
||||
*
|
||||
* @param string The user answer
|
||||
* @param HelperSet $helperSet The helper set
|
||||
*/
|
||||
static public function ask(OutputInterface $output, $question, $default = null)
|
||||
public function setHelperSet(HelperSet $helperSet)
|
||||
{
|
||||
// @codeCoverageIgnoreStart
|
||||
$output->write($question);
|
||||
$this->helperSet = $helperSet;
|
||||
|
||||
$ret = trim(fgets(STDIN));
|
||||
|
||||
return $ret ? $ret : $default;
|
||||
// @codeCoverageIgnoreEnd
|
||||
$helperSet->setCommand($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asks a confirmation to the user.
|
||||
* Get the helper set associated with the command
|
||||
*
|
||||
* The question will be asked until the user answer by nothing, yes, or no.
|
||||
*
|
||||
* @param OutputInterface $output
|
||||
* @param string|array $question The question to ask
|
||||
* @param Boolean $default The default answer if the user enters nothing
|
||||
*
|
||||
* @param Boolean true if the user has confirmed, false otherwise
|
||||
* @return HelperSet
|
||||
*/
|
||||
static public function askConfirmation(OutputInterface $output, $question, $default = true)
|
||||
public function getHelperSet()
|
||||
{
|
||||
// @codeCoverageIgnoreStart
|
||||
$answer = 'z';
|
||||
while ($answer && !in_array(strtolower($answer[0]), array('y', 'n')))
|
||||
{
|
||||
$answer = static::ask($output, $question);
|
||||
}
|
||||
|
||||
if (false === $default)
|
||||
{
|
||||
return $answer && 'y' == strtolower($answer[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
return !$answer || 'y' == strtolower($answer[0]);
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
return $this->helperSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Asks for a value and validates the response.
|
||||
* Gets a helper value.
|
||||
*
|
||||
* @param OutputInterface $output
|
||||
* @param string|array $question
|
||||
* @param Closure $validator
|
||||
* @param integer $attempts Max number of times to ask before giving up (false by default, which means infinite)
|
||||
* @param string $name The helper name
|
||||
*
|
||||
* @return mixed
|
||||
* @return mixed The helper value
|
||||
*
|
||||
* @throws \InvalidArgumentException if the helper is not defined
|
||||
*/
|
||||
static public function askAndValidate(OutputInterface $output, $question, \Closure $validator, $attempts = false)
|
||||
public function __get($name)
|
||||
{
|
||||
// @codeCoverageIgnoreStart
|
||||
$error = null;
|
||||
while (false === $attempts || $attempts--)
|
||||
{
|
||||
if (null !== $error)
|
||||
{
|
||||
$output->write($this->formatter->formatBlock($error->getMessage(), 'error'));
|
||||
}
|
||||
|
||||
$value = static::ask($output, $question, null);
|
||||
|
||||
try
|
||||
{
|
||||
return $validator($value);
|
||||
}
|
||||
catch (\Exception $error)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
throw $error;
|
||||
// @codeCoverageIgnoreEnd
|
||||
return $this->helperSet->get($name);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
|
||||
namespace Symfony\Components\Console\Output;
|
||||
namespace Symfony\Components\Console\Helper;
|
||||
|
||||
/*
|
||||
* This file is part of the symfony framework.
|
||||
|
@ -18,8 +18,16 @@ namespace Symfony\Components\Console\Output;
|
|||
* @subpackage cli
|
||||
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*/
|
||||
class Formatter
|
||||
class FormatterHelper extends Helper
|
||||
{
|
||||
/**
|
||||
* Returns the helper's canonical name
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'formatter';
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats a message within a section.
|
||||
*
|
||||
|
@ -27,7 +35,7 @@ class Formatter
|
|||
* @param string $message The message
|
||||
* @param string $style The style to apply to the section
|
||||
*/
|
||||
static public function formatSection($section, $message, $style = 'info')
|
||||
public function formatSection($section, $message, $style = 'info')
|
||||
{
|
||||
return sprintf("<%s>[%s]</%s> %s", $style, $section, $style, $message);
|
||||
}
|
||||
|
@ -41,7 +49,7 @@ class Formatter
|
|||
*
|
||||
* @return string The formatter message
|
||||
*/
|
||||
static public function formatBlock($messages, $style, $large = false)
|
||||
public function formatBlock($messages, $style, $large = false)
|
||||
{
|
||||
if (!is_array($messages))
|
||||
{
|
||||
|
@ -53,13 +61,13 @@ class Formatter
|
|||
foreach ($messages as $message)
|
||||
{
|
||||
$lines[] = sprintf($large ? ' %s ' : ' %s ', $message);
|
||||
$len = max(static::strlen($message) + ($large ? 4 : 2), $len);
|
||||
$len = max($this->strlen($message) + ($large ? 4 : 2), $len);
|
||||
}
|
||||
|
||||
$messages = $large ? array(str_repeat(' ', $len)) : array();
|
||||
foreach ($lines as $line)
|
||||
{
|
||||
$messages[] = $line.str_repeat(' ', $len - static::strlen($line));
|
||||
$messages[] = $line.str_repeat(' ', $len - $this->strlen($line));
|
||||
}
|
||||
if ($large)
|
||||
{
|
||||
|
@ -74,8 +82,9 @@ class Formatter
|
|||
return implode("\n", $messages);
|
||||
}
|
||||
|
||||
static protected function strlen($string)
|
||||
protected function strlen($string)
|
||||
{
|
||||
return function_exists('mb_strlen') ? mb_strlen($string) : strlen($string);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
<?php
|
||||
|
||||
namespace Symfony\Components\Console\Helper;
|
||||
|
||||
/*
|
||||
* This file is part of the symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Helper is the base class for all helper classes.
|
||||
*
|
||||
* @package symfony
|
||||
* @subpackage templating
|
||||
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*/
|
||||
abstract class Helper implements HelperInterface
|
||||
{
|
||||
protected
|
||||
$helperSet = null;
|
||||
|
||||
/**
|
||||
* Sets the helper set associated with this helper.
|
||||
*
|
||||
* @param HelperSet $helperSet A HelperSet instance
|
||||
*/
|
||||
public function setHelperSet(HelperSet $helperSet = null)
|
||||
{
|
||||
$this->helperSet = $helperSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the helper set associated with this helper.
|
||||
*
|
||||
* @return HelperSet A HelperSet instance
|
||||
*/
|
||||
public function getHelperSet()
|
||||
{
|
||||
return $this->helperSet;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
<?php
|
||||
|
||||
namespace Symfony\Components\Console\Helper;
|
||||
|
||||
/*
|
||||
* This file is part of the symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* HelperInterface is the interface all helpers must implement.
|
||||
*
|
||||
* @package symfony
|
||||
* @subpackage templating
|
||||
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*/
|
||||
interface HelperInterface
|
||||
{
|
||||
/**
|
||||
* Returns the canonical name of this helper.
|
||||
*
|
||||
* @return string The canonical name
|
||||
*/
|
||||
function getName();
|
||||
|
||||
/**
|
||||
* Sets the helper set associated with this helper.
|
||||
*
|
||||
* @param HelperSet $helperSet A HelperSet instance
|
||||
*/
|
||||
function setHelperSet(HelperSet $helperSet = null);
|
||||
|
||||
/**
|
||||
* Gets the helper set associated with this helper.
|
||||
*
|
||||
* @return HelperSet A HelperSet instance
|
||||
*/
|
||||
function getHelperSet();
|
||||
}
|
|
@ -0,0 +1,105 @@
|
|||
<?php
|
||||
|
||||
namespace Symfony\Components\Console\Helper;
|
||||
|
||||
use Symfony\Components\Console\Command\Command;
|
||||
|
||||
/*
|
||||
* This file is part of the symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* HelperSet represents a set of helpers to be used with a command.
|
||||
*
|
||||
* @package symfony
|
||||
* @subpackage templating
|
||||
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*/
|
||||
class HelperSet
|
||||
{
|
||||
protected
|
||||
$helpers = array(),
|
||||
$command = null;
|
||||
|
||||
public function __construct(array $helpers = array())
|
||||
{
|
||||
foreach ($helpers as $alias => $helper)
|
||||
{
|
||||
$this->set($helper, is_int($alias) ? null : $alias);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a helper.
|
||||
*
|
||||
* @param HelperInterface $value The helper instance
|
||||
* @param string $alias An alias
|
||||
*/
|
||||
public function set(HelperInterface $helper, $alias = null)
|
||||
{
|
||||
$this->helpers[$helper->getName()] = $helper;
|
||||
if (null !== $alias)
|
||||
{
|
||||
$this->helpers[$alias] = $helper;
|
||||
}
|
||||
|
||||
$helper->setHelperSet($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the helper if defined.
|
||||
*
|
||||
* @param string $name The helper name
|
||||
*
|
||||
* @return Boolean true if the helper is defined, false otherwise
|
||||
*/
|
||||
public function has($name)
|
||||
{
|
||||
return isset($this->helpers[$name]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a helper value.
|
||||
*
|
||||
* @param string $name The helper name
|
||||
*
|
||||
* @return HelperInterface The helper instance
|
||||
*
|
||||
* @throws \InvalidArgumentException if the helper is not defined
|
||||
*/
|
||||
public function get($name)
|
||||
{
|
||||
if (!$this->has($name))
|
||||
{
|
||||
throw new \InvalidArgumentException(sprintf('The helper "%s" is not defined.', $name));
|
||||
}
|
||||
|
||||
return $this->helpers[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the command associated with this helper set.
|
||||
*
|
||||
* @param Command $command A Command instance
|
||||
*/
|
||||
public function setCommand(Command $command = null)
|
||||
{
|
||||
$this->command = $command;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the command associated with this helper set.
|
||||
*
|
||||
* @return Command A Command instance
|
||||
*/
|
||||
public function getCommand()
|
||||
{
|
||||
return $this->command;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,119 @@
|
|||
<?php
|
||||
|
||||
namespace Symfony\Components\Console\Helper;
|
||||
|
||||
use Symfony\Components\Console\Output\OutputInterface;
|
||||
|
||||
/*
|
||||
* This file is part of the symfony framework.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* The Interact class provides helpers to interact with the user.
|
||||
*
|
||||
* @package symfony
|
||||
* @subpackage cli
|
||||
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*/
|
||||
class InteractHelper extends Helper
|
||||
{
|
||||
/**
|
||||
* Returns the helper's canonical name
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'interact';
|
||||
}
|
||||
|
||||
/**
|
||||
* Asks a question to the user.
|
||||
*
|
||||
* @param OutputInterface $output
|
||||
* @param string|array $question The question to ask
|
||||
* @param string $default The default answer if none is given by the user
|
||||
*
|
||||
* @param string The user answer
|
||||
*/
|
||||
public function ask(OutputInterface $output, $question, $default = null)
|
||||
{
|
||||
// @codeCoverageIgnoreStart
|
||||
$output->write($question);
|
||||
|
||||
$ret = trim(fgets(STDIN));
|
||||
|
||||
return $ret ? $ret : $default;
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
|
||||
/**
|
||||
* Asks a confirmation to the user.
|
||||
*
|
||||
* The question will be asked until the user answer by nothing, yes, or no.
|
||||
*
|
||||
* @param OutputInterface $output
|
||||
* @param string|array $question The question to ask
|
||||
* @param Boolean $default The default answer if the user enters nothing
|
||||
*
|
||||
* @param Boolean true if the user has confirmed, false otherwise
|
||||
*/
|
||||
public function askConfirmation(OutputInterface $output, $question, $default = true)
|
||||
{
|
||||
// @codeCoverageIgnoreStart
|
||||
$answer = 'z';
|
||||
while ($answer && !in_array(strtolower($answer[0]), array('y', 'n')))
|
||||
{
|
||||
$answer = $this->ask($output, $question);
|
||||
}
|
||||
|
||||
if (false === $default)
|
||||
{
|
||||
return $answer && 'y' == strtolower($answer[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
return !$answer || 'y' == strtolower($answer[0]);
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
|
||||
/**
|
||||
* Asks for a value and validates the response.
|
||||
*
|
||||
* @param OutputInterface $output
|
||||
* @param string|array $question
|
||||
* @param Closure $validator
|
||||
* @param integer $attempts Max number of times to ask before giving up (false by default, which means infinite)
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function askAndValidate(OutputInterface $output, $question, \Closure $validator, $attempts = false)
|
||||
{
|
||||
// @codeCoverageIgnoreStart
|
||||
$error = null;
|
||||
while (false === $attempts || $attempts--)
|
||||
{
|
||||
if (null !== $error)
|
||||
{
|
||||
$output->write($this->getHelperSet()->get('formatter')->formatBlock($error->getMessage(), 'error'));
|
||||
}
|
||||
|
||||
$value = $this->ask($output, $question, null);
|
||||
|
||||
try
|
||||
{
|
||||
return $validator($value);
|
||||
}
|
||||
catch (\Exception $error)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
throw $error;
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the symfony package.
|
||||
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
require_once __DIR__.'/../../../../bootstrap.php';
|
||||
|
||||
use Symfony\Components\Console\Helper\FormatterHelper;
|
||||
|
||||
$formatter = new FormatterHelper();
|
||||
|
||||
$t = new LimeTest(4);
|
||||
|
||||
// ::formatSection()
|
||||
$t->diag('::formatSection()');
|
||||
$t->is($formatter->formatSection('cli', 'Some text to display'), '<info>[cli]</info> Some text to display', '::formatSection() formats a message in a section');
|
||||
|
||||
// ::formatBlock()
|
||||
$t->diag('::formatBlock()');
|
||||
$t->is($formatter->formatBlock('Some text to display', 'error'), '<error> Some text to display </error>', '::formatBlock() formats a message in a block');
|
||||
$t->is($formatter->formatBlock(array('Some text to display', 'foo bar'), 'error'), "<error> Some text to display </error>\n<error> foo bar </error>", '::formatBlock() formats a message in a block');
|
||||
|
||||
$t->is($formatter->formatBlock('Some text to display', 'error', true), "<error> </error>\n<error> Some text to display </error>\n<error> </error>", '::formatBlock() formats a message in a block');
|
|
@ -1,26 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the symfony package.
|
||||
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
require_once __DIR__.'/../../../../bootstrap.php';
|
||||
|
||||
use Symfony\Components\Console\Output\Formatter;
|
||||
|
||||
$t = new LimeTest(4);
|
||||
|
||||
// ::formatSection()
|
||||
$t->diag('::formatSection()');
|
||||
$t->is(Formatter::formatSection('cli', 'Some text to display'), '<info>[cli]</info> Some text to display', '::formatSection() formats a message in a section');
|
||||
|
||||
// ::formatBlock()
|
||||
$t->diag('::formatBlock()');
|
||||
$t->is(Formatter::formatBlock('Some text to display', 'error'), '<error> Some text to display </error>', '::formatBlock() formats a message in a block');
|
||||
$t->is(Formatter::formatBlock(array('Some text to display', 'foo bar'), 'error'), "<error> Some text to display </error>\n<error> foo bar </error>", '::formatBlock() formats a message in a block');
|
||||
|
||||
$t->is(Formatter::formatBlock('Some text to display', 'error', true), "<error> </error>\n<error> Some text to display </error>\n<error> </error>", '::formatBlock() formats a message in a block');
|
Reference in New Issue