Update to Drupal 8.2.6. For more information, see https://www.drupal.org/project/drupal/releases/8.2.6

This commit is contained in:
Pantheon Automation 2017-02-02 16:28:38 -08:00 committed by Greg Anderson
parent db56c09587
commit f1e72395cb
588 changed files with 26857 additions and 2777 deletions

View file

@ -41,6 +41,7 @@ use Symfony\Component\Console\Event\ConsoleExceptionEvent;
use Symfony\Component\Console\Event\ConsoleTerminateEvent;
use Symfony\Component\Console\Exception\CommandNotFoundException;
use Symfony\Component\Console\Exception\LogicException;
use Symfony\Component\Debug\Exception\FatalThrowableError;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
/**
@ -104,8 +105,6 @@ class Application
* @param OutputInterface $output An Output instance
*
* @return int 0 if everything went fine, or an error code
*
* @throws \Exception When doRun returns Exception
*/
public function run(InputInterface $input = null, OutputInterface $output = null)
{
@ -216,7 +215,7 @@ class Application
}
/**
* Set an input definition set to be used with this application.
* Set an input definition to be used with this application.
*
* @param InputDefinition $definition The input definition
*/
@ -238,7 +237,7 @@ class Application
/**
* Gets the help message.
*
* @return string A help message.
* @return string A help message
*/
public function getHelp()
{
@ -338,6 +337,8 @@ class Application
/**
* Adds an array of command objects.
*
* If a Command is not enabled it will not be added.
*
* @param Command[] $commands An array of commands
*/
public function addCommands(array $commands)
@ -351,10 +352,11 @@ class Application
* Adds a command object.
*
* If a command with the same name already exists, it will be overridden.
* If the command is not enabled it will not be added.
*
* @param Command $command A Command object
*
* @return Command The registered command
* @return Command|null The registered command if enabled or null
*/
public function add(Command $command)
{
@ -386,7 +388,7 @@ class Application
*
* @return Command A Command object
*
* @throws CommandNotFoundException When command name given does not exist
* @throws CommandNotFoundException When given command name does not exist
*/
public function get($name)
{
@ -423,9 +425,9 @@ class Application
/**
* Returns an array of all unique namespaces used by currently registered commands.
*
* It does not returns the global namespace which always exists.
* It does not return the global namespace which always exists.
*
* @return array An array of namespaces
* @return string[] An array of namespaces
*/
public function getNamespaces()
{
@ -773,7 +775,7 @@ class Application
* @param int $width The width
* @param int $height The height
*
* @return Application The current application
* @return $this
*/
public function setTerminalDimensions($width, $height)
{
@ -807,6 +809,7 @@ class Application
if (true === $input->hasParameterOption(array('--quiet', '-q'))) {
$output->setVerbosity(OutputInterface::VERBOSITY_QUIET);
$input->setInteractive(false);
} else {
if ($input->hasParameterOption('-vvv') || $input->hasParameterOption('--verbose=3') || $input->getParameterOption('--verbose') === 3) {
$output->setVerbosity(OutputInterface::VERBOSITY_DEBUG);
@ -829,8 +832,6 @@ class Application
* @param OutputInterface $output An Output instance
*
* @return int 0 if everything went fine, or an error code
*
* @throws \Exception when the command being run threw an exception
*/
protected function doRunCommand(Command $command, InputInterface $input, OutputInterface $output)
{
@ -841,7 +842,13 @@ class Application
}
if (null === $this->dispatcher) {
return $command->run($input, $output);
try {
return $command->run($input, $output);
} catch (\Exception $e) {
throw $e;
} catch (\Throwable $e) {
throw new FatalThrowableError($e);
}
}
// bind before the console.command event, so the listeners have access to input options/arguments
@ -857,17 +864,25 @@ class Application
if ($event->commandShouldRun()) {
try {
$e = null;
$exitCode = $command->run($input, $output);
} catch (\Exception $e) {
} catch (\Exception $x) {
$e = $x;
} catch (\Throwable $x) {
$e = new FatalThrowableError($x);
}
if (null !== $e) {
$event = new ConsoleExceptionEvent($command, $input, $output, $e, $e->getCode());
$this->dispatcher->dispatch(ConsoleEvents::EXCEPTION, $event);
$e = $event->getException();
if ($e !== $event->getException()) {
$x = $e = $event->getException();
}
$event = new ConsoleTerminateEvent($command, $input, $output, $e->getCode());
$this->dispatcher->dispatch(ConsoleEvents::TERMINATE, $event);
throw $e;
throw $x;
}
} else {
$exitCode = ConsoleCommandEvent::RETURN_CODE_DISABLED;
@ -965,7 +980,7 @@ class Application
/**
* Runs and parses mode CON if it's available, suppressing any error output.
*
* @return string <width>x<height> or null if it could not be parsed
* @return string|null <width>x<height> or null if it could not be parsed
*/
private function getConsoleMode()
{
@ -1024,7 +1039,7 @@ class Application
* @param string $name The string
* @param array|\Traversable $collection The collection
*
* @return array A sorted array of similar string
* @return string[] A sorted array of similar string
*/
private function findAlternatives($name, $collection)
{
@ -1123,7 +1138,7 @@ class Application
*
* @param string $name The full name of the command
*
* @return array The namespaces of the command
* @return string[] The namespaces of the command
*/
private function extractAllNamespaces($name)
{

View file

@ -205,8 +205,6 @@ class Command
*
* @return int The command exit code
*
* @throws \Exception
*
* @see setCode()
* @see execute()
*/
@ -232,7 +230,14 @@ class Command
if (null !== $this->processTitle) {
if (function_exists('cli_set_process_title')) {
cli_set_process_title($this->processTitle);
if (false === @cli_set_process_title($this->processTitle)) {
if ('Darwin' === PHP_OS) {
$output->writeln('<comment>Running "cli_get_process_title" as an unprivileged user is not supported on MacOS.</comment>');
} else {
$error = error_get_last();
trigger_error($error['message'], E_USER_WARNING);
}
}
} elseif (function_exists('setproctitle')) {
setproctitle($this->processTitle);
} elseif (OutputInterface::VERBOSITY_VERY_VERBOSE === $output->getVerbosity()) {
@ -270,7 +275,7 @@ class Command
*
* @param callable $code A callable(InputInterface $input, OutputInterface $output)
*
* @return Command The current instance
* @return $this
*
* @throws InvalidArgumentException
*
@ -285,7 +290,15 @@ class Command
if (PHP_VERSION_ID >= 50400 && $code instanceof \Closure) {
$r = new \ReflectionFunction($code);
if (null === $r->getClosureThis()) {
$code = \Closure::bind($code, $this);
if (PHP_VERSION_ID < 70000) {
// Bug in PHP5: https://bugs.php.net/bug.php?id=64761
// This means that we cannot bind static closures and therefore we must
// ignore any errors here. There is no way to test if the closure is
// bindable.
$code = @\Closure::bind($code, $this);
} else {
$code = \Closure::bind($code, $this);
}
}
}
@ -307,14 +320,14 @@ class Command
return;
}
$this->definition->addOptions($this->application->getDefinition()->getOptions());
if ($mergeArgs) {
$currentArguments = $this->definition->getArguments();
$this->definition->setArguments($this->application->getDefinition()->getArguments());
$this->definition->addArguments($currentArguments);
}
$this->definition->addOptions($this->application->getDefinition()->getOptions());
$this->applicationDefinitionMerged = true;
if ($mergeArgs) {
$this->applicationDefinitionMergedWithArgs = true;
@ -326,7 +339,7 @@ class Command
*
* @param array|InputDefinition $definition An array of argument and option instances or a definition instance
*
* @return Command The current instance
* @return $this
*/
public function setDefinition($definition)
{
@ -374,7 +387,7 @@ class Command
* @param string $description A description text
* @param mixed $default The default value (for InputArgument::OPTIONAL mode only)
*
* @return Command The current instance
* @return $this
*/
public function addArgument($name, $mode = null, $description = '', $default = null)
{
@ -392,7 +405,7 @@ class Command
* @param string $description A description text
* @param mixed $default The default value (must be null for InputOption::VALUE_NONE)
*
* @return Command The current instance
* @return $this
*/
public function addOption($name, $shortcut = null, $mode = null, $description = '', $default = null)
{
@ -411,7 +424,7 @@ class Command
*
* @param string $name The command name
*
* @return Command The current instance
* @return $this
*
* @throws InvalidArgumentException When the name is invalid
*/
@ -434,7 +447,7 @@ class Command
*
* @param string $title The process title
*
* @return Command The current instance
* @return $this
*/
public function setProcessTitle($title)
{
@ -458,7 +471,7 @@ class Command
*
* @param string $description The description for the command
*
* @return Command The current instance
* @return $this
*/
public function setDescription($description)
{
@ -482,7 +495,7 @@ class Command
*
* @param string $help The help for the command
*
* @return Command The current instance
* @return $this
*/
public function setHelp($help)
{
@ -528,7 +541,7 @@ class Command
*
* @param string[] $aliases An array of aliases for the command
*
* @return Command The current instance
* @return $this
*
* @throws InvalidArgumentException When an alias is invalid
*/
@ -579,6 +592,8 @@ class Command
* Add a command usage example.
*
* @param string $usage The usage, it'll be prefixed with the command name
*
* @return $this
*/
public function addUsage($usage)
{
@ -608,10 +623,15 @@ class Command
*
* @return mixed The helper value
*
* @throws LogicException if no HelperSet is defined
* @throws InvalidArgumentException if the helper is not defined
*/
public function getHelper($name)
{
if (null === $this->helperSet) {
throw new LogicException(sprintf('Cannot retrieve helper "%s" because there is no HelperSet defined. Did you forget to add your command to the application or to set the application on the command using the setApplication() method? You can also set the HelperSet directly using the setHelperSet() method.', $name));
}
return $this->helperSet->get($name);
}

View file

@ -13,6 +13,7 @@ namespace Symfony\Component\Console\Descriptor;
use Symfony\Component\Console\Application;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Helper\Helper;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputDefinition;
use Symfony\Component\Console\Input\InputOption;
@ -94,11 +95,11 @@ class MarkdownDescriptor extends Descriptor
$this->write(
$command->getName()."\n"
.str_repeat('-', strlen($command->getName()))."\n\n"
.str_repeat('-', Helper::strlen($command->getName()))."\n\n"
.'* Description: '.($command->getDescription() ?: '<none>')."\n"
.'* Usage:'."\n\n"
.array_reduce(array_merge(array($command->getSynopsis()), $command->getAliases(), $command->getUsages()), function ($carry, $usage) {
return $carry .= ' * `'.$usage.'`'."\n";
return $carry.' * `'.$usage.'`'."\n";
})
);
@ -121,7 +122,7 @@ class MarkdownDescriptor extends Descriptor
$describedNamespace = isset($options['namespace']) ? $options['namespace'] : null;
$description = new ApplicationDescription($application, $describedNamespace);
$this->write($application->getName()."\n".str_repeat('=', strlen($application->getName())));
$this->write($application->getName()."\n".str_repeat('=', Helper::strlen($application->getName())));
foreach ($description->getNamespaces() as $namespace) {
if (ApplicationDescription::GLOBAL_NAMESPACE !== $namespace['id']) {

View file

@ -13,6 +13,8 @@ namespace Symfony\Component\Console\Descriptor;
use Symfony\Component\Console\Application;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Formatter\OutputFormatter;
use Symfony\Component\Console\Helper\Helper;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputDefinition;
use Symfony\Component\Console\Input\InputOption;
@ -37,14 +39,14 @@ class TextDescriptor extends Descriptor
$default = '';
}
$totalWidth = isset($options['total_width']) ? $options['total_width'] : strlen($argument->getName());
$spacingWidth = $totalWidth - strlen($argument->getName()) + 2;
$totalWidth = isset($options['total_width']) ? $options['total_width'] : Helper::strlen($argument->getName());
$spacingWidth = $totalWidth - strlen($argument->getName());
$this->writeText(sprintf(' <info>%s</info>%s%s%s',
$this->writeText(sprintf(' <info>%s</info> %s%s%s',
$argument->getName(),
str_repeat(' ', $spacingWidth),
// + 17 = 2 spaces + <info> + </info> + 2 spaces
preg_replace('/\s*[\r\n]\s*/', "\n".str_repeat(' ', $totalWidth + 17), $argument->getDescription()),
// + 4 = 2 spaces before <info>, 2 spaces after </info>
preg_replace('/\s*[\r\n]\s*/', "\n".str_repeat(' ', $totalWidth + 4), $argument->getDescription()),
$default
), $options);
}
@ -75,13 +77,13 @@ class TextDescriptor extends Descriptor
sprintf('--%s%s', $option->getName(), $value)
);
$spacingWidth = $totalWidth - strlen($synopsis) + 2;
$spacingWidth = $totalWidth - Helper::strlen($synopsis);
$this->writeText(sprintf(' <info>%s</info>%s%s%s%s',
$this->writeText(sprintf(' <info>%s</info> %s%s%s%s',
$synopsis,
str_repeat(' ', $spacingWidth),
// + 17 = 2 spaces + <info> + </info> + 2 spaces
preg_replace('/\s*[\r\n]\s*/', "\n".str_repeat(' ', $totalWidth + 17), $option->getDescription()),
// + 4 = 2 spaces before <info>, 2 spaces after </info>
preg_replace('/\s*[\r\n]\s*/', "\n".str_repeat(' ', $totalWidth + 4), $option->getDescription()),
$default,
$option->isArray() ? '<comment> (multiple values allowed)</comment>' : ''
), $options);
@ -94,7 +96,7 @@ class TextDescriptor extends Descriptor
{
$totalWidth = $this->calculateTotalWidthForOptions($definition->getOptions());
foreach ($definition->getArguments() as $argument) {
$totalWidth = max($totalWidth, strlen($argument->getName()));
$totalWidth = max($totalWidth, Helper::strlen($argument->getName()));
}
if ($definition->getArguments()) {
@ -156,7 +158,7 @@ class TextDescriptor extends Descriptor
$this->writeText("\n");
$this->writeText('<comment>Help:</comment>', $options);
$this->writeText("\n");
$this->writeText(' '.str_replace("\n", "\n ", $help), $options);
$this->writeText(' '.str_replace("\n", "\n ", $help), $options);
$this->writeText("\n");
}
}
@ -206,7 +208,7 @@ class TextDescriptor extends Descriptor
foreach ($namespace['commands'] as $name) {
$this->writeText("\n");
$spacingWidth = $width - strlen($name);
$spacingWidth = $width - Helper::strlen($name);
$this->writeText(sprintf(' <info>%s</info>%s%s', $name, str_repeat(' ', $spacingWidth), $description->getCommand($name)->getDescription()), $options);
}
}
@ -235,6 +237,16 @@ class TextDescriptor extends Descriptor
*/
private function formatDefaultValue($default)
{
if (is_string($default)) {
$default = OutputFormatter::escape($default);
} elseif (is_array($default)) {
foreach ($default as $key => $value) {
if (is_string($value)) {
$default[$key] = OutputFormatter::escape($value);
}
}
}
if (PHP_VERSION_ID < 50400) {
return str_replace(array('\/', '\\\\'), array('/', '\\'), json_encode($default));
}
@ -252,9 +264,9 @@ class TextDescriptor extends Descriptor
$widths = array();
foreach ($commands as $command) {
$widths[] = strlen($command->getName());
$widths[] = Helper::strlen($command->getName());
foreach ($command->getAliases() as $alias) {
$widths[] = strlen($alias);
$widths[] = Helper::strlen($alias);
}
}
@ -271,10 +283,10 @@ class TextDescriptor extends Descriptor
$totalWidth = 0;
foreach ($options as $option) {
// "-" + shortcut + ", --" + name
$nameLength = 1 + max(strlen($option->getShortcut()), 1) + 4 + strlen($option->getName());
$nameLength = 1 + max(strlen($option->getShortcut()), 1) + 4 + Helper::strlen($option->getName());
if ($option->acceptValue()) {
$valueLength = 1 + strlen($option->getName()); // = + value
$valueLength = 1 + Helper::strlen($option->getName()); // = + value
$valueLength += $option->isValueOptional() ? 2 : 0; // [ + ]
$nameLength += $valueLength;

View file

@ -21,10 +21,10 @@ class CommandNotFoundException extends \InvalidArgumentException implements Exce
private $alternatives;
/**
* @param string $message Exception message to throw.
* @param array $alternatives List of similar defined names.
* @param int $code Exception code.
* @param Exception $previous previous exception used for the exception chaining.
* @param string $message Exception message to throw
* @param array $alternatives List of similar defined names
* @param int $code Exception code
* @param Exception $previous previous exception used for the exception chaining
*/
public function __construct($message, array $alternatives = array(), $code = 0, \Exception $previous = null)
{
@ -34,7 +34,7 @@ class CommandNotFoundException extends \InvalidArgumentException implements Exce
}
/**
* @return array A list of similar defined names.
* @return array A list of similar defined names
*/
public function getAlternatives()
{

View file

@ -35,6 +35,20 @@ class OutputFormatter implements OutputFormatterInterface
{
$text = preg_replace('/([^\\\\]?)</', '$1\\<', $text);
return self::escapeTrailingBackslash($text);
}
/**
* Escapes trailing "\" in given text.
*
* @param string $text Text to escape
*
* @return string Escaped text
*
* @internal
*/
public static function escapeTrailingBackslash($text)
{
if ('\\' === substr($text, -1)) {
$len = strlen($text);
$text = rtrim($text, '\\');
@ -194,7 +208,7 @@ class OutputFormatter implements OutputFormatterInterface
*
* @param string $string
*
* @return OutputFormatterStyle|bool false if string is not format string
* @return OutputFormatterStyle|false false if string is not format string
*/
private function createStyleFromString($string)
{

View file

@ -104,7 +104,7 @@ class OutputFormatterStyleStack
/**
* @param OutputFormatterStyleInterface $emptyStyle
*
* @return OutputFormatterStyleStack
* @return $this
*/
public function setEmptyStyle(OutputFormatterStyleInterface $emptyStyle)
{

View file

@ -78,7 +78,7 @@ class DescriptorHelper extends Helper
* @param string $format
* @param DescriptorInterface $descriptor
*
* @return DescriptorHelper
* @return $this
*/
public function register($format, DescriptorInterface $descriptor)
{

View file

@ -35,7 +35,7 @@ abstract class Helper implements HelperInterface
/**
* Gets the helper set associated with this helper.
*
* @return HelperSet A HelperSet instance
* @return HelperSet|null
*/
public function getHelperSet()
{
@ -62,26 +62,28 @@ abstract class Helper implements HelperInterface
{
static $timeFormats = array(
array(0, '< 1 sec'),
array(2, '1 sec'),
array(59, 'secs', 1),
array(1, '1 sec'),
array(2, 'secs', 1),
array(60, '1 min'),
array(3600, 'mins', 60),
array(5400, '1 hr'),
array(86400, 'hrs', 3600),
array(129600, '1 day'),
array(604800, 'days', 86400),
array(120, 'mins', 60),
array(3600, '1 hr'),
array(7200, 'hrs', 3600),
array(86400, '1 day'),
array(172800, 'days', 86400),
);
foreach ($timeFormats as $format) {
foreach ($timeFormats as $index => $format) {
if ($secs >= $format[0]) {
continue;
}
if ((isset($timeFormats[$index + 1]) && $secs < $timeFormats[$index + 1][0])
|| $index == count($timeFormats) - 1
) {
if (2 == count($format)) {
return $format[1];
}
if (2 == count($format)) {
return $format[1];
return floor($secs / $format[2]).' '.$format[1];
}
}
return ceil($secs / $format[2]).' '.$format[1];
}
}

View file

@ -21,13 +21,16 @@ use Symfony\Component\Console\Exception\InvalidArgumentException;
*/
class HelperSet implements \IteratorAggregate
{
/**
* @var Helper[]
*/
private $helpers = array();
private $command;
/**
* Constructor.
*
* @param Helper[] $helpers An array of helper.
* @param Helper[] $helpers An array of helper
*/
public function __construct(array $helpers = array())
{
@ -110,6 +113,9 @@ class HelperSet implements \IteratorAggregate
return $this->command;
}
/**
* @return Helper[]
*/
public function getIterator()
{
return new \ArrayIterator($this->helpers);

View file

@ -41,10 +41,10 @@ class ProgressBar
private $startTime;
private $stepWidth;
private $percent = 0.0;
private $lastMessagesLength = 0;
private $formatLineCount;
private $messages;
private $messages = array();
private $overwrite = true;
private $firstRun = true;
private static $formatters;
private static $formats;
@ -141,6 +141,16 @@ class ProgressBar
return isset(self::$formats[$name]) ? self::$formats[$name] : null;
}
/**
* Associates a text with a named placeholder.
*
* The text is displayed when the progress bar is rendered but only
* when the corresponding placeholder is part of the custom format line
* (by wrapping the name with %).
*
* @param string $message The text to associate with the placeholder
* @param string $name The name of the placeholder
*/
public function setMessage($message, $name = 'message')
{
$this->messages[$name] = $message;
@ -473,7 +483,7 @@ class ProgressBar
$this->setRealFormat($this->internalFormat ?: $this->determineBestFormat());
}
$this->overwrite(str_repeat("\n", $this->formatLineCount));
$this->overwrite('');
}
/**
@ -513,37 +523,26 @@ class ProgressBar
*/
private function overwrite($message)
{
$lines = explode("\n", $message);
if ($this->overwrite) {
if (!$this->firstRun) {
// Move the cursor to the beginning of the line
$this->output->write("\x0D");
// append whitespace to match the line's length
if (null !== $this->lastMessagesLength) {
foreach ($lines as $i => $line) {
if ($this->lastMessagesLength > Helper::strlenWithoutDecoration($this->output->getFormatter(), $line)) {
$lines[$i] = str_pad($line, $this->lastMessagesLength, "\x20", STR_PAD_RIGHT);
// Erase the line
$this->output->write("\x1B[2K");
// Erase previous lines
if ($this->formatLineCount > 0) {
$this->output->write(str_repeat("\x1B[1A\x1B[2K", $this->formatLineCount));
}
}
}
if ($this->overwrite) {
// move back to the beginning of the progress bar before redrawing it
$this->output->write("\x0D");
} elseif ($this->step > 0) {
// move to new line
$this->output->writeln('');
}
if ($this->formatLineCount) {
$this->output->write(sprintf("\033[%dA", $this->formatLineCount));
}
$this->output->write(implode("\n", $lines));
$this->firstRun = false;
$this->lastMessagesLength = 0;
foreach ($lines as $line) {
$len = Helper::strlenWithoutDecoration($this->output->getFormatter(), $line);
if ($len > $this->lastMessagesLength) {
$this->lastMessagesLength = $len;
}
}
$this->output->write($message);
}
private function determineBestFormat()

View file

@ -372,8 +372,6 @@ class ProgressHelper extends Helper
}
if (isset($this->formatVars['bar'])) {
$completeBars = 0;
if ($this->max > 0) {
$completeBars = floor($percent * $this->barWidth);
} else {

View file

@ -11,6 +11,8 @@
namespace Symfony\Component\Console\Helper;
use Symfony\Component\Console\Exception\InvalidArgumentException;
use Symfony\Component\Console\Exception\LogicException;
use Symfony\Component\Console\Output\OutputInterface;
/**
@ -26,7 +28,6 @@ class ProgressIndicator
private $indicatorCurrent;
private $indicatorChangeInterval;
private $indicatorUpdateTime;
private $lastMessagesLength;
private $started = false;
private static $formatters;
@ -53,7 +54,7 @@ class ProgressIndicator
$indicatorValues = array_values($indicatorValues);
if (2 > count($indicatorValues)) {
throw new \InvalidArgumentException('Must have at least 2 indicator value characters.');
throw new InvalidArgumentException('Must have at least 2 indicator value characters.');
}
$this->format = self::getFormatDefinition($format);
@ -118,12 +119,11 @@ class ProgressIndicator
public function start($message)
{
if ($this->started) {
throw new \LogicException('Progress indicator already started.');
throw new LogicException('Progress indicator already started.');
}
$this->message = $message;
$this->started = true;
$this->lastMessagesLength = 0;
$this->startTime = time();
$this->indicatorUpdateTime = $this->getCurrentTimeInMilliseconds() + $this->indicatorChangeInterval;
$this->indicatorCurrent = 0;
@ -137,7 +137,7 @@ class ProgressIndicator
public function advance()
{
if (!$this->started) {
throw new \LogicException('Progress indicator has not yet been started.');
throw new LogicException('Progress indicator has not yet been started.');
}
if (!$this->output->isDecorated()) {
@ -164,7 +164,7 @@ class ProgressIndicator
public function finish($message)
{
if (!$this->started) {
throw new \LogicException('Progress indicator has not yet been started.');
throw new LogicException('Progress indicator has not yet been started.');
}
$this->message = $message;
@ -260,27 +260,12 @@ class ProgressIndicator
*/
private function overwrite($message)
{
// append whitespace to match the line's length
if (null !== $this->lastMessagesLength) {
if ($this->lastMessagesLength > Helper::strlenWithoutDecoration($this->output->getFormatter(), $message)) {
$message = str_pad($message, $this->lastMessagesLength, "\x20", STR_PAD_RIGHT);
}
}
if ($this->output->isDecorated()) {
$this->output->write("\x0D");
$this->output->write("\x0D\x1B[2K");
$this->output->write($message);
} else {
$this->output->writeln($message);
}
$this->lastMessagesLength = 0;
$len = Helper::strlenWithoutDecoration($this->output->getFormatter(), $message);
if ($len > $this->lastMessagesLength) {
$this->lastMessagesLength = $len;
}
}
private function getCurrentTimeInMilliseconds()

View file

@ -136,7 +136,7 @@ class QuestionHelper extends Helper
if (false === $ret) {
$ret = fgets($inputStream, 4096);
if (false === $ret) {
throw new \RuntimeException('Aborted');
throw new RuntimeException('Aborted');
}
$ret = trim($ret);
}
@ -202,6 +202,7 @@ class QuestionHelper extends Helper
*
* @param OutputInterface $output
* @param Question $question
* @param resource $inputStream
*
* @return string
*/
@ -318,7 +319,8 @@ class QuestionHelper extends Helper
/**
* Gets a hidden response from user.
*
* @param OutputInterface $output An Output instance
* @param OutputInterface $output An Output instance
* @param resource $inputStream The handler resource
*
* @return string The answer
*
@ -397,6 +399,8 @@ class QuestionHelper extends Helper
try {
return call_user_func($question->getValidator(), $interviewer());
} catch (RuntimeException $e) {
throw $e;
} catch (\Exception $error) {
}
}

View file

@ -18,6 +18,7 @@ use Symfony\Component\Console\Question\ChoiceQuestion;
use Symfony\Component\Console\Question\ConfirmationQuestion;
use Symfony\Component\Console\Question\Question;
use Symfony\Component\Console\Style\SymfonyStyle;
use Symfony\Component\Console\Formatter\OutputFormatter;
/**
* Symfony Style Guide compliant question helper.
@ -35,11 +36,11 @@ class SymfonyQuestionHelper extends QuestionHelper
$question->setValidator(function ($value) use ($validator) {
if (null !== $validator) {
$value = $validator($value);
}
// make required
if (!is_array($value) && !is_bool($value) && 0 === strlen($value)) {
throw new LogicException('A value is required.');
} else {
// make required
if (!is_array($value) && !is_bool($value) && 0 === strlen($value)) {
throw new LogicException('A value is required.');
}
}
return $value;
@ -53,7 +54,7 @@ class SymfonyQuestionHelper extends QuestionHelper
*/
protected function writePrompt(OutputInterface $output, Question $question)
{
$text = $question->getQuestion();
$text = OutputFormatter::escapeTrailingBackslash($question->getQuestion());
$default = $question->getDefault();
switch (true) {
@ -67,14 +68,26 @@ class SymfonyQuestionHelper extends QuestionHelper
break;
case $question instanceof ChoiceQuestion && $question->isMultiselect():
$choices = $question->getChoices();
$default = explode(',', $default);
foreach ($default as $key => $value) {
$default[$key] = $choices[trim($value)];
}
$text = sprintf(' <info>%s</info> [<comment>%s</comment>]:', $text, OutputFormatter::escape(implode(', ', $default)));
break;
case $question instanceof ChoiceQuestion:
$choices = $question->getChoices();
$text = sprintf(' <info>%s</info> [<comment>%s</comment>]:', $text, $choices[$default]);
$text = sprintf(' <info>%s</info> [<comment>%s</comment>]:', $text, OutputFormatter::escape($choices[$default]));
break;
default:
$text = sprintf(' <info>%s</info> [<comment>%s</comment>]:', $text, $default);
$text = sprintf(' <info>%s</info> [<comment>%s</comment>]:', $text, OutputFormatter::escape($default));
}
$output->writeln($text);

View file

@ -100,7 +100,7 @@ class Table
*
* @param string $name The style name
*
* @return TableStyle A TableStyle instance
* @return TableStyle
*/
public static function getStyleDefinition($name)
{
@ -108,11 +108,11 @@ class Table
self::$styles = self::initStyles();
}
if (!self::$styles[$name]) {
throw new InvalidArgumentException(sprintf('Style "%s" is not defined.', $name));
if (isset(self::$styles[$name])) {
return self::$styles[$name];
}
return self::$styles[$name];
throw new InvalidArgumentException(sprintf('Style "%s" is not defined.', $name));
}
/**
@ -120,17 +120,11 @@ class Table
*
* @param TableStyle|string $name The style name or a TableStyle instance
*
* @return Table
* @return $this
*/
public function setStyle($name)
{
if ($name instanceof TableStyle) {
$this->style = $name;
} elseif (isset(self::$styles[$name])) {
$this->style = self::$styles[$name];
} else {
throw new InvalidArgumentException(sprintf('Style "%s" is not defined.', $name));
}
$this->style = $this->resolveStyle($name);
return $this;
}
@ -151,19 +145,13 @@ class Table
* @param int $columnIndex Column index
* @param TableStyle|string $name The style name or a TableStyle instance
*
* @return Table
* @return $this
*/
public function setColumnStyle($columnIndex, $name)
{
$columnIndex = intval($columnIndex);
if ($name instanceof TableStyle) {
$this->columnStyles[$columnIndex] = $name;
} elseif (isset(self::$styles[$name])) {
$this->columnStyles[$columnIndex] = self::$styles[$name];
} else {
throw new \InvalidArgumentException(sprintf('Style "%s" is not defined.', $name));
}
$this->columnStyles[$columnIndex] = $this->resolveStyle($name);
return $this;
}
@ -307,7 +295,7 @@ class Table
*/
private function renderColumnSeparator()
{
$this->output->write(sprintf($this->style->getBorderFormat(), $this->style->getVerticalBorderChar()));
return sprintf($this->style->getBorderFormat(), $this->style->getVerticalBorderChar());
}
/**
@ -324,12 +312,12 @@ class Table
return;
}
$this->renderColumnSeparator();
$rowContent = $this->renderColumnSeparator();
foreach ($this->getRowColumns($row) as $column) {
$this->renderCell($row, $column, $cellFormat);
$this->renderColumnSeparator();
$rowContent .= $this->renderCell($row, $column, $cellFormat);
$rowContent .= $this->renderColumnSeparator();
}
$this->output->writeln('');
$this->output->writeln($rowContent);
}
/**
@ -358,12 +346,13 @@ class Table
$style = $this->getColumnStyle($column);
if ($cell instanceof TableSeparator) {
$this->output->write(sprintf($style->getBorderFormat(), str_repeat($style->getHorizontalBorderChar(), $width)));
} else {
$width += Helper::strlen($cell) - Helper::strlenWithoutDecoration($this->output->getFormatter(), $cell);
$content = sprintf($style->getCellRowContentFormat(), $cell);
$this->output->write(sprintf($cellFormat, str_pad($content, $width, $style->getPaddingChar(), $style->getPadType())));
return sprintf($style->getBorderFormat(), str_repeat($style->getHorizontalBorderChar(), $width));
}
$width += Helper::strlen($cell) - Helper::strlenWithoutDecoration($this->output->getFormatter(), $cell);
$content = sprintf($style->getCellRowContentFormat(), $cell);
return sprintf($cellFormat, str_pad($content, $width, $style->getPaddingChar(), $style->getPadType()));
}
/**
@ -447,7 +436,7 @@ class Table
}
// create a two dimensional array (rowspan x colspan)
$unmergedRows = array_replace_recursive(array_fill($line + 1, $nbLines, ''), $unmergedRows);
$unmergedRows = array_replace_recursive(array_fill($line + 1, $nbLines, array()), $unmergedRows);
foreach ($unmergedRows as $unmergedRowKey => $unmergedRow) {
$value = isset($lines[$unmergedRowKey - $line]) ? $lines[$unmergedRowKey - $line] : '';
$unmergedRows[$unmergedRowKey][$column] = new TableCell($value, array('colspan' => $cell->getColspan()));
@ -569,6 +558,18 @@ class Table
continue;
}
foreach ($row as $i => $cell) {
if ($cell instanceof TableCell) {
$textLength = strlen($cell);
if ($textLength > 0) {
$contentColumns = str_split($cell, ceil($textLength / $cell->getColspan()));
foreach ($contentColumns as $position => $content) {
$row[$i + $position] = $content;
}
}
}
}
$lengths[] = $this->getCellWidth($row, $column);
}
@ -599,10 +600,6 @@ class Table
if (isset($row[$column])) {
$cell = $row[$column];
$cellWidth = Helper::strlenWithoutDecoration($this->output->getFormatter(), $cell);
if ($cell instanceof TableCell && $cell->getColspan() > 1) {
// we assume that cell value will be across more than one column.
$cellWidth = $cellWidth / $cell->getColspan();
}
return $cellWidth;
}
@ -651,4 +648,17 @@ class Table
'symfony-style-guide' => $styleGuide,
);
}
private function resolveStyle($name)
{
if ($name instanceof TableStyle) {
return $name;
}
if (isset(self::$styles[$name])) {
return self::$styles[$name];
}
throw new InvalidArgumentException(sprintf('Style "%s" is not defined.', $name));
}
}

View file

@ -49,7 +49,7 @@ class TableHelper extends Helper
*
* @param int $layout self::LAYOUT_*
*
* @return TableHelper
* @return $this
*
* @throws InvalidArgumentException when the table layout is not known
*/
@ -115,7 +115,7 @@ class TableHelper extends Helper
*
* @param string $paddingChar
*
* @return TableHelper
* @return $this
*/
public function setPaddingChar($paddingChar)
{
@ -129,7 +129,7 @@ class TableHelper extends Helper
*
* @param string $horizontalBorderChar
*
* @return TableHelper
* @return $this
*/
public function setHorizontalBorderChar($horizontalBorderChar)
{
@ -143,7 +143,7 @@ class TableHelper extends Helper
*
* @param string $verticalBorderChar
*
* @return TableHelper
* @return $this
*/
public function setVerticalBorderChar($verticalBorderChar)
{
@ -157,7 +157,7 @@ class TableHelper extends Helper
*
* @param string $crossingChar
*
* @return TableHelper
* @return $this
*/
public function setCrossingChar($crossingChar)
{
@ -171,7 +171,7 @@ class TableHelper extends Helper
*
* @param string $cellHeaderFormat
*
* @return TableHelper
* @return $this
*/
public function setCellHeaderFormat($cellHeaderFormat)
{
@ -185,7 +185,7 @@ class TableHelper extends Helper
*
* @param string $cellRowFormat
*
* @return TableHelper
* @return $this
*/
public function setCellRowFormat($cellRowFormat)
{
@ -199,7 +199,7 @@ class TableHelper extends Helper
*
* @param string $cellRowContentFormat
*
* @return TableHelper
* @return $this
*/
public function setCellRowContentFormat($cellRowContentFormat)
{
@ -213,7 +213,7 @@ class TableHelper extends Helper
*
* @param string $borderFormat
*
* @return TableHelper
* @return $this
*/
public function setBorderFormat($borderFormat)
{
@ -227,7 +227,7 @@ class TableHelper extends Helper
*
* @param int $padType STR_PAD_*
*
* @return TableHelper
* @return $this
*/
public function setPadType($padType)
{

View file

@ -19,8 +19,7 @@ namespace Symfony\Component\Console\Helper;
class TableSeparator extends TableCell
{
/**
* @param string $value
* @param array $options
* @param array $options
*/
public function __construct(array $options = array())
{

View file

@ -37,7 +37,7 @@ class TableStyle
*
* @param string $paddingChar
*
* @return TableStyle
* @return $this
*/
public function setPaddingChar($paddingChar)
{
@ -65,7 +65,7 @@ class TableStyle
*
* @param string $horizontalBorderChar
*
* @return TableStyle
* @return $this
*/
public function setHorizontalBorderChar($horizontalBorderChar)
{
@ -89,7 +89,7 @@ class TableStyle
*
* @param string $verticalBorderChar
*
* @return TableStyle
* @return $this
*/
public function setVerticalBorderChar($verticalBorderChar)
{
@ -113,7 +113,7 @@ class TableStyle
*
* @param string $crossingChar
*
* @return TableStyle
* @return $this
*/
public function setCrossingChar($crossingChar)
{
@ -137,7 +137,7 @@ class TableStyle
*
* @param string $cellHeaderFormat
*
* @return TableStyle
* @return $this
*/
public function setCellHeaderFormat($cellHeaderFormat)
{
@ -161,7 +161,7 @@ class TableStyle
*
* @param string $cellRowFormat
*
* @return TableStyle
* @return $this
*/
public function setCellRowFormat($cellRowFormat)
{
@ -185,7 +185,7 @@ class TableStyle
*
* @param string $cellRowContentFormat
*
* @return TableStyle
* @return $this
*/
public function setCellRowContentFormat($cellRowContentFormat)
{
@ -209,7 +209,7 @@ class TableStyle
*
* @param string $borderFormat
*
* @return TableStyle
* @return $this
*/
public function setBorderFormat($borderFormat)
{
@ -233,7 +233,7 @@ class TableStyle
*
* @param int $padType STR_PAD_*
*
* @return TableStyle
* @return $this
*/
public function setPadType($padType)
{

View file

@ -46,8 +46,8 @@ class ArgvInput extends Input
/**
* Constructor.
*
* @param array $argv An array of parameters from the CLI (in the argv format)
* @param InputDefinition $definition A InputDefinition instance
* @param array|null $argv An array of parameters from the CLI (in the argv format)
* @param InputDefinition|null $definition A InputDefinition instance
*/
public function __construct(array $argv = null, InputDefinition $definition = null)
{
@ -69,7 +69,7 @@ class ArgvInput extends Input
}
/**
* Processes command line arguments.
* {@inheritdoc}
*/
protected function parse()
{
@ -93,7 +93,7 @@ class ArgvInput extends Input
/**
* Parses a short option.
*
* @param string $token The current token.
* @param string $token The current token
*/
private function parseShortOption($token)
{
@ -147,7 +147,10 @@ class ArgvInput extends Input
$name = substr($token, 2);
if (false !== $pos = strpos($name, '=')) {
$this->addLongOption(substr($name, 0, $pos), substr($name, $pos + 1));
if (0 === strlen($value = substr($name, $pos + 1))) {
array_unshift($this->parsed, null);
}
$this->addLongOption(substr($name, 0, $pos), $value);
} else {
$this->addLongOption($name, null);
}
@ -176,7 +179,12 @@ class ArgvInput extends Input
// unexpected argument
} else {
throw new RuntimeException('Too many arguments.');
$all = $this->definition->getArguments();
if (count($all)) {
throw new RuntimeException(sprintf('Too many arguments, expected arguments "%s".', implode('" "', array_keys($all))));
}
throw new RuntimeException(sprintf('No arguments expected, got "%s".', $token));
}
}
@ -229,7 +237,7 @@ class ArgvInput extends Input
if (isset($next[0]) && '-' !== $next[0]) {
$value = $next;
} elseif (empty($next)) {
$value = '';
$value = null;
} else {
array_unshift($this->parsed, $next);
}
@ -253,9 +261,7 @@ class ArgvInput extends Input
}
/**
* Returns the first argument from the raw parameters (not parsed).
*
* @return string The value of the first argument or null otherwise
* {@inheritdoc}
*/
public function getFirstArgument()
{
@ -269,14 +275,7 @@ class ArgvInput extends Input
}
/**
* Returns true if the raw parameters (not parsed) contain a value.
*
* This method is to be used to introspect the input parameters
* before they have been validated. It must be used carefully.
*
* @param string|array $values The value(s) to look for in the raw parameters (can be an array)
*
* @return bool true if the value is contained in the raw parameters
* {@inheritdoc}
*/
public function hasParameterOption($values)
{
@ -294,15 +293,7 @@ class ArgvInput extends Input
}
/**
* Returns the value of a raw option (not parsed).
*
* This method is to be used to introspect the input parameters
* before they have been validated. It must be used carefully.
*
* @param string|array $values The value(s) to look for in the raw parameters (can be an array)
* @param mixed $default The default value to return if no result is found
*
* @return mixed The option value
* {@inheritdoc}
*/
public function getParameterOption($values, $default = false)
{

View file

@ -30,8 +30,8 @@ class ArrayInput extends Input
/**
* Constructor.
*
* @param array $parameters An array of parameters
* @param InputDefinition $definition A InputDefinition instance
* @param array $parameters An array of parameters
* @param InputDefinition|null $definition A InputDefinition instance
*/
public function __construct(array $parameters, InputDefinition $definition = null)
{
@ -41,9 +41,7 @@ class ArrayInput extends Input
}
/**
* Returns the first argument from the raw parameters (not parsed).
*
* @return string The value of the first argument or null otherwise
* {@inheritdoc}
*/
public function getFirstArgument()
{
@ -57,14 +55,7 @@ class ArrayInput extends Input
}
/**
* Returns true if the raw parameters (not parsed) contain a value.
*
* This method is to be used to introspect the input parameters
* before they have been validated. It must be used carefully.
*
* @param string|array $values The values to look for in the raw parameters (can be an array)
*
* @return bool true if the value is contained in the raw parameters
* {@inheritdoc}
*/
public function hasParameterOption($values)
{
@ -84,15 +75,7 @@ class ArrayInput extends Input
}
/**
* Returns the value of a raw option (not parsed).
*
* This method is to be used to introspect the input parameters
* before they have been validated. It must be used carefully.
*
* @param string|array $values The value(s) to look for in the raw parameters (can be an array)
* @param mixed $default The default value to return if no result is found
*
* @return mixed The option value
* {@inheritdoc}
*/
public function getParameterOption($values, $default = false)
{
@ -131,7 +114,7 @@ class ArrayInput extends Input
}
/**
* Processes command line arguments.
* {@inheritdoc}
*/
protected function parse()
{

View file

@ -38,7 +38,7 @@ abstract class Input implements InputInterface
/**
* Constructor.
*
* @param InputDefinition $definition A InputDefinition instance
* @param InputDefinition|null $definition A InputDefinition instance
*/
public function __construct(InputDefinition $definition = null)
{
@ -51,9 +51,7 @@ abstract class Input implements InputInterface
}
/**
* Binds the current Input instance with the given arguments and options.
*
* @param InputDefinition $definition A InputDefinition instance
* {@inheritdoc}
*/
public function bind(InputDefinition $definition)
{
@ -70,9 +68,7 @@ abstract class Input implements InputInterface
abstract protected function parse();
/**
* Validates the input.
*
* @throws RuntimeException When not enough arguments are given
* {@inheritdoc}
*/
public function validate()
{
@ -89,9 +85,7 @@ abstract class Input implements InputInterface
}
/**
* Checks if the input is interactive.
*
* @return bool Returns true if the input is interactive
* {@inheritdoc}
*/
public function isInteractive()
{
@ -99,9 +93,7 @@ abstract class Input implements InputInterface
}
/**
* Sets the input interactivity.
*
* @param bool $interactive If the input should be interactive
* {@inheritdoc}
*/
public function setInteractive($interactive)
{
@ -109,9 +101,7 @@ abstract class Input implements InputInterface
}
/**
* Returns the argument values.
*
* @return array An array of argument values
* {@inheritdoc}
*/
public function getArguments()
{
@ -119,13 +109,7 @@ abstract class Input implements InputInterface
}
/**
* Returns the argument value for a given argument name.
*
* @param string $name The argument name
*
* @return mixed The argument value
*
* @throws InvalidArgumentException When argument given doesn't exist
* {@inheritdoc}
*/
public function getArgument($name)
{
@ -137,12 +121,7 @@ abstract class Input implements InputInterface
}
/**
* Sets an argument value by name.
*
* @param string $name The argument name
* @param string $value The argument value
*
* @throws InvalidArgumentException When argument given doesn't exist
* {@inheritdoc}
*/
public function setArgument($name, $value)
{
@ -154,11 +133,7 @@ abstract class Input implements InputInterface
}
/**
* Returns true if an InputArgument object exists by name or position.
*
* @param string|int $name The InputArgument name or position
*
* @return bool true if the InputArgument object exists, false otherwise
* {@inheritdoc}
*/
public function hasArgument($name)
{
@ -166,9 +141,7 @@ abstract class Input implements InputInterface
}
/**
* Returns the options values.
*
* @return array An array of option values
* {@inheritdoc}
*/
public function getOptions()
{
@ -176,13 +149,7 @@ abstract class Input implements InputInterface
}
/**
* Returns the option value for a given option name.
*
* @param string $name The option name
*
* @return mixed The option value
*
* @throws InvalidArgumentException When option given doesn't exist
* {@inheritdoc}
*/
public function getOption($name)
{
@ -194,12 +161,7 @@ abstract class Input implements InputInterface
}
/**
* Sets an option value by name.
*
* @param string $name The option name
* @param string|bool $value The option value
*
* @throws InvalidArgumentException When option given doesn't exist
* {@inheritdoc}
*/
public function setOption($name, $value)
{
@ -211,11 +173,7 @@ abstract class Input implements InputInterface
}
/**
* Returns true if an InputOption object exists by name.
*
* @param string $name The InputOption name
*
* @return bool true if the InputOption object exists, false otherwise
* {@inheritdoc}
*/
public function hasOption($name)
{

View file

@ -284,6 +284,9 @@ class InputDefinition
/**
* Returns true if an InputOption object exists by name.
*
* This method can't be used to check if the user included the option when
* executing the command (use getOption() instead).
*
* @param string $name The InputOption name
*
* @return bool true if the InputOption object exists, false otherwise

View file

@ -11,6 +11,9 @@
namespace Symfony\Component\Console\Input;
use Symfony\Component\Console\Exception\InvalidArgumentException;
use Symfony\Component\Console\Exception\RuntimeException;
/**
* InputInterface is the interface implemented by all input classes.
*
@ -58,11 +61,9 @@ interface InputInterface
public function bind(InputDefinition $definition);
/**
* Validates if arguments given are correct.
* Validates the input.
*
* Throws an exception when not enough arguments are given.
*
* @throws \RuntimeException
* @throws RuntimeException When not enough arguments are given
*/
public function validate();
@ -74,11 +75,13 @@ interface InputInterface
public function getArguments();
/**
* Gets argument by name.
* Returns the argument value for a given argument name.
*
* @param string $name The name of the argument
* @param string $name The argument name
*
* @return mixed
* @return mixed The argument value
*
* @throws InvalidArgumentException When argument given doesn't exist
*/
public function getArgument($name);
@ -109,11 +112,13 @@ interface InputInterface
public function getOptions();
/**
* Gets an option by name.
* Returns the option value for a given option name.
*
* @param string $name The name of the option
* @param string $name The option name
*
* @return mixed
* @return mixed The option value
*
* @throws InvalidArgumentException When option given doesn't exist
*/
public function getOption($name);

View file

@ -1,4 +1,4 @@
Copyright (c) 2004-2016 Fabien Potencier
Copyright (c) 2004-2017 Fabien Potencier
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View file

@ -22,7 +22,7 @@ use Symfony\Component\Console\Output\ConsoleOutputInterface;
*
* @author Kévin Dunglas <dunglas@gmail.com>
*
* @link http://www.php-fig.org/psr/psr-3/
* @see http://www.php-fig.org/psr/psr-3/
*/
class ConsoleLogger extends AbstractLogger
{

View file

@ -73,21 +73,33 @@ class NullOutput implements OutputInterface
return self::VERBOSITY_QUIET;
}
/**
* {@inheritdoc}
*/
public function isQuiet()
{
return true;
}
/**
* {@inheritdoc}
*/
public function isVerbose()
{
return false;
}
/**
* {@inheritdoc}
*/
public function isVeryVerbose()
{
return false;
}
/**
* {@inheritdoc}
*/
public function isDebug()
{
return false;

View file

@ -94,21 +94,33 @@ abstract class Output implements OutputInterface
return $this->verbosity;
}
/**
* {@inheritdoc}
*/
public function isQuiet()
{
return self::VERBOSITY_QUIET === $this->verbosity;
}
/**
* {@inheritdoc}
*/
public function isVerbose()
{
return self::VERBOSITY_VERBOSE <= $this->verbosity;
}
/**
* {@inheritdoc}
*/
public function isVeryVerbose()
{
return self::VERBOSITY_VERY_VERBOSE <= $this->verbosity;
}
/**
* {@inheritdoc}
*/
public function isDebug()
{
return self::VERBOSITY_DEBUG <= $this->verbosity;

View file

@ -72,7 +72,7 @@ class StreamOutput extends Output
*/
protected function doWrite($message, $newline)
{
if (false === @fwrite($this->stream, $message.($newline ? PHP_EOL : ''))) {
if (false === @fwrite($this->stream, $message) || ($newline && (false === @fwrite($this->stream, PHP_EOL)))) {
// should never happen
throw new RuntimeException('Unable to write output.');
}
@ -85,7 +85,7 @@ class StreamOutput extends Output
*
* Colorization is disabled if not supported by the stream:
*
* - Windows without Ansicon, ConEmu or Mintty
* - Windows != 10.0.10586 without Ansicon, ConEmu or Mintty
* - non tty consoles
*
* @return bool true if the stream supports colorization, false otherwise
@ -93,7 +93,11 @@ class StreamOutput extends Output
protected function hasColorSupport()
{
if (DIRECTORY_SEPARATOR === '\\') {
return false !== getenv('ANSICON') || 'ON' === getenv('ConEmuANSI') || 'xterm' === getenv('TERM');
return
'10.0.10586' === PHP_WINDOWS_VERSION_MAJOR.'.'.PHP_WINDOWS_VERSION_MINOR.'.'.PHP_WINDOWS_VERSION_BUILD
|| false !== getenv('ANSICON')
|| 'ON' === getenv('ConEmuANSI')
|| 'xterm' === getenv('TERM');
}
return function_exists('posix_isatty') && @posix_isatty($this->stream);

View file

@ -58,7 +58,7 @@ class ChoiceQuestion extends Question
*
* @param bool $multiselect
*
* @return ChoiceQuestion The current instance
* @return $this
*/
public function setMultiselect($multiselect)
{
@ -68,6 +68,16 @@ class ChoiceQuestion extends Question
return $this;
}
/**
* Returns whether the choices are multiselect.
*
* @return bool
*/
public function isMultiselect()
{
return $this->multiselect;
}
/**
* Gets the prompt for choices.
*
@ -83,7 +93,7 @@ class ChoiceQuestion extends Question
*
* @param string $prompt
*
* @return ChoiceQuestion The current instance
* @return $this
*/
public function setPrompt($prompt)
{
@ -99,7 +109,7 @@ class ChoiceQuestion extends Question
*
* @param string $errorMessage
*
* @return ChoiceQuestion The current instance
* @return $this
*/
public function setErrorMessage($errorMessage)
{

View file

@ -77,7 +77,7 @@ class Question
*
* @param bool $hidden
*
* @return Question The current instance
* @return $this
*
* @throws LogicException In case the autocompleter is also used
*/
@ -107,7 +107,7 @@ class Question
*
* @param bool $fallback
*
* @return Question The current instance
* @return $this
*/
public function setHiddenFallback($fallback)
{
@ -131,7 +131,7 @@ class Question
*
* @param null|array|\Traversable $values
*
* @return Question The current instance
* @return $this
*
* @throws InvalidArgumentException
* @throws LogicException
@ -162,7 +162,7 @@ class Question
*
* @param null|callable $validator
*
* @return Question The current instance
* @return $this
*/
public function setValidator($validator)
{
@ -188,7 +188,7 @@ class Question
*
* @param null|int $attempts
*
* @return Question The current instance
* @return $this
*
* @throws InvalidArgumentException In case the number of attempts is invalid.
*/
@ -222,7 +222,7 @@ class Question
*
* @param callable $normalizer
*
* @return Question The current instance
* @return $this
*/
public function setNormalizer($normalizer)
{

View file

@ -65,40 +65,10 @@ class SymfonyStyle extends OutputStyle
*/
public function block($messages, $type = null, $style = null, $prefix = ' ', $padding = false)
{
$this->autoPrependBlock();
$messages = is_array($messages) ? array_values($messages) : array($messages);
$lines = array();
// add type
if (null !== $type) {
$messages[0] = sprintf('[%s] %s', $type, $messages[0]);
}
// wrap and add newlines for each element
foreach ($messages as $key => $message) {
$message = OutputFormatter::escape($message);
$lines = array_merge($lines, explode(PHP_EOL, wordwrap($message, $this->lineLength - Helper::strlen($prefix), PHP_EOL, true)));
if (count($messages) > 1 && $key < count($messages) - 1) {
$lines[] = '';
}
}
if ($padding && $this->isDecorated()) {
array_unshift($lines, '');
$lines[] = '';
}
foreach ($lines as &$line) {
$line = sprintf('%s%s', $prefix, $line);
$line .= str_repeat(' ', $this->lineLength - Helper::strlenWithoutDecoration($this->getFormatter(), $line));
if ($style) {
$line = sprintf('<%s>%s</>', $style, $line);
}
}
$this->writeln($lines);
$this->autoPrependBlock();
$this->writeln($this->createBlock($messages, $type, $style, $prefix, $padding, true));
$this->newLine();
}
@ -109,7 +79,7 @@ class SymfonyStyle extends OutputStyle
{
$this->autoPrependBlock();
$this->writeln(array(
sprintf('<comment>%s</>', $message),
sprintf('<comment>%s</>', OutputFormatter::escapeTrailingBackslash($message)),
sprintf('<comment>%s</>', str_repeat('=', Helper::strlenWithoutDecoration($this->getFormatter(), $message))),
));
$this->newLine();
@ -122,7 +92,7 @@ class SymfonyStyle extends OutputStyle
{
$this->autoPrependBlock();
$this->writeln(array(
sprintf('<comment>%s</>', $message),
sprintf('<comment>%s</>', OutputFormatter::escapeTrailingBackslash($message)),
sprintf('<comment>%s</>', str_repeat('-', Helper::strlenWithoutDecoration($this->getFormatter(), $message))),
));
$this->newLine();
@ -156,16 +126,17 @@ class SymfonyStyle extends OutputStyle
}
/**
* {@inheritdoc}
* Formats a command comment.
*
* @param string|array $message
*/
public function comment($message)
{
$this->autoPrependText();
$messages = is_array($message) ? array_values($message) : array($message);
foreach ($messages as $message) {
$this->writeln(sprintf(' // %s', $message));
}
$this->autoPrependBlock();
$this->writeln($this->createBlock($messages, null, null, '<fg=default;bg=default> // </>'));
$this->newLine();
}
/**
@ -213,12 +184,13 @@ class SymfonyStyle extends OutputStyle
*/
public function table(array $headers, array $rows)
{
$headers = array_map(function ($value) { return sprintf('<info>%s</>', $value); }, $headers);
$style = clone Table::getStyleDefinition('symfony-style-guide');
$style->setCellHeaderFormat('<info>%s</info>');
$table = new Table($this);
$table->setHeaders($headers);
$table->setRows($rows);
$table->setStyle('symfony-style-guide');
$table->setStyle($style);
$table->render();
$this->newLine();
@ -412,4 +384,52 @@ class SymfonyStyle extends OutputStyle
return substr($value, -4);
}, array_merge(array($this->bufferedOutput->fetch()), (array) $messages));
}
private function createBlock($messages, $type = null, $style = null, $prefix = ' ', $padding = false, $escape = false)
{
$indentLength = 0;
$prefixLength = Helper::strlenWithoutDecoration($this->getFormatter(), $prefix);
$lines = array();
if (null !== $type) {
$type = sprintf('[%s] ', $type);
$indentLength = strlen($type);
$lineIndentation = str_repeat(' ', $indentLength);
}
// wrap and add newlines for each element
foreach ($messages as $key => $message) {
if ($escape) {
$message = OutputFormatter::escape($message);
}
$lines = array_merge($lines, explode(PHP_EOL, wordwrap($message, $this->lineLength - $prefixLength - $indentLength, PHP_EOL, true)));
if (count($messages) > 1 && $key < count($messages) - 1) {
$lines[] = '';
}
}
$firstLineIndex = 0;
if ($padding && $this->isDecorated()) {
$firstLineIndex = 1;
array_unshift($lines, '');
$lines[] = '';
}
foreach ($lines as $i => &$line) {
if (null !== $type) {
$line = $firstLineIndex === $i ? $type.$line : $lineIndentation.$line;
}
$line = $prefix.$line;
$line .= str_repeat(' ', $this->lineLength - Helper::strlenWithoutDecoration($this->getFormatter(), $line));
if ($style) {
$line = sprintf('<%s>%s</>', $style, $line);
}
}
return $lines;
}
}

View file

@ -37,7 +37,7 @@ class ApplicationTester
/**
* Constructor.
*
* @param Application $application An Application instance to test.
* @param Application $application An Application instance to test
*/
public function __construct(Application $application)
{

View file

@ -32,7 +32,7 @@ class CommandTester
/**
* Constructor.
*
* @param Command $command A Command instance to test.
* @param Command $command A Command instance to test
*/
public function __construct(Command $command)
{

View file

@ -17,7 +17,8 @@
],
"require": {
"php": ">=5.3.9",
"symfony/polyfill-mbstring": "~1.0"
"symfony/polyfill-mbstring": "~1.0",
"symfony/debug": "~2.7,>=2.7.2|~3.0.0"
},
"require-dev": {
"symfony/event-dispatcher": "~2.1|~3.0.0",