Commit 8cbebc3a authored by Benjamin Eberlei's avatar Benjamin Eberlei

DBAL-16 - Update Symfony\Component\Console to fix upstream bug

parent fd2e8fa0
......@@ -10,7 +10,7 @@ use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Application;
/*
* This file is part of the symfony framework.
* This file is part of the Symfony framework.
*
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
*
......@@ -21,8 +21,6 @@ use Symfony\Component\Console\Application;
/**
* Base class for all commands.
*
* @package symfony
* @subpackage console
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
*/
class Command
......@@ -35,7 +33,6 @@ class Command
protected $application;
protected $description;
protected $ignoreValidationErrors;
protected $formatter;
protected $applicationDefinitionMerged;
protected $code;
......@@ -43,6 +40,8 @@ class Command
* Constructor.
*
* @param string $name The name of the command
*
* @throws \LogicException When the command name is empty
*/
public function __construct($name = null)
{
......@@ -51,15 +50,13 @@ class Command
$this->applicationDefinitionMerged = false;
$this->aliases = array();
if (null !== $name)
{
if (null !== $name) {
$this->setName($name);
}
$this->configure();
if (!$this->name)
{
if (!$this->name) {
throw new \LogicException('The command name cannot be empty.');
}
}
......@@ -88,6 +85,8 @@ class Command
* @param OutputInterface $output An OutputInterface instance
*
* @return integer 0 if everything went fine, or an error code
*
* @throws \LogicException When this abstract class is not implemented
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
......@@ -129,33 +128,25 @@ class Command
$this->mergeApplicationDefinition();
// bind the input against the command specific arguments/options
try
{
try {
$input->bind($this->definition);
}
catch (\Exception $e)
{
if (!$this->ignoreValidationErrors)
{
} catch (\Exception $e) {
if (!$this->ignoreValidationErrors) {
throw $e;
}
}
$this->initialize($input, $output);
if ($input->isInteractive())
{
if ($input->isInteractive()) {
$this->interact($input, $output);
}
$input->validate();
if ($this->code)
{
if ($this->code) {
return call_user_func($this->code, $input, $output);
}
else
{
} else {
return $this->execute($input, $output);
}
}
......@@ -179,8 +170,7 @@ class Command
*/
protected function mergeApplicationDefinition()
{
if (null === $this->application || true === $this->applicationDefinitionMerged)
{
if (null === $this->application || true === $this->applicationDefinitionMerged) {
return;
}
......@@ -203,12 +193,9 @@ class Command
*/
public function setDefinition($definition)
{
if ($definition instanceof InputDefinition)
{
if ($definition instanceof InputDefinition) {
$this->definition = $definition;
}
else
{
} else {
$this->definition->setDefinition($definition);
}
......@@ -220,7 +207,7 @@ class Command
/**
* Gets the InputDefinition attached to this Command.
*
* @return InputDefinition $definition An InputDefinition instance
* @return InputDefinition An InputDefinition instance
*/
public function getDefinition()
{
......@@ -273,22 +260,20 @@ class Command
* @param string $name The command name
*
* @return Command The current instance
*
* @throws \InvalidArgumentException When command name given is empty
*/
public function setName($name)
{
if (false !== $pos = strrpos($name, ':'))
{
if (false !== $pos = strrpos($name, ':')) {
$namespace = substr($name, 0, $pos);
$name = substr($name, $pos + 1);
}
else
{
} else {
$namespace = $this->namespace;
}
if (!$name)
{
throw new \InvalidArgumentException('A command name cannot be empty');
if (!$name) {
throw new \InvalidArgumentException('A command name cannot be empty.');
}
$this->namespace = $namespace;
......@@ -472,15 +457,13 @@ class Command
'',
);
if ($this->getAliases())
{
if ($this->getAliases()) {
$messages[] = '<comment>Aliases:</comment> <info>'.implode(', ', $this->getAliases()).'</info>';
}
$messages[] = $this->definition->asText();
if ($help = $this->getProcessedHelp())
{
if ($help = $this->getProcessedHelp()) {
$messages[] = '<comment>Help:</comment>';
$messages[] = ' '.implode("\n ", explode("\n", $help))."\n";
}
......@@ -515,8 +498,7 @@ class Command
$helpXML->appendChild($dom->createTextNode(implode("\n ", explode("\n", $help))));
$commandXML->appendChild($aliasesXML = $dom->createElement('aliases'));
foreach ($this->getAliases() as $alias)
{
foreach ($this->getAliases() as $alias) {
$aliasesXML->appendChild($aliasXML = $dom->createElement('alias'));
$aliasXML->appendChild($dom->createTextNode($alias));
}
......
......@@ -10,7 +10,7 @@ use Symfony\Component\Console\Output\Output;
use Symfony\Component\Console\Command\Command;
/*
* This file is part of the symfony framework.
* This file is part of the Symfony framework.
*
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
*
......@@ -21,8 +21,6 @@ use Symfony\Component\Console\Command\Command;
/**
* HelpCommand displays the help for a given command.
*
* @package symfony
* @subpackage console
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
*/
class HelpCommand extends Command
......@@ -47,11 +45,11 @@ class HelpCommand extends Command
->setHelp(<<<EOF
The <info>help</info> command displays help for a given command:
<info>./symfony help test:all</info>
<info>./symfony help list</info>
You can also output the help as XML by using the <comment>--xml</comment> option:
<info>./symfony help --xml test:all</info>
<info>./symfony help --xml list</info>
EOF
);
}
......@@ -66,17 +64,13 @@ EOF
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
if (null === $this->command)
{
if (null === $this->command) {
$this->command = $this->application->getCommand($input->getArgument('command_name'));
}
if ($input->getOption('xml'))
{
if ($input->getOption('xml')) {
$output->writeln($this->command->asXml(), Output::OUTPUT_RAW);
}
else
{
} else {
$output->writeln($this->command->asText());
}
}
......
......@@ -10,7 +10,7 @@ use Symfony\Component\Console\Output\Output;
use Symfony\Component\Console\Command\Command;
/*
* This file is part of the symfony framework.
* This file is part of the Symfony framework.
*
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
*
......@@ -21,8 +21,6 @@ use Symfony\Component\Console\Command\Command;
/**
* ListCommand displays the list of all available commands for the application.
*
* @package symfony
* @subpackage console
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
*/
class ListCommand extends Command
......@@ -60,12 +58,9 @@ EOF
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
if ($input->getOption('xml'))
{
if ($input->getOption('xml')) {
$output->writeln($this->application->asXml($input->getArgument('namespace')), Output::OUTPUT_RAW);
}
else
{
} else {
$output->writeln($this->application->asText($input->getArgument('namespace')));
}
}
......
......@@ -5,7 +5,7 @@ namespace Symfony\Component\Console\Helper;
use Symfony\Component\Console\Output\OutputInterface;
/*
* This file is part of the symfony framework.
* This file is part of the Symfony framework.
*
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
*
......@@ -16,8 +16,6 @@ use Symfony\Component\Console\Output\OutputInterface;
/**
* The Dialog class provides helpers to interact with the user.
*
* @package symfony
* @subpackage console
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
*/
class DialogHelper extends Helper
......@@ -29,7 +27,7 @@ class DialogHelper extends Helper
* @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
* @return string The user answer
*/
public function ask(OutputInterface $output, $question, $default = null)
{
......@@ -51,23 +49,19 @@ class DialogHelper extends Helper
* @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 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')))
{
while ($answer && !in_array(strtolower($answer[0]), array('y', 'n'))) {
$answer = $this->ask($output, $question);
}
if (false === $default)
{
if (false === $default) {
return $answer && 'y' == strtolower($answer[0]);
}
else
{
} else {
return !$answer || 'y' == strtolower($answer[0]);
}
// @codeCoverageIgnoreEnd
......@@ -82,26 +76,23 @@ class DialogHelper extends Helper
* @param integer $attempts Max number of times to ask before giving up (false by default, which means infinite)
*
* @return mixed
*
* @throws \Exception When any of the validator returns an error
*/
public function askAndValidate(OutputInterface $output, $question, \Closure $validator, $attempts = false)
{
// @codeCoverageIgnoreStart
$error = null;
while (false === $attempts || $attempts--)
{
if (null !== $error)
{
while (false === $attempts || $attempts--) {
if (null !== $error) {
$output->writeln($this->getHelperSet()->get('formatter')->formatBlock($error->getMessage(), 'error'));
}
$value = $this->ask($output, $question, null);
try
{
try {
return $validator($value);
}
catch (\Exception $error)
{
} catch (\Exception $error) {
}
}
......
......@@ -3,7 +3,7 @@
namespace Symfony\Component\Console\Helper;
/*
* This file is part of the symfony framework.
* This file is part of the Symfony framework.
*
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
*
......@@ -14,8 +14,6 @@ namespace Symfony\Component\Console\Helper;
/**
* The Formatter class provides helpers to format messages.
*
* @package symfony
* @subpackage console
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
*/
class FormatterHelper extends Helper
......@@ -29,7 +27,7 @@ class FormatterHelper extends Helper
*/
public function formatSection($section, $message, $style = 'info')
{
return sprintf("<%s>[%s]</%s> %s", $style, $section, $style, $message);
return sprintf('<%s>[%s]</%s> %s', $style, $section, $style, $message);
}
/**
......@@ -43,31 +41,26 @@ class FormatterHelper extends Helper
*/
public function formatBlock($messages, $style, $large = false)
{
if (!is_array($messages))
{
if (!is_array($messages)) {
$messages = array($messages);
}
$len = 0;
$lines = array();
foreach ($messages as $message)
{
foreach ($messages as $message) {
$lines[] = sprintf($large ? ' %s ' : ' %s ', $message);
$len = max($this->strlen($message) + ($large ? 4 : 2), $len);
}
$messages = $large ? array(str_repeat(' ', $len)) : array();
foreach ($lines as $line)
{
foreach ($lines as $line) {
$messages[] = $line.str_repeat(' ', $len - $this->strlen($line));
}
if ($large)
{
if ($large) {
$messages[] = str_repeat(' ', $len);
}
foreach ($messages as &$message)
{
foreach ($messages as &$message) {
$message = sprintf('<%s>%s</%s>', $style, $message, $style);
}
......
......@@ -3,7 +3,7 @@
namespace Symfony\Component\Console\Helper;
/*
* This file is part of the symfony framework.
* This file is part of the Symfony framework.
*
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
*
......@@ -14,14 +14,11 @@ namespace Symfony\Component\Console\Helper;
/**
* Helper is the base class for all helper classes.
*
* @package symfony
* @subpackage console
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
*/
abstract class Helper implements HelperInterface
{
protected
$helperSet = null;
protected $helperSet = null;
/**
* Sets the helper set associated with this helper.
......
......@@ -3,7 +3,7 @@
namespace Symfony\Component\Console\Helper;
/*
* This file is part of the symfony framework.
* This file is part of the Symfony framework.
*
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
*
......@@ -14,8 +14,6 @@ namespace Symfony\Component\Console\Helper;
/**
* HelperInterface is the interface all helpers must implement.
*
* @package symfony
* @subpackage console
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
*/
interface HelperInterface
......
......@@ -5,7 +5,7 @@ namespace Symfony\Component\Console\Helper;
use Symfony\Component\Console\Command\Command;
/*
* This file is part of the symfony framework.
* This file is part of the Symfony framework.
*
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
*
......@@ -16,20 +16,20 @@ use Symfony\Component\Console\Command\Command;
/**
* HelperSet represents a set of helpers to be used with a command.
*
* @package symfony
* @subpackage console
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
*/
class HelperSet
{
protected
$helpers = array(),
$command = null;
protected $helpers;
protected $command;
/**
* @param Helper[] $helpers An array of helper.
*/
public function __construct(array $helpers = array())
{
foreach ($helpers as $alias => $helper)
{
$this->helpers = array();
foreach ($helpers as $alias => $helper) {
$this->set($helper, is_int($alias) ? null : $alias);
}
}
......@@ -43,8 +43,7 @@ class HelperSet
public function set(HelperInterface $helper, $alias = null)
{
$this->helpers[$helper->getName()] = $helper;
if (null !== $alias)
{
if (null !== $alias) {
$this->helpers[$alias] = $helper;
}
......@@ -74,8 +73,7 @@ class HelperSet
*/
public function get($name)
{
if (!$this->has($name))
{
if (!$this->has($name)) {
throw new \InvalidArgumentException(sprintf('The helper "%s" is not defined.', $name));
}
......
......@@ -3,7 +3,7 @@
namespace Symfony\Component\Console\Input;
/*
* This file is part of the symfony framework.
* This file is part of the Symfony framework.
*
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
*
......@@ -20,7 +20,7 @@ namespace Symfony\Component\Console\Input;
*
* By default, the `$_SERVER['argv']` array is used for the input values.
*
* This can be overriden by explicitly passing the input values in the constructor:
* This can be overridden by explicitly passing the input values in the constructor:
*
* $input = new ArgvInput($_SERVER['argv']);
*
......@@ -31,8 +31,6 @@ namespace Symfony\Component\Console\Input;
* the same rules as the argv one. It's almost always better to use the
* `StringInput` when you want to provide your own input.
*
* @package symfony
* @subpackage console
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
*
* @see http://www.gnu.org/software/libc/manual/html_node/Argument-Syntax.html
......@@ -51,8 +49,7 @@ class ArgvInput extends Input
*/
public function __construct(array $argv = null, InputDefinition $definition = null)
{
if (null === $argv)
{
if (null === $argv) {
$argv = $_SERVER['argv'];
}
......@@ -70,18 +67,12 @@ class ArgvInput extends Input
protected function parse()
{
$this->parsed = $this->tokens;
while (null !== ($token = array_shift($this->parsed)))
{
if ('--' === substr($token, 0, 2))
{
while (null !== $token = array_shift($this->parsed)) {
if ('--' === substr($token, 0, 2)) {
$this->parseLongOption($token);
}
elseif ('-' === $token[0])
{
} elseif ('-' === $token[0]) {
$this->parseShortOption($token);
}
else
{
} else {
$this->parseArgument($token);
}
}
......@@ -96,20 +87,14 @@ class ArgvInput extends Input
{
$name = substr($token, 1);
if (strlen($name) > 1)
{
if ($this->definition->hasShortcut($name[0]) && $this->definition->getOptionForShortcut($name[0])->acceptParameter())
{
if (strlen($name) > 1) {
if ($this->definition->hasShortcut($name[0]) && $this->definition->getOptionForShortcut($name[0])->acceptParameter()) {
// an option with a value (with no space)
$this->addShortOption($name[0], substr($name, 1));
}
else
{
} else {
$this->parseShortOptionSet($name);
}
}
else
{
} else {
$this->addShortOption($name, null);
}
}
......@@ -118,26 +103,23 @@ class ArgvInput extends Input
* Parses a short option set.
*
* @param string $token The current token
*
* @throws \RuntimeException When option given doesn't exist
*/
protected function parseShortOptionSet($name)
{
$len = strlen($name);
for ($i = 0; $i < $len; $i++)
{
if (!$this->definition->hasShortcut($name[$i]))
{
for ($i = 0; $i < $len; $i++) {
if (!$this->definition->hasShortcut($name[$i])) {
throw new \RuntimeException(sprintf('The "-%s" option does not exist.', $name[$i]));
}
$option = $this->definition->getOptionForShortcut($name[$i]);
if ($option->acceptParameter())
{
if ($option->acceptParameter()) {
$this->addLongOption($option->getName(), $i === $len - 1 ? null : substr($name, $i + 1));
break;
}
else
{
} else {
$this->addLongOption($option->getName(), true);
}
}
......@@ -152,12 +134,9 @@ class ArgvInput extends Input
{
$name = substr($token, 2);
if (false !== $pos = strpos($name, '='))
{
if (false !== $pos = strpos($name, '=')) {
$this->addLongOption(substr($name, 0, $pos), substr($name, $pos + 1));
}
else
{
} else {
$this->addLongOption($name, null);
}
}
......@@ -166,11 +145,12 @@ class ArgvInput extends Input
* Parses an argument.
*
* @param string $token The current token
*
* @throws \RuntimeException When too many arguments are given
*/
protected function parseArgument($token)
{
if (!$this->definition->hasArgument(count($this->arguments)))
{
if (!$this->definition->hasArgument(count($this->arguments))) {
throw new \RuntimeException('Too many arguments.');
}
......@@ -182,11 +162,12 @@ class ArgvInput extends Input
*
* @param string $shortcut The short option key
* @param mixed $value The value for the option
*
* @throws \RuntimeException When option given doesn't exist
*/
protected function addShortOption($shortcut, $value)
{
if (!$this->definition->hasShortcut($shortcut))
{
if (!$this->definition->hasShortcut($shortcut)) {
throw new \RuntimeException(sprintf('The "-%s" option does not exist.', $shortcut));
}
......@@ -198,35 +179,30 @@ class ArgvInput extends Input
*
* @param string $name The long option key
* @param mixed $value The value for the option
*
* @throws \RuntimeException When option given doesn't exist
*/
protected function addLongOption($name, $value)
{
if (!$this->definition->hasOption($name))
{
if (!$this->definition->hasOption($name)) {
throw new \RuntimeException(sprintf('The "--%s" option does not exist.', $name));
}
$option = $this->definition->getOption($name);
if (null === $value && $option->acceptParameter())
{
if (null === $value && $option->acceptParameter()) {
// if option accepts an optional or mandatory argument
// let's see if there is one provided
$next = array_shift($this->parsed);
if ('-' !== $next[0])
{
if ('-' !== $next[0]) {
$value = $next;
}
else
{
} else {
array_unshift($this->parsed, $next);
}
}
if (null === $value)
{
if ($option->isParameterRequired())
{
if (null === $value) {
if ($option->isParameterRequired()) {
throw new \RuntimeException(sprintf('The "--%s" option requires a value.', $name));
}
......@@ -243,10 +219,8 @@ class ArgvInput extends Input
*/
public function getFirstArgument()
{
foreach ($this->tokens as $token)
{
if ($token && '-' === $token[0])
{
foreach ($this->tokens as $token) {
if ($token && '-' === $token[0]) {
continue;
}
......@@ -266,15 +240,12 @@ class ArgvInput extends Input
*/
public function hasParameterOption($values)
{
if (!is_array($values))
{
if (!is_array($values)) {
$values = array($values);
}
foreach ($this->tokens as $v)
{
if (in_array($v, $values))
{
foreach ($this->tokens as $v) {
if (in_array($v, $values)) {
return true;
}
}
......
......@@ -3,7 +3,7 @@
namespace Symfony\Component\Console\Input;
/*
* This file is part of the symfony framework.
* This file is part of the Symfony framework.
*
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
*
......@@ -18,8 +18,6 @@ namespace Symfony\Component\Console\Input;
*
* $input = new ArrayInput(array('name' => 'foo', '--bar' => 'foobar'));
*
* @package symfony
* @subpackage console
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
*/
class ArrayInput extends Input
......@@ -46,10 +44,8 @@ class ArrayInput extends Input
*/
public function getFirstArgument()
{
foreach ($this->parameters as $key => $value)
{
if ($key && '-' === $key[0])
{
foreach ($this->parameters as $key => $value) {
if ($key && '-' === $key[0]) {
continue;
}
......@@ -69,20 +65,16 @@ class ArrayInput extends Input
*/
public function hasParameterOption($values)
{
if (!is_array($values))
{
if (!is_array($values)) {
$values = array($values);
}
foreach ($this->parameters as $k => $v)
{
if (!is_int($k))
{
foreach ($this->parameters as $k => $v) {
if (!is_int($k)) {
$v = $k;
}
if (in_array($v, $values))
{
if (in_array($v, $values)) {
return true;
}
}
......@@ -95,18 +87,12 @@ class ArrayInput extends Input
*/
protected function parse()
{
foreach ($this->parameters as $key => $value)
{
if ('--' === substr($key, 0, 2))
{
foreach ($this->parameters as $key => $value) {
if ('--' === substr($key, 0, 2)) {
$this->addLongOption(substr($key, 2), $value);
}
elseif ('-' === $key[0])
{
} elseif ('-' === $key[0]) {
$this->addShortOption(substr($key, 1), $value);
}
else
{
} else {
$this->addArgument($key, $value);
}
}
......@@ -117,12 +103,13 @@ class ArrayInput extends Input
*
* @param string $shortcut The short option key
* @param mixed $value The value for the option
*
* @throws \RuntimeException When option given doesn't exist
*/
protected function addShortOption($shortcut, $value)
{
if (!$this->definition->hasShortcut($shortcut))
{
throw new \RuntimeException(sprintf('The "-%s" option does not exist.', $shortcut));
if (!$this->definition->hasShortcut($shortcut)) {
throw new \InvalidArgumentException(sprintf('The "-%s" option does not exist.', $shortcut));
}
$this->addLongOption($this->definition->getOptionForShortcut($shortcut)->getName(), $value);
......@@ -133,21 +120,21 @@ class ArrayInput extends Input
*
* @param string $name The long option key
* @param mixed $value The value for the option
*
* @throws \InvalidArgumentException When option given doesn't exist
* @throws \InvalidArgumentException When a required value is missing
*/
protected function addLongOption($name, $value)
{
if (!$this->definition->hasOption($name))
{
throw new \RuntimeException(sprintf('The "--%s" option does not exist.', $name));
if (!$this->definition->hasOption($name)) {
throw new \InvalidArgumentException(sprintf('The "--%s" option does not exist.', $name));
}
$option = $this->definition->getOption($name);
if (null === $value)
{
if ($option->isParameterRequired())
{
throw new \RuntimeException(sprintf('The "--%s" option requires a value.', $name));
if (null === $value) {
if ($option->isParameterRequired()) {
throw new \InvalidArgumentException(sprintf('The "--%s" option requires a value.', $name));
}
$value = $option->isParameterOptional() ? $option->getDefault() : true;
......@@ -161,12 +148,13 @@ class ArrayInput extends Input
*
* @param string $name The argument name
* @param mixed $value The value for the argument
*
* @throws \InvalidArgumentException When argument given doesn't exist
*/
protected function addArgument($name, $value)
{
if (!$this->definition->hasArgument($name))
{
throw new \RuntimeException(sprintf('The "%s" argument does not exist.', $name));
if (!$this->definition->hasArgument($name)) {
throw new \InvalidArgumentException(sprintf('The "%s" argument does not exist.', $name));
}
$this->arguments[$name] = $value;
......
......@@ -3,7 +3,7 @@
namespace Symfony\Component\Console\Input;
/*
* This file is part of the symfony framework.
* This file is part of the Symfony framework.
*
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
*
......@@ -20,8 +20,6 @@ namespace Symfony\Component\Console\Input;
* * `StringInput`: The input is provided as a string
* * `ArrayInput`: The input is provided as an array
*
* @package symfony
* @subpackage console
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
*/
abstract class Input implements InputInterface
......@@ -38,12 +36,9 @@ abstract class Input implements InputInterface
*/
public function __construct(InputDefinition $definition = null)
{
if (null === $definition)
{
if (null === $definition) {
$this->definition = new InputDefinition();
}
else
{
} else {
$this->bind($definition);
$this->validate();
}
......@@ -68,10 +63,12 @@ abstract class Input implements InputInterface
*/
abstract protected function parse();
/**
* @throws \RuntimeException When not enough arguments are given
*/
public function validate()
{
if (count($this->arguments) < $this->definition->getArgumentRequiredCount())
{
if (count($this->arguments) < $this->definition->getArgumentRequiredCount()) {
throw new \RuntimeException('Not enough arguments.');
}
}
......@@ -102,11 +99,12 @@ abstract class Input implements InputInterface
* @param string $name The argument name
*
* @return mixed The argument value
*
* @throws \InvalidArgumentException When argument given doesn't exist
*/
public function getArgument($name)
{
if (!$this->definition->hasArgument($name))
{
if (!$this->definition->hasArgument($name)) {
throw new \InvalidArgumentException(sprintf('The "%s" argument does not exist.', $name));
}
......@@ -118,11 +116,12 @@ abstract class Input implements InputInterface
*
* @param string $name The argument name
* @param string $value The argument value
*
* @throws \InvalidArgumentException When argument given doesn't exist
*/
public function setArgument($name, $value)
{
if (!$this->definition->hasArgument($name))
{
if (!$this->definition->hasArgument($name)) {
throw new \InvalidArgumentException(sprintf('The "%s" argument does not exist.', $name));
}
......@@ -157,11 +156,12 @@ abstract class Input implements InputInterface
* @param string $name The option name
*
* @return mixed The option value
*
* @throws \InvalidArgumentException When option given doesn't exist
*/
public function getOption($name)
{
if (!$this->definition->hasOption($name))
{
if (!$this->definition->hasOption($name)) {
throw new \InvalidArgumentException(sprintf('The "%s" option does not exist.', $name));
}
......@@ -173,11 +173,12 @@ abstract class Input implements InputInterface
*
* @param string $name The option name
* @param string $value The option value
*
* @throws \InvalidArgumentException When option given doesn't exist
*/
public function setOption($name, $value)
{
if (!$this->definition->hasOption($name))
{
if (!$this->definition->hasOption($name)) {
throw new \InvalidArgumentException(sprintf('The "%s" option does not exist.', $name));
}
......
......@@ -3,7 +3,7 @@
namespace Symfony\Component\Console\Input;
/*
* This file is part of the symfony framework.
* This file is part of the Symfony framework.
*
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
*
......@@ -14,8 +14,6 @@ namespace Symfony\Component\Console\Input;
/**
* Represents a command line argument.
*
* @package symfony
* @subpackage console
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
*/
class InputArgument
......@@ -36,15 +34,14 @@ class InputArgument
* @param integer $mode The argument mode: self::REQUIRED or self::OPTIONAL
* @param string $description A description text
* @param mixed $default The default value (for self::OPTIONAL mode only)
*
* @throws \InvalidArgumentException When argument mode is not valid
*/
public function __construct($name, $mode = null, $description = '', $default = null)
{
if (null === $mode)
{
if (null === $mode) {
$mode = self::OPTIONAL;
}
else if (is_string($mode) || $mode > 7)
{
} else if (is_string($mode) || $mode > 7) {
throw new \InvalidArgumentException(sprintf('Argument mode "%s" is not valid.', $mode));
}
......@@ -89,22 +86,19 @@ class InputArgument
* Sets the default value.
*
* @param mixed $default The default value
*
* @throws \LogicException When incorrect default value is given
*/
public function setDefault($default = null)
{
if (self::REQUIRED === $this->mode && null !== $default)
{
if (self::REQUIRED === $this->mode && null !== $default) {
throw new \LogicException('Cannot set a default value except for Parameter::OPTIONAL mode.');
}
if ($this->isArray())
{
if (null === $default)
{
if ($this->isArray()) {
if (null === $default) {
$default = array();
}
else if (!is_array($default))
{
} else if (!is_array($default)) {
throw new \LogicException('A default value for an array argument must be an array.');
}
}
......
......@@ -3,7 +3,7 @@
namespace Symfony\Component\Console\Input;
/*
* This file is part of the symfony framework.
* This file is part of the Symfony framework.
*
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
*
......@@ -14,8 +14,6 @@ namespace Symfony\Component\Console\Input;
/**
* InputInterface is the interface implemented by all input classes.
*
* @package symfony
* @subpackage console
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
*/
interface InputInterface
......
......@@ -3,7 +3,7 @@
namespace Symfony\Component\Console\Input;
/*
* This file is part of the symfony framework.
* This file is part of the Symfony framework.
*
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
*
......@@ -14,8 +14,6 @@ namespace Symfony\Component\Console\Input;
/**
* Represents a command line option.
*
* @package symfony
* @subpackage console
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
*/
class InputOption
......@@ -39,33 +37,28 @@ class InputOption
* @param integer $mode The option mode: self::PARAMETER_REQUIRED, self::PARAMETER_NONE or self::PARAMETER_OPTIONAL
* @param string $description A description text
* @param mixed $default The default value (must be null for self::PARAMETER_REQUIRED or self::PARAMETER_NONE)
*
* @throws \InvalidArgumentException If option mode is invalid or incompatible
*/
public function __construct($name, $shortcut = null, $mode = null, $description = '', $default = null)
{
if ('--' === substr($name, 0, 2))
{
if ('--' === substr($name, 0, 2)) {
$name = substr($name, 2);
}
if (empty($shortcut))
{
if (empty($shortcut)) {
$shortcut = null;
}
if (null !== $shortcut)
{
if ('-' === $shortcut[0])
{
if (null !== $shortcut) {
if ('-' === $shortcut[0]) {
$shortcut = substr($shortcut, 1);
}
}
if (null === $mode)
{
if (null === $mode) {
$mode = self::PARAMETER_NONE;
}
else if (!is_int($mode) || $mode > 15)
{
} else if (!is_int($mode) || $mode > 15) {
throw new \InvalidArgumentException(sprintf('Option mode "%s" is not valid.', $mode));
}
......@@ -74,8 +67,7 @@ class InputOption
$this->mode = $mode;
$this->description = $description;
if ($this->isArray() && !$this->acceptParameter())
{
if ($this->isArray() && !$this->acceptParameter()) {
throw new \InvalidArgumentException('Impossible to have an option mode PARAMETER_IS_ARRAY if the option does not accept a parameter.');
}
......@@ -149,19 +141,14 @@ class InputOption
*/
public function setDefault($default = null)
{
if (self::PARAMETER_NONE === (self::PARAMETER_NONE & $this->mode) && null !== $default)
{
if (self::PARAMETER_NONE === (self::PARAMETER_NONE & $this->mode) && null !== $default) {
throw new \LogicException('Cannot set a default value when using Option::PARAMETER_NONE mode.');
}
if ($this->isArray())
{
if (null === $default)
{
if ($this->isArray()) {
if (null === $default) {
$default = array();
}
elseif (!is_array($default))
{
} elseif (!is_array($default)) {
throw new \LogicException('A default value for an array option must be an array.');
}
}
......
......@@ -3,7 +3,7 @@
namespace Symfony\Component\Console\Input;
/*
* This file is part of the symfony framework.
* This file is part of the Symfony framework.
*
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
*
......@@ -18,8 +18,6 @@ namespace Symfony\Component\Console\Input;
*
* $input = new StringInput('foo --bar="foobar"');
*
* @package symfony
* @subpackage console
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
*/
class StringInput extends ArgvInput
......@@ -40,6 +38,9 @@ class StringInput extends ArgvInput
$this->tokens = $this->tokenize($input);
}
/**
* @throws \InvalidArgumentException When unable to parse input (should never happen)
*/
protected function tokenize($input)
{
$input = preg_replace('/(\r\n|\r|\n|\t)/', ' ', $input);
......@@ -47,25 +48,15 @@ class StringInput extends ArgvInput
$tokens = array();
$length = strlen($input);
$cursor = 0;
while ($cursor < $length)
{
if (preg_match('/\s+/A', $input, $match, null, $cursor))
{
}
elseif (preg_match('/([^="\' ]+?)(=?)('.self::REGEX_QUOTED_STRING.'+)/A', $input, $match, null, $cursor))
{
while ($cursor < $length) {
if (preg_match('/\s+/A', $input, $match, null, $cursor)) {
} elseif (preg_match('/([^="\' ]+?)(=?)('.self::REGEX_QUOTED_STRING.'+)/A', $input, $match, null, $cursor)) {
$tokens[] = $match[1].$match[2].stripcslashes(str_replace(array('"\'', '\'"', '\'\'', '""'), '', substr($match[3], 1, strlen($match[3]) - 2)));
}
elseif (preg_match('/'.self::REGEX_QUOTED_STRING.'/A', $input, $match, null, $cursor))
{
} elseif (preg_match('/'.self::REGEX_QUOTED_STRING.'/A', $input, $match, null, $cursor)) {
$tokens[] = stripcslashes(substr($match[0], 1, strlen($match[0]) - 2));
}
elseif (preg_match('/'.self::REGEX_STRING.'/A', $input, $match, null, $cursor))
{
} elseif (preg_match('/'.self::REGEX_STRING.'/A', $input, $match, null, $cursor)) {
$tokens[] = stripcslashes($match[1]);
}
else
{
} else {
// should never happen
// @codeCoverageIgnoreStart
throw new \InvalidArgumentException(sprintf('Unable to parse input near "... %s ..."', substr($input, $cursor, 10)));
......
......@@ -3,7 +3,7 @@
namespace Symfony\Component\Console\Output;
/*
* This file is part of the symfony framework.
* This file is part of the Symfony framework.
*
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
*
......@@ -22,8 +22,6 @@ namespace Symfony\Component\Console\Output;
*
* $output = new StreamOutput(fopen('php://stdout', 'w'));
*
* @package symfony
* @subpackage console
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
*/
class ConsoleOutput extends StreamOutput
......
......@@ -3,7 +3,7 @@
namespace Symfony\Component\Console\Output;
/*
* This file is part of the symfony framework.
* This file is part of the Symfony framework.
*
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
*
......@@ -16,8 +16,6 @@ namespace Symfony\Component\Console\Output;
*
* $output = new NullOutput();
*
* @package symfony
* @subpackage console
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
*/
class NullOutput extends Output
......
......@@ -3,7 +3,7 @@
namespace Symfony\Component\Console\Output;
/*
* This file is part of the symfony framework.
* This file is part of the Symfony framework.
*
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
*
......@@ -20,8 +20,6 @@ namespace Symfony\Component\Console\Output;
* * verbose: -v (more output - debug)
* * quiet: -q (no output)
*
* @package symfony
* @subpackage console
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
*/
abstract class Output implements OutputInterface
......@@ -127,23 +125,21 @@ abstract class Output implements OutputInterface
* @param string|array $messages The message as an array of lines of a single string
* @param Boolean $newline Whether to add a newline or not
* @param integer $type The type of output
*
* @throws \InvalidArgumentException When unknown output type is given
*/
public function write($messages, $newline = false, $type = 0)
{
if (self::VERBOSITY_QUIET === $this->verbosity)
{
if (self::VERBOSITY_QUIET === $this->verbosity) {
return;
}
if (!is_array($messages))
{
if (!is_array($messages)) {
$messages = array($messages);
}
foreach ($messages as $message)
{
switch ($type)
{
foreach ($messages as $message) {
switch ($type) {
case Output::OUTPUT_NORMAL:
$message = $this->format($message);
break;
......@@ -177,51 +173,56 @@ abstract class Output implements OutputInterface
*/
protected function format($message)
{
$message = preg_replace_callback('#<([a-z][a-z0-9\-_]+)>#i', array($this, 'replaceStartStyle'), $message);
$message = preg_replace_callback('#<([a-z][a-z0-9\-_=;]+)>#i', array($this, 'replaceStartStyle'), $message);
return preg_replace_callback('#</([a-z][a-z0-9\-_]+)>#i', array($this, 'replaceEndStyle'), $message);
return preg_replace_callback('#</([a-z][a-z0-9\-_]*)?>#i', array($this, 'replaceEndStyle'), $message);
}
/**
* @throws \InvalidArgumentException When style is unknown
*/
protected function replaceStartStyle($match)
{
if (!$this->decorated)
{
if (!$this->decorated) {
return '';
}
if (!isset(static::$styles[strtolower($match[1])]))
{
if (isset(static::$styles[strtolower($match[1])])) {
$parameters = static::$styles[strtolower($match[1])];
} else {
// bg=blue;fg=red
if (!preg_match_all('/([^=]+)=([^;]+)(;|$)/', strtolower($match[1]), $matches, PREG_SET_ORDER)) {
throw new \InvalidArgumentException(sprintf('Unknown style "%s".', $match[1]));
}
$parameters = static::$styles[strtolower($match[1])];
$parameters = array();
foreach ($matches as $match) {
$parameters[$match[1]] = $match[2];
}
}
$codes = array();
if (isset($parameters['fg']))
{
if (isset($parameters['fg'])) {
$codes[] = static::$foreground[$parameters['fg']];
}
if (isset($parameters['bg']))
{
if (isset($parameters['bg'])) {
$codes[] = static::$background[$parameters['bg']];
}
foreach (static::$options as $option => $value)
{
if (isset($parameters[$option]) && $parameters[$option])
{
foreach (static::$options as $option => $value) {
if (isset($parameters[$option]) && $parameters[$option]) {
$codes[] = $value;
}
}
return "\033[".implode(';', $codes)."m";
return "\033[".implode(';', $codes).'m';
}
protected function replaceEndStyle($match)
{
if (!$this->decorated)
{
if (!$this->decorated) {
return '';
}
......
......@@ -3,7 +3,7 @@
namespace Symfony\Component\Console\Output;
/*
* This file is part of the symfony framework.
* This file is part of the Symfony framework.
*
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
*
......@@ -14,8 +14,6 @@ namespace Symfony\Component\Console\Output;
/**
* OutputInterface is the interface implemented by all Output classes.
*
* @package symfony
* @subpackage console
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
*/
interface OutputInterface
......@@ -24,21 +22,24 @@ interface OutputInterface
* Writes a message to the output.
*
* @param string|array $messages The message as an array of lines of a single string
* @param Boolean $newline Whether to add a newline or not
* @param integer $type The type of output
*
* @throws \InvalidArgumentException When unknown output type is given
*/
public function write($messages, $type = 0);
function write($messages, $newline = false, $type = 0);
/**
* Sets the verbosity of the output.
*
* @param integer $level The level of verbosity
*/
public function setVerbosity($level);
function setVerbosity($level);
/**
* Sets the decorated flag.
*
* @param Boolean $decorated Whether to decorated the messages or not
*/
public function setDecorated($decorated);
function setDecorated($decorated);
}
......@@ -3,7 +3,7 @@
namespace Symfony\Component\Console\Output;
/*
* This file is part of the symfony framework.
* This file is part of the Symfony framework.
*
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
*
......@@ -22,8 +22,6 @@ namespace Symfony\Component\Console\Output;
*
* $output = new StreamOutput(fopen('/path/to/output.log', 'a', false));
*
* @package symfony
* @subpackage console
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
*/
class StreamOutput extends Output
......@@ -36,18 +34,18 @@ class StreamOutput extends Output
* @param mixed $stream A stream resource
* @param integer $verbosity The verbosity level (self::VERBOSITY_QUIET, self::VERBOSITY_NORMAL, self::VERBOSITY_VERBOSE)
* @param Boolean $decorated Whether to decorate messages or not (null for auto-guessing)
*
* @throws \InvalidArgumentException When first argument is not a real stream
*/
public function __construct($stream, $verbosity = self::VERBOSITY_NORMAL, $decorated = null)
{
if (!is_resource($stream) || 'stream' !== get_resource_type($stream))
{
if (!is_resource($stream) || 'stream' !== get_resource_type($stream)) {
throw new \InvalidArgumentException('The StreamOutput class needs a stream as its first argument.');
}
$this->stream = $stream;
if (null === $decorated)
{
if (null === $decorated) {
$decorated = $this->hasColorSupport($decorated);
}
......@@ -69,11 +67,12 @@ class StreamOutput extends Output
*
* @param string $message A message to write to the output
* @param Boolean $newline Whether to add a newline or not
*
* @throws \RuntimeException When unable to write output (should never happen)
*/
public function doWrite($message, $newline)
{
if (false === @fwrite($this->stream, $message.($newline ? PHP_EOL : '')))
{
if (false === @fwrite($this->stream, $message.($newline ? PHP_EOL : ''))) {
// @codeCoverageIgnoreStart
// should never happen
throw new \RuntimeException('Unable to write output.');
......@@ -96,12 +95,9 @@ class StreamOutput extends Output
protected function hasColorSupport()
{
// @codeCoverageIgnoreStart
if (DIRECTORY_SEPARATOR == '\\')
{
if (DIRECTORY_SEPARATOR == '\\') {
return false !== getenv('ANSICON');
}
else
{
} else {
return function_exists('posix_isatty') && @posix_isatty($this->stream);
}
// @codeCoverageIgnoreEnd
......
......@@ -7,7 +7,7 @@ use Symfony\Component\Console\Input\StringInput;
use Symfony\Component\Console\Output\ConsoleOutput;
/*
* This file is part of the symfony framework.
* This file is part of the Symfony framework.
*
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
*
......@@ -21,8 +21,6 @@ use Symfony\Component\Console\Output\ConsoleOutput;
* This class only works with a PHP compiled with readline support
* (either --with-readline or --with-libedit)
*
* @package symfony
* @subpackage cli
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
*/
class Shell
......@@ -38,11 +36,12 @@ class Shell
* a \RuntimeException exception is thrown.
*
* @param Application $application An application instance
*
* @throws \RuntimeException When Readline extension is not enabled
*/
public function __construct(Application $application)
{
if (!function_exists('readline'))
{
if (!function_exists('readline')) {
throw new \RuntimeException('Unable to start the shell as the Readline extension is not enabled.');
}
......@@ -63,12 +62,10 @@ class Shell
readline_completion_function(array($this, 'autocompleter'));
$this->output->writeln($this->getHeader());
while (true)
{
while (true) {
$command = readline($this->application->getName().' > ');
if (false === $command)
{
if (false === $command) {
$this->output->writeln("\n");
break;
......@@ -77,8 +74,7 @@ class Shell
readline_add_history($command);
readline_write_history($this->history);
if (0 !== $ret = $this->application->run(new StringInput($command), $this->output))
{
if (0 !== $ret = $this->application->run(new StringInput($command), $this->output)) {
$this->output->writeln(sprintf('<error>The command terminated with an error status (%s)</error>', $ret));
}
}
......@@ -95,30 +91,24 @@ class Shell
$info = readline_info();
$text = substr($info['line_buffer'], 0, $info['end']);
if ($info['point'] !== $info['end'])
{
if ($info['point'] !== $info['end']) {
return true;
}
// task name?
if (false === strpos($text, ' ') || !$text)
{
if (false === strpos($text, ' ') || !$text) {
return array_keys($this->application->getCommands());
}
// options and arguments?
try
{
try {
$command = $this->application->findCommand(substr($text, 0, strpos($text, ' ')));
}
catch (\Exception $e)
{
} catch (\Exception $e) {
return true;
}
$list = array('--help');
foreach ($command->getDefinition()->getOptions() as $option)
{
foreach ($command->getDefinition()->getOptions() as $option) {
$list[] = '--'.$option->getName();
}
......
......@@ -6,6 +6,18 @@ use Symfony\Component\Console\Application;
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Output\StreamOutput;
/*
* 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.
*/
/**
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
*/
class ApplicationTester
{
protected $application;
......@@ -38,18 +50,15 @@ class ApplicationTester
public function run(array $input, $options = array())
{
$this->input = new ArrayInput($input);
if (isset($options['interactive']))
{
if (isset($options['interactive'])) {
$this->input->setInteractive($options['interactive']);
}
$this->output = new StreamOutput(fopen('php://memory', 'w', false));
if (isset($options['decorated']))
{
if (isset($options['decorated'])) {
$this->output->setDecorated($options['decorated']);
}
if (isset($options['verbosity']))
{
if (isset($options['verbosity'])) {
$this->output->setVerbosity($options['verbosity']);
}
......
......@@ -6,6 +6,18 @@ use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Output\StreamOutput;
/*
* 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.
*/
/**
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
*/
class CommandTester
{
protected $command;
......@@ -37,19 +49,16 @@ class CommandTester
*/
public function execute(array $input, array $options = array())
{
$this->input = new ArrayInput(array_merge($input, array('command' => $this->command->getFullName())));
if (isset($options['interactive']))
{
$this->input = new ArrayInput($input);
if (isset($options['interactive'])) {
$this->input->setInteractive($options['interactive']);
}
$this->output = new StreamOutput(fopen('php://memory', 'w', false));
if (isset($options['decorated']))
{
if (isset($options['decorated'])) {
$this->output->setDecorated($options['decorated']);
}
if (isset($options['verbosity']))
{
if (isset($options['verbosity'])) {
$this->output->setVerbosity($options['verbosity']);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment