Add pear modules, mail and net_smtp via composer (#93)
Add pear modules, mail and net_smtp via composer, remove php 5.6 build due to phpunit 6
This commit is contained in:
518
lib/composer/vendor/symfony/console/Application.php
vendored
518
lib/composer/vendor/symfony/console/Application.php
vendored
@@ -11,11 +11,15 @@
|
||||
|
||||
namespace Symfony\Component\Console;
|
||||
|
||||
use Symfony\Component\Console\CommandLoader\CommandLoaderInterface;
|
||||
use Symfony\Component\Console\Exception\ExceptionInterface;
|
||||
use Symfony\Component\Console\Formatter\OutputFormatter;
|
||||
use Symfony\Component\Console\Helper\DebugFormatterHelper;
|
||||
use Symfony\Component\Console\Helper\Helper;
|
||||
use Symfony\Component\Console\Helper\ProcessHelper;
|
||||
use Symfony\Component\Console\Helper\QuestionHelper;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\StreamableInputInterface;
|
||||
use Symfony\Component\Console\Input\ArgvInput;
|
||||
use Symfony\Component\Console\Input\ArrayInput;
|
||||
use Symfony\Component\Console\Input\InputDefinition;
|
||||
@@ -31,10 +35,12 @@ use Symfony\Component\Console\Command\ListCommand;
|
||||
use Symfony\Component\Console\Helper\HelperSet;
|
||||
use Symfony\Component\Console\Helper\FormatterHelper;
|
||||
use Symfony\Component\Console\Event\ConsoleCommandEvent;
|
||||
use Symfony\Component\Console\Event\ConsoleErrorEvent;
|
||||
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\ErrorHandler;
|
||||
use Symfony\Component\Debug\Exception\FatalThrowableError;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||
|
||||
@@ -60,17 +66,18 @@ class Application
|
||||
private $runningCommand;
|
||||
private $name;
|
||||
private $version;
|
||||
private $commandLoader;
|
||||
private $catchExceptions = true;
|
||||
private $autoExit = true;
|
||||
private $definition;
|
||||
private $helperSet;
|
||||
private $dispatcher;
|
||||
private $terminalDimensions;
|
||||
private $terminal;
|
||||
private $defaultCommand;
|
||||
private $singleCommand;
|
||||
private $initialized;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $name The name of the application
|
||||
* @param string $version The version of the application
|
||||
*/
|
||||
@@ -78,13 +85,8 @@ class Application
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->version = $version;
|
||||
$this->terminal = new Terminal();
|
||||
$this->defaultCommand = 'list';
|
||||
$this->helperSet = $this->getDefaultHelperSet();
|
||||
$this->definition = $this->getDefaultInputDefinition();
|
||||
|
||||
foreach ($this->getDefaultCommands() as $command) {
|
||||
$this->add($command);
|
||||
}
|
||||
}
|
||||
|
||||
public function setDispatcher(EventDispatcherInterface $dispatcher)
|
||||
@@ -92,18 +94,23 @@ class Application
|
||||
$this->dispatcher = $dispatcher;
|
||||
}
|
||||
|
||||
public function setCommandLoader(CommandLoaderInterface $commandLoader)
|
||||
{
|
||||
$this->commandLoader = $commandLoader;
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the current application.
|
||||
*
|
||||
* @param InputInterface $input An Input instance
|
||||
* @param OutputInterface $output An Output instance
|
||||
*
|
||||
* @return int 0 if everything went fine, or an error code
|
||||
*
|
||||
* @throws \Exception When doRun returns Exception
|
||||
* @throws \Exception When running fails. Bypass this when {@link setCatchExceptions()}.
|
||||
*/
|
||||
public function run(InputInterface $input = null, OutputInterface $output = null)
|
||||
{
|
||||
putenv('LINES='.$this->terminal->getHeight());
|
||||
putenv('COLUMNS='.$this->terminal->getWidth());
|
||||
|
||||
if (null === $input) {
|
||||
$input = new ArgvInput();
|
||||
}
|
||||
@@ -112,6 +119,29 @@ class Application
|
||||
$output = new ConsoleOutput();
|
||||
}
|
||||
|
||||
$renderException = function ($e) use ($output) {
|
||||
if (!$e instanceof \Exception) {
|
||||
$e = class_exists(FatalThrowableError::class) ? new FatalThrowableError($e) : new \ErrorException($e->getMessage(), $e->getCode(), E_ERROR, $e->getFile(), $e->getLine());
|
||||
}
|
||||
if ($output instanceof ConsoleOutputInterface) {
|
||||
$this->renderException($e, $output->getErrorOutput());
|
||||
} else {
|
||||
$this->renderException($e, $output);
|
||||
}
|
||||
};
|
||||
if ($phpHandler = set_exception_handler($renderException)) {
|
||||
restore_exception_handler();
|
||||
if (!is_array($phpHandler) || !$phpHandler[0] instanceof ErrorHandler) {
|
||||
$debugHandler = true;
|
||||
} elseif ($debugHandler = $phpHandler[0]->setExceptionHandler($renderException)) {
|
||||
$phpHandler[0]->setExceptionHandler($debugHandler);
|
||||
}
|
||||
}
|
||||
|
||||
if (null !== $this->dispatcher && $this->dispatcher->hasListeners(ConsoleEvents::EXCEPTION)) {
|
||||
@trigger_error(sprintf('The "ConsoleEvents::EXCEPTION" event is deprecated since Symfony 3.3 and will be removed in 4.0. Listen to the "ConsoleEvents::ERROR" event instead.'), E_USER_DEPRECATED);
|
||||
}
|
||||
|
||||
$this->configureIO($input, $output);
|
||||
|
||||
try {
|
||||
@@ -121,11 +151,7 @@ class Application
|
||||
throw $e;
|
||||
}
|
||||
|
||||
if ($output instanceof ConsoleOutputInterface) {
|
||||
$this->renderException($e, $output->getErrorOutput());
|
||||
} else {
|
||||
$this->renderException($e, $output);
|
||||
}
|
||||
$renderException($e);
|
||||
|
||||
$exitCode = $e->getCode();
|
||||
if (is_numeric($exitCode)) {
|
||||
@@ -136,6 +162,12 @@ class Application
|
||||
} else {
|
||||
$exitCode = 1;
|
||||
}
|
||||
} finally {
|
||||
if (!$phpHandler) {
|
||||
restore_exception_handler();
|
||||
} elseif (!$debugHandler) {
|
||||
$phpHandler[0]->setExceptionHandler(null);
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->autoExit) {
|
||||
@@ -152,9 +184,6 @@ class Application
|
||||
/**
|
||||
* Runs the current application.
|
||||
*
|
||||
* @param InputInterface $input An Input instance
|
||||
* @param OutputInterface $output An Output instance
|
||||
*
|
||||
* @return int 0 if everything went fine, or an error code
|
||||
*/
|
||||
public function doRun(InputInterface $input, OutputInterface $output)
|
||||
@@ -169,7 +198,7 @@ class Application
|
||||
if (true === $input->hasParameterOption(array('--help', '-h'), true)) {
|
||||
if (!$name) {
|
||||
$name = 'help';
|
||||
$input = new ArrayInput(array('command' => 'help'));
|
||||
$input = new ArrayInput(array('command_name' => $this->defaultCommand));
|
||||
} else {
|
||||
$this->wantHelps = true;
|
||||
}
|
||||
@@ -177,11 +206,35 @@ class Application
|
||||
|
||||
if (!$name) {
|
||||
$name = $this->defaultCommand;
|
||||
$input = new ArrayInput(array('command' => $this->defaultCommand));
|
||||
$definition = $this->getDefinition();
|
||||
$definition->setArguments(array_merge(
|
||||
$definition->getArguments(),
|
||||
array(
|
||||
'command' => new InputArgument('command', InputArgument::OPTIONAL, $definition->getArgument('command')->getDescription(), $name),
|
||||
)
|
||||
));
|
||||
}
|
||||
|
||||
// the command name MUST be the first element of the input
|
||||
$command = $this->find($name);
|
||||
try {
|
||||
$e = $this->runningCommand = null;
|
||||
// the command name MUST be the first element of the input
|
||||
$command = $this->find($name);
|
||||
} catch (\Exception $e) {
|
||||
} catch (\Throwable $e) {
|
||||
}
|
||||
if (null !== $e) {
|
||||
if (null !== $this->dispatcher) {
|
||||
$event = new ConsoleErrorEvent($input, $output, $e);
|
||||
$this->dispatcher->dispatch(ConsoleEvents::ERROR, $event);
|
||||
$e = $event->getError();
|
||||
|
||||
if (0 === $event->getExitCode()) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
throw $e;
|
||||
}
|
||||
|
||||
$this->runningCommand = $command;
|
||||
$exitCode = $this->doRunCommand($command, $input, $output);
|
||||
@@ -190,11 +243,6 @@ class Application
|
||||
return $exitCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a helper set to be used with the command.
|
||||
*
|
||||
* @param HelperSet $helperSet The helper set
|
||||
*/
|
||||
public function setHelperSet(HelperSet $helperSet)
|
||||
{
|
||||
$this->helperSet = $helperSet;
|
||||
@@ -207,14 +255,13 @@ class Application
|
||||
*/
|
||||
public function getHelperSet()
|
||||
{
|
||||
if (!$this->helperSet) {
|
||||
$this->helperSet = $this->getDefaultHelperSet();
|
||||
}
|
||||
|
||||
return $this->helperSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set an input definition to be used with this application.
|
||||
*
|
||||
* @param InputDefinition $definition The input definition
|
||||
*/
|
||||
public function setDefinition(InputDefinition $definition)
|
||||
{
|
||||
$this->definition = $definition;
|
||||
@@ -227,6 +274,17 @@ class Application
|
||||
*/
|
||||
public function getDefinition()
|
||||
{
|
||||
if (!$this->definition) {
|
||||
$this->definition = $this->getDefaultInputDefinition();
|
||||
}
|
||||
|
||||
if ($this->singleCommand) {
|
||||
$inputDefinition = $this->definition;
|
||||
$inputDefinition->setArguments();
|
||||
|
||||
return $inputDefinition;
|
||||
}
|
||||
|
||||
return $this->definition;
|
||||
}
|
||||
|
||||
@@ -329,13 +387,13 @@ class Application
|
||||
{
|
||||
if ('UNKNOWN' !== $this->getName()) {
|
||||
if ('UNKNOWN' !== $this->getVersion()) {
|
||||
return sprintf('<info>%s</info> version <comment>%s</comment>', $this->getName(), $this->getVersion());
|
||||
return sprintf('%s <info>%s</info>', $this->getName(), $this->getVersion());
|
||||
}
|
||||
|
||||
return sprintf('<info>%s</info>', $this->getName());
|
||||
return $this->getName();
|
||||
}
|
||||
|
||||
return '<info>Console Tool</info>';
|
||||
return 'Console Tool';
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -370,12 +428,12 @@ class Application
|
||||
* 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|null The registered command if enabled or null
|
||||
*/
|
||||
public function add(Command $command)
|
||||
{
|
||||
$this->init();
|
||||
|
||||
$command->setApplication($this);
|
||||
|
||||
if (!$command->isEnabled()) {
|
||||
@@ -388,6 +446,10 @@ class Application
|
||||
throw new LogicException(sprintf('Command class "%s" is not correctly initialized. You probably forgot to call the parent constructor.', get_class($command)));
|
||||
}
|
||||
|
||||
if (!$command->getName()) {
|
||||
throw new LogicException(sprintf('The command defined in "%s" cannot have an empty name.', get_class($command)));
|
||||
}
|
||||
|
||||
$this->commands[$command->getName()] = $command;
|
||||
|
||||
foreach ($command->getAliases() as $alias) {
|
||||
@@ -404,11 +466,13 @@ 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)
|
||||
{
|
||||
if (!isset($this->commands[$name])) {
|
||||
$this->init();
|
||||
|
||||
if (!$this->has($name)) {
|
||||
throw new CommandNotFoundException(sprintf('The command "%s" does not exist.', $name));
|
||||
}
|
||||
|
||||
@@ -435,7 +499,9 @@ class Application
|
||||
*/
|
||||
public function has($name)
|
||||
{
|
||||
return isset($this->commands[$name]);
|
||||
$this->init();
|
||||
|
||||
return isset($this->commands[$name]) || ($this->commandLoader && $this->commandLoader->has($name) && $this->add($this->commandLoader->get($name)));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -492,7 +558,7 @@ class Application
|
||||
|
||||
$exact = in_array($namespace, $namespaces, true);
|
||||
if (count($namespaces) > 1 && !$exact) {
|
||||
throw new CommandNotFoundException(sprintf('The namespace "%s" is ambiguous (%s).', $namespace, $this->getAbbreviationSuggestions(array_values($namespaces))), array_values($namespaces));
|
||||
throw new CommandNotFoundException(sprintf("The namespace \"%s\" is ambiguous.\nDid you mean one of these?\n%s", $namespace, $this->getAbbreviationSuggestions(array_values($namespaces))), array_values($namespaces));
|
||||
}
|
||||
|
||||
return $exact ? $namespace : reset($namespaces);
|
||||
@@ -512,11 +578,19 @@ class Application
|
||||
*/
|
||||
public function find($name)
|
||||
{
|
||||
$allCommands = array_keys($this->commands);
|
||||
$this->init();
|
||||
|
||||
$aliases = array();
|
||||
$allCommands = $this->commandLoader ? array_merge($this->commandLoader->getNames(), array_keys($this->commands)) : array_keys($this->commands);
|
||||
$expr = preg_replace_callback('{([^:]+|)}', function ($matches) { return preg_quote($matches[1]).'[^:]*'; }, $name);
|
||||
$commands = preg_grep('{^'.$expr.'}', $allCommands);
|
||||
|
||||
if (empty($commands) || count(preg_grep('{^'.$expr.'$}', $commands)) < 1) {
|
||||
if (empty($commands)) {
|
||||
$commands = preg_grep('{^'.$expr.'}i', $allCommands);
|
||||
}
|
||||
|
||||
// if no commands matched or we just matched namespaces
|
||||
if (empty($commands) || count(preg_grep('{^'.$expr.'$}i', $commands)) < 1) {
|
||||
if (false !== $pos = strrpos($name, ':')) {
|
||||
// check if a namespace exists and contains commands
|
||||
$this->findNamespace(substr($name, 0, $pos));
|
||||
@@ -538,19 +612,34 @@ class Application
|
||||
|
||||
// filter out aliases for commands which are already on the list
|
||||
if (count($commands) > 1) {
|
||||
$commandList = $this->commands;
|
||||
$commands = array_filter($commands, function ($nameOrAlias) use ($commandList, $commands) {
|
||||
$commandName = $commandList[$nameOrAlias]->getName();
|
||||
$commandList = $this->commandLoader ? array_merge(array_flip($this->commandLoader->getNames()), $this->commands) : $this->commands;
|
||||
$commands = array_unique(array_filter($commands, function ($nameOrAlias) use ($commandList, $commands, &$aliases) {
|
||||
$commandName = $commandList[$nameOrAlias] instanceof Command ? $commandList[$nameOrAlias]->getName() : $nameOrAlias;
|
||||
$aliases[$nameOrAlias] = $commandName;
|
||||
|
||||
return $commandName === $nameOrAlias || !in_array($commandName, $commands);
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
$exact = in_array($name, $commands, true);
|
||||
$exact = in_array($name, $commands, true) || isset($aliases[$name]);
|
||||
if (count($commands) > 1 && !$exact) {
|
||||
$suggestions = $this->getAbbreviationSuggestions(array_values($commands));
|
||||
$usableWidth = $this->terminal->getWidth() - 10;
|
||||
$abbrevs = array_values($commands);
|
||||
$maxLen = 0;
|
||||
foreach ($abbrevs as $abbrev) {
|
||||
$maxLen = max(Helper::strlen($abbrev), $maxLen);
|
||||
}
|
||||
$abbrevs = array_map(function ($cmd) use ($commandList, $usableWidth, $maxLen) {
|
||||
if (!$commandList[$cmd] instanceof Command) {
|
||||
return $cmd;
|
||||
}
|
||||
$abbrev = str_pad($cmd, $maxLen, ' ').' '.$commandList[$cmd]->getDescription();
|
||||
|
||||
throw new CommandNotFoundException(sprintf('Command "%s" is ambiguous (%s).', $name, $suggestions), array_values($commands));
|
||||
return Helper::strlen($abbrev) > $usableWidth ? Helper::substr($abbrev, 0, $usableWidth - 3).'...' : $abbrev;
|
||||
}, array_values($commands));
|
||||
$suggestions = $this->getAbbreviationSuggestions($abbrevs);
|
||||
|
||||
throw new CommandNotFoundException(sprintf("Command \"%s\" is ambiguous.\nDid you mean one of these?\n%s", $name, $suggestions), array_values($commands));
|
||||
}
|
||||
|
||||
return $this->get($exact ? $name : reset($commands));
|
||||
@@ -567,8 +656,21 @@ class Application
|
||||
*/
|
||||
public function all($namespace = null)
|
||||
{
|
||||
$this->init();
|
||||
|
||||
if (null === $namespace) {
|
||||
return $this->commands;
|
||||
if (!$this->commandLoader) {
|
||||
return $this->commands;
|
||||
}
|
||||
|
||||
$commands = $this->commands;
|
||||
foreach ($this->commandLoader->getNames() as $name) {
|
||||
if (!isset($commands[$name]) && $this->has($name)) {
|
||||
$commands[$name] = $this->get($name);
|
||||
}
|
||||
}
|
||||
|
||||
return $commands;
|
||||
}
|
||||
|
||||
$commands = array();
|
||||
@@ -578,6 +680,14 @@ class Application
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->commandLoader) {
|
||||
foreach ($this->commandLoader->getNames() as $name) {
|
||||
if (!isset($commands[$name]) && $namespace === $this->extractNamespace($name, substr_count($namespace, ':') + 1) && $this->has($name)) {
|
||||
$commands[$name] = $this->get($name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $commands;
|
||||
}
|
||||
|
||||
@@ -603,34 +713,40 @@ class Application
|
||||
|
||||
/**
|
||||
* Renders a caught exception.
|
||||
*
|
||||
* @param \Exception $e An exception instance
|
||||
* @param OutputInterface $output An OutputInterface instance
|
||||
*/
|
||||
public function renderException(\Exception $e, OutputInterface $output)
|
||||
{
|
||||
$output->writeln('', OutputInterface::VERBOSITY_QUIET);
|
||||
|
||||
$this->doRenderException($e, $output);
|
||||
|
||||
if (null !== $this->runningCommand) {
|
||||
$output->writeln(sprintf('<info>%s</info>', sprintf($this->runningCommand->getSynopsis(), $this->getName())), OutputInterface::VERBOSITY_QUIET);
|
||||
$output->writeln('', OutputInterface::VERBOSITY_QUIET);
|
||||
}
|
||||
}
|
||||
|
||||
protected function doRenderException(\Exception $e, OutputInterface $output)
|
||||
{
|
||||
do {
|
||||
$title = sprintf(
|
||||
' [%s%s] ',
|
||||
get_class($e),
|
||||
$output->isVerbose() && 0 !== ($code = $e->getCode()) ? ' ('.$code.')' : ''
|
||||
);
|
||||
$message = trim($e->getMessage());
|
||||
if ('' === $message || OutputInterface::VERBOSITY_VERBOSE <= $output->getVerbosity()) {
|
||||
$title = sprintf(' [%s%s] ', get_class($e), 0 !== ($code = $e->getCode()) ? ' ('.$code.')' : '');
|
||||
$len = Helper::strlen($title);
|
||||
} else {
|
||||
$len = 0;
|
||||
}
|
||||
|
||||
$len = $this->stringWidth($title);
|
||||
|
||||
$width = $this->getTerminalWidth() ? $this->getTerminalWidth() - 1 : PHP_INT_MAX;
|
||||
$width = $this->terminal->getWidth() ? $this->terminal->getWidth() - 1 : PHP_INT_MAX;
|
||||
// HHVM only accepts 32 bits integer in str_split, even when PHP_INT_MAX is a 64 bit integer: https://github.com/facebook/hhvm/issues/1327
|
||||
if (defined('HHVM_VERSION') && $width > 1 << 31) {
|
||||
$width = 1 << 31;
|
||||
}
|
||||
$formatter = $output->getFormatter();
|
||||
$lines = array();
|
||||
foreach (preg_split('/\r?\n/', $e->getMessage()) as $line) {
|
||||
foreach ('' !== $message ? preg_split('/\r?\n/', $message) : array() as $line) {
|
||||
foreach ($this->splitStringByWidth($line, $width - 4) as $line) {
|
||||
// pre-format lines to get the right string length
|
||||
$lineLength = $this->stringWidth(preg_replace('/\[[^m]*m/', '', $formatter->format($line))) + 4;
|
||||
$lineLength = Helper::strlen($line) + 4;
|
||||
$lines[] = array($line, $lineLength);
|
||||
|
||||
$len = max($lineLength, $len);
|
||||
@@ -638,27 +754,26 @@ class Application
|
||||
}
|
||||
|
||||
$messages = array();
|
||||
$messages[] = $emptyLine = $formatter->format(sprintf('<error>%s</error>', str_repeat(' ', $len)));
|
||||
$messages[] = $formatter->format(sprintf('<error>%s%s</error>', $title, str_repeat(' ', max(0, $len - $this->stringWidth($title)))));
|
||||
if (!$e instanceof ExceptionInterface || OutputInterface::VERBOSITY_VERBOSE <= $output->getVerbosity()) {
|
||||
$messages[] = sprintf('<comment>%s</comment>', OutputFormatter::escape(sprintf('In %s line %s:', basename($e->getFile()) ?: 'n/a', $e->getLine() ?: 'n/a')));
|
||||
}
|
||||
$messages[] = $emptyLine = sprintf('<error>%s</error>', str_repeat(' ', $len));
|
||||
if ('' === $message || OutputInterface::VERBOSITY_VERBOSE <= $output->getVerbosity()) {
|
||||
$messages[] = sprintf('<error>%s%s</error>', $title, str_repeat(' ', max(0, $len - Helper::strlen($title))));
|
||||
}
|
||||
foreach ($lines as $line) {
|
||||
$messages[] = $formatter->format(sprintf('<error> %s %s</error>', $line[0], str_repeat(' ', $len - $line[1])));
|
||||
$messages[] = sprintf('<error> %s %s</error>', OutputFormatter::escape($line[0]), str_repeat(' ', $len - $line[1]));
|
||||
}
|
||||
$messages[] = $emptyLine;
|
||||
$messages[] = '';
|
||||
|
||||
$output->writeln($messages, OutputInterface::OUTPUT_RAW | OutputInterface::VERBOSITY_QUIET);
|
||||
$output->writeln($messages, OutputInterface::VERBOSITY_QUIET);
|
||||
|
||||
if (OutputInterface::VERBOSITY_VERBOSE <= $output->getVerbosity()) {
|
||||
$output->writeln('<comment>Exception trace:</comment>', OutputInterface::VERBOSITY_QUIET);
|
||||
|
||||
// exception related properties
|
||||
$trace = $e->getTrace();
|
||||
array_unshift($trace, array(
|
||||
'function' => '',
|
||||
'file' => $e->getFile() !== null ? $e->getFile() : 'n/a',
|
||||
'line' => $e->getLine() !== null ? $e->getLine() : 'n/a',
|
||||
'args' => array(),
|
||||
));
|
||||
|
||||
for ($i = 0, $count = count($trace); $i < $count; ++$i) {
|
||||
$class = isset($trace[$i]['class']) ? $trace[$i]['class'] : '';
|
||||
@@ -673,71 +788,48 @@ class Application
|
||||
$output->writeln('', OutputInterface::VERBOSITY_QUIET);
|
||||
}
|
||||
} while ($e = $e->getPrevious());
|
||||
|
||||
if (null !== $this->runningCommand) {
|
||||
$output->writeln(sprintf('<info>%s</info>', sprintf($this->runningCommand->getSynopsis(), $this->getName())), OutputInterface::VERBOSITY_QUIET);
|
||||
$output->writeln('', OutputInterface::VERBOSITY_QUIET);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to figure out the terminal width in which this application runs.
|
||||
*
|
||||
* @return int|null
|
||||
*
|
||||
* @deprecated since version 3.2, to be removed in 4.0. Create a Terminal instance instead.
|
||||
*/
|
||||
protected function getTerminalWidth()
|
||||
{
|
||||
$dimensions = $this->getTerminalDimensions();
|
||||
@trigger_error(sprintf('%s is deprecated as of 3.2 and will be removed in 4.0. Create a Terminal instance instead.', __METHOD__), E_USER_DEPRECATED);
|
||||
|
||||
return $dimensions[0];
|
||||
return $this->terminal->getWidth();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to figure out the terminal height in which this application runs.
|
||||
*
|
||||
* @return int|null
|
||||
*
|
||||
* @deprecated since version 3.2, to be removed in 4.0. Create a Terminal instance instead.
|
||||
*/
|
||||
protected function getTerminalHeight()
|
||||
{
|
||||
$dimensions = $this->getTerminalDimensions();
|
||||
@trigger_error(sprintf('%s is deprecated as of 3.2 and will be removed in 4.0. Create a Terminal instance instead.', __METHOD__), E_USER_DEPRECATED);
|
||||
|
||||
return $dimensions[1];
|
||||
return $this->terminal->getHeight();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to figure out the terminal dimensions based on the current environment.
|
||||
*
|
||||
* @return array Array containing width and height
|
||||
*
|
||||
* @deprecated since version 3.2, to be removed in 4.0. Create a Terminal instance instead.
|
||||
*/
|
||||
public function getTerminalDimensions()
|
||||
{
|
||||
if ($this->terminalDimensions) {
|
||||
return $this->terminalDimensions;
|
||||
}
|
||||
@trigger_error(sprintf('%s is deprecated as of 3.2 and will be removed in 4.0. Create a Terminal instance instead.', __METHOD__), E_USER_DEPRECATED);
|
||||
|
||||
if ('\\' === DIRECTORY_SEPARATOR) {
|
||||
// extract [w, H] from "wxh (WxH)"
|
||||
if (preg_match('/^(\d+)x\d+ \(\d+x(\d+)\)$/', trim(getenv('ANSICON')), $matches)) {
|
||||
return array((int) $matches[1], (int) $matches[2]);
|
||||
}
|
||||
// extract [w, h] from "wxh"
|
||||
if (preg_match('/^(\d+)x(\d+)$/', $this->getConsoleMode(), $matches)) {
|
||||
return array((int) $matches[1], (int) $matches[2]);
|
||||
}
|
||||
}
|
||||
|
||||
if ($sttyString = $this->getSttyColumns()) {
|
||||
// extract [w, h] from "rows h; columns w;"
|
||||
if (preg_match('/rows.(\d+);.columns.(\d+);/i', $sttyString, $matches)) {
|
||||
return array((int) $matches[2], (int) $matches[1]);
|
||||
}
|
||||
// extract [w, h] from "; h rows; w columns"
|
||||
if (preg_match('/;.(\d+).rows;.(\d+).columns/i', $sttyString, $matches)) {
|
||||
return array((int) $matches[2], (int) $matches[1]);
|
||||
}
|
||||
}
|
||||
|
||||
return array(null, null);
|
||||
return array($this->terminal->getWidth(), $this->terminal->getHeight());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -748,20 +840,22 @@ class Application
|
||||
* @param int $width The width
|
||||
* @param int $height The height
|
||||
*
|
||||
* @return Application The current application
|
||||
* @return $this
|
||||
*
|
||||
* @deprecated since version 3.2, to be removed in 4.0. Set the COLUMNS and LINES env vars instead.
|
||||
*/
|
||||
public function setTerminalDimensions($width, $height)
|
||||
{
|
||||
$this->terminalDimensions = array($width, $height);
|
||||
@trigger_error(sprintf('%s is deprecated as of 3.2 and will be removed in 4.0. Set the COLUMNS and LINES env vars instead.', __METHOD__), E_USER_DEPRECATED);
|
||||
|
||||
putenv('COLUMNS='.$width);
|
||||
putenv('LINES='.$height);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures the input and output instances based on the user arguments and options.
|
||||
*
|
||||
* @param InputInterface $input An InputInterface instance
|
||||
* @param OutputInterface $output An OutputInterface instance
|
||||
*/
|
||||
protected function configureIO(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
@@ -773,25 +867,55 @@ class Application
|
||||
|
||||
if (true === $input->hasParameterOption(array('--no-interaction', '-n'), true)) {
|
||||
$input->setInteractive(false);
|
||||
} elseif (function_exists('posix_isatty') && $this->getHelperSet()->has('question')) {
|
||||
$inputStream = $this->getHelperSet()->get('question')->getInputStream();
|
||||
} elseif (function_exists('posix_isatty')) {
|
||||
$inputStream = null;
|
||||
|
||||
if ($input instanceof StreamableInputInterface) {
|
||||
$inputStream = $input->getStream();
|
||||
}
|
||||
|
||||
// This check ensures that calling QuestionHelper::setInputStream() works
|
||||
// To be removed in 4.0 (in the same time as QuestionHelper::setInputStream)
|
||||
if (!$inputStream && $this->getHelperSet()->has('question')) {
|
||||
$inputStream = $this->getHelperSet()->get('question')->getInputStream(false);
|
||||
}
|
||||
|
||||
if (!@posix_isatty($inputStream) && false === getenv('SHELL_INTERACTIVE')) {
|
||||
$input->setInteractive(false);
|
||||
}
|
||||
}
|
||||
|
||||
switch ($shellVerbosity = (int) getenv('SHELL_VERBOSITY')) {
|
||||
case -1: $output->setVerbosity(OutputInterface::VERBOSITY_QUIET); break;
|
||||
case 1: $output->setVerbosity(OutputInterface::VERBOSITY_VERBOSE); break;
|
||||
case 2: $output->setVerbosity(OutputInterface::VERBOSITY_VERY_VERBOSE); break;
|
||||
case 3: $output->setVerbosity(OutputInterface::VERBOSITY_DEBUG); break;
|
||||
default: $shellVerbosity = 0; break;
|
||||
}
|
||||
|
||||
if (true === $input->hasParameterOption(array('--quiet', '-q'), true)) {
|
||||
$output->setVerbosity(OutputInterface::VERBOSITY_QUIET);
|
||||
$input->setInteractive(false);
|
||||
$shellVerbosity = -1;
|
||||
} else {
|
||||
if ($input->hasParameterOption('-vvv', true) || $input->hasParameterOption('--verbose=3', true) || $input->getParameterOption('--verbose', false, true) === 3) {
|
||||
if ($input->hasParameterOption('-vvv', true) || $input->hasParameterOption('--verbose=3', true) || 3 === $input->getParameterOption('--verbose', false, true)) {
|
||||
$output->setVerbosity(OutputInterface::VERBOSITY_DEBUG);
|
||||
} elseif ($input->hasParameterOption('-vv', true) || $input->hasParameterOption('--verbose=2', true) || $input->getParameterOption('--verbose', false, true) === 2) {
|
||||
$shellVerbosity = 3;
|
||||
} elseif ($input->hasParameterOption('-vv', true) || $input->hasParameterOption('--verbose=2', true) || 2 === $input->getParameterOption('--verbose', false, true)) {
|
||||
$output->setVerbosity(OutputInterface::VERBOSITY_VERY_VERBOSE);
|
||||
$shellVerbosity = 2;
|
||||
} elseif ($input->hasParameterOption('-v', true) || $input->hasParameterOption('--verbose=1', true) || $input->hasParameterOption('--verbose', true) || $input->getParameterOption('--verbose', false, true)) {
|
||||
$output->setVerbosity(OutputInterface::VERBOSITY_VERBOSE);
|
||||
$shellVerbosity = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (-1 === $shellVerbosity) {
|
||||
$input->setInteractive(false);
|
||||
}
|
||||
|
||||
putenv('SHELL_VERBOSITY='.$shellVerbosity);
|
||||
$_ENV['SHELL_VERBOSITY'] = $shellVerbosity;
|
||||
$_SERVER['SHELL_VERBOSITY'] = $shellVerbosity;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -800,13 +924,7 @@ class Application
|
||||
* If an event dispatcher has been attached to the application,
|
||||
* events are also dispatched during the life-cycle of the command.
|
||||
*
|
||||
* @param Command $command A Command instance
|
||||
* @param InputInterface $input An Input instance
|
||||
* @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)
|
||||
{
|
||||
@@ -829,50 +947,56 @@ class Application
|
||||
}
|
||||
|
||||
$event = new ConsoleCommandEvent($command, $input, $output);
|
||||
$this->dispatcher->dispatch(ConsoleEvents::COMMAND, $event);
|
||||
$e = null;
|
||||
|
||||
if ($event->commandShouldRun()) {
|
||||
try {
|
||||
$e = null;
|
||||
try {
|
||||
$this->dispatcher->dispatch(ConsoleEvents::COMMAND, $event);
|
||||
|
||||
if ($event->commandShouldRun()) {
|
||||
$exitCode = $command->run($input, $output);
|
||||
} catch (\Exception $x) {
|
||||
$e = $x;
|
||||
} catch (\Throwable $x) {
|
||||
$e = new FatalThrowableError($x);
|
||||
} else {
|
||||
$exitCode = ConsoleCommandEvent::RETURN_CODE_DISABLED;
|
||||
}
|
||||
if (null !== $e) {
|
||||
$event = new ConsoleExceptionEvent($command, $input, $output, $e, $e->getCode());
|
||||
} catch (\Exception $e) {
|
||||
} catch (\Throwable $e) {
|
||||
}
|
||||
if (null !== $e) {
|
||||
if ($this->dispatcher->hasListeners(ConsoleEvents::EXCEPTION)) {
|
||||
$x = $e instanceof \Exception ? $e : new FatalThrowableError($e);
|
||||
$event = new ConsoleExceptionEvent($command, $input, $output, $x, $x->getCode());
|
||||
$this->dispatcher->dispatch(ConsoleEvents::EXCEPTION, $event);
|
||||
|
||||
if ($e !== $event->getException()) {
|
||||
$x = $e = $event->getException();
|
||||
if ($x !== $event->getException()) {
|
||||
$e = $event->getException();
|
||||
}
|
||||
|
||||
$event = new ConsoleTerminateEvent($command, $input, $output, $e->getCode());
|
||||
$this->dispatcher->dispatch(ConsoleEvents::TERMINATE, $event);
|
||||
|
||||
throw $x;
|
||||
}
|
||||
} else {
|
||||
$exitCode = ConsoleCommandEvent::RETURN_CODE_DISABLED;
|
||||
$event = new ConsoleErrorEvent($input, $output, $e, $command);
|
||||
$this->dispatcher->dispatch(ConsoleEvents::ERROR, $event);
|
||||
$e = $event->getError();
|
||||
|
||||
if (0 === $exitCode = $event->getExitCode()) {
|
||||
$e = null;
|
||||
}
|
||||
}
|
||||
|
||||
$event = new ConsoleTerminateEvent($command, $input, $output, $exitCode);
|
||||
$this->dispatcher->dispatch(ConsoleEvents::TERMINATE, $event);
|
||||
|
||||
if (null !== $e) {
|
||||
throw $e;
|
||||
}
|
||||
|
||||
return $event->getExitCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name of the command based on input.
|
||||
*
|
||||
* @param InputInterface $input The input interface
|
||||
*
|
||||
* @return string The command name
|
||||
*/
|
||||
protected function getCommandName(InputInterface $input)
|
||||
{
|
||||
return $input->getFirstArgument();
|
||||
return $this->singleCommand ? $this->defaultCommand : $input->getFirstArgument();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -920,54 +1044,6 @@ class Application
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs and parses stty -a if it's available, suppressing any error output.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function getSttyColumns()
|
||||
{
|
||||
if (!function_exists('proc_open')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$descriptorspec = array(1 => array('pipe', 'w'), 2 => array('pipe', 'w'));
|
||||
$process = proc_open('stty -a | grep columns', $descriptorspec, $pipes, null, null, array('suppress_errors' => true));
|
||||
if (is_resource($process)) {
|
||||
$info = stream_get_contents($pipes[1]);
|
||||
fclose($pipes[1]);
|
||||
fclose($pipes[2]);
|
||||
proc_close($process);
|
||||
|
||||
return $info;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs and parses mode CON if it's available, suppressing any error output.
|
||||
*
|
||||
* @return string|null <width>x<height> or null if it could not be parsed
|
||||
*/
|
||||
private function getConsoleMode()
|
||||
{
|
||||
if (!function_exists('proc_open')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$descriptorspec = array(1 => array('pipe', 'w'), 2 => array('pipe', 'w'));
|
||||
$process = proc_open('mode CON', $descriptorspec, $pipes, null, null, array('suppress_errors' => true));
|
||||
if (is_resource($process)) {
|
||||
$info = stream_get_contents($pipes[1]);
|
||||
fclose($pipes[1]);
|
||||
fclose($pipes[2]);
|
||||
proc_close($process);
|
||||
|
||||
if (preg_match('/--------+\r?\n.+?(\d+)\r?\n.+?(\d+)\r?\n/', $info, $matches)) {
|
||||
return $matches[2].'x'.$matches[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns abbreviated suggestions in string format.
|
||||
*
|
||||
@@ -977,7 +1053,7 @@ class Application
|
||||
*/
|
||||
private function getAbbreviationSuggestions($abbrevs)
|
||||
{
|
||||
return sprintf('%s, %s%s', $abbrevs[0], $abbrevs[1], count($abbrevs) > 2 ? sprintf(' and %d more', count($abbrevs) - 2) : '');
|
||||
return ' '.implode("\n ", $abbrevs);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1002,8 +1078,8 @@ class Application
|
||||
* Finds alternative of $name among $collection,
|
||||
* if nothing is found in $collection, try in $abbrevs.
|
||||
*
|
||||
* @param string $name The string
|
||||
* @param array|\Traversable $collection The collection
|
||||
* @param string $name The string
|
||||
* @param iterable $collection The collection
|
||||
*
|
||||
* @return string[] A sorted array of similar string
|
||||
*/
|
||||
@@ -1044,7 +1120,7 @@ class Application
|
||||
}
|
||||
|
||||
$alternatives = array_filter($alternatives, function ($lev) use ($threshold) { return $lev < 2 * $threshold; });
|
||||
asort($alternatives);
|
||||
ksort($alternatives, SORT_NATURAL | SORT_FLAG_CASE);
|
||||
|
||||
return array_keys($alternatives);
|
||||
}
|
||||
@@ -1052,20 +1128,23 @@ class Application
|
||||
/**
|
||||
* Sets the default Command name.
|
||||
*
|
||||
* @param string $commandName The Command name
|
||||
* @param string $commandName The Command name
|
||||
* @param bool $isSingleCommand Set to true if there is only one command in this application
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setDefaultCommand($commandName)
|
||||
public function setDefaultCommand($commandName, $isSingleCommand = false)
|
||||
{
|
||||
$this->defaultCommand = $commandName;
|
||||
}
|
||||
|
||||
private function stringWidth($string)
|
||||
{
|
||||
if (false === $encoding = mb_detect_encoding($string, null, true)) {
|
||||
return strlen($string);
|
||||
if ($isSingleCommand) {
|
||||
// Ensure the command exist
|
||||
$this->find($commandName);
|
||||
|
||||
$this->singleCommand = true;
|
||||
}
|
||||
|
||||
return mb_strwidth($string, $encoding);
|
||||
return $this;
|
||||
}
|
||||
|
||||
private function splitStringByWidth($string, $width)
|
||||
@@ -1090,9 +1169,8 @@ class Application
|
||||
$lines[] = str_pad($line, $width);
|
||||
$line = $char;
|
||||
}
|
||||
if ('' !== $line) {
|
||||
$lines[] = count($lines) ? str_pad($line, $width) : $line;
|
||||
}
|
||||
|
||||
$lines[] = count($lines) ? str_pad($line, $width) : $line;
|
||||
|
||||
mb_convert_variables($encoding, 'utf8', $lines);
|
||||
|
||||
@@ -1122,4 +1200,16 @@ class Application
|
||||
|
||||
return $namespaces;
|
||||
}
|
||||
|
||||
private function init()
|
||||
{
|
||||
if ($this->initialized) {
|
||||
return;
|
||||
}
|
||||
$this->initialized = true;
|
||||
|
||||
foreach ($this->getDefaultCommands() as $command) {
|
||||
$this->add($command);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
33
lib/composer/vendor/symfony/console/CHANGELOG.md
vendored
33
lib/composer/vendor/symfony/console/CHANGELOG.md
vendored
@@ -1,6 +1,39 @@
|
||||
CHANGELOG
|
||||
=========
|
||||
|
||||
3.4.0
|
||||
-----
|
||||
|
||||
* added `SHELL_VERBOSITY` env var to control verbosity
|
||||
* added `CommandLoaderInterface`, `FactoryCommandLoader` and PSR-11
|
||||
`ContainerCommandLoader` for commands lazy-loading
|
||||
* added a case-insensitive command name matching fallback
|
||||
* added static `Command::$defaultName/getDefaultName()`, allowing for
|
||||
commands to be registered at compile time in the application command loader.
|
||||
Setting the `$defaultName` property avoids the need for filling the `command`
|
||||
attribute on the `console.command` tag when using `AddConsoleCommandPass`.
|
||||
|
||||
3.3.0
|
||||
-----
|
||||
|
||||
* added `ExceptionListener`
|
||||
* added `AddConsoleCommandPass` (originally in FrameworkBundle)
|
||||
* [BC BREAK] `Input::getOption()` no longer returns the default value for options
|
||||
with value optional explicitly passed empty
|
||||
* added console.error event to catch exceptions thrown by other listeners
|
||||
* deprecated console.exception event in favor of console.error
|
||||
* added ability to handle `CommandNotFoundException` through the
|
||||
`console.error` event
|
||||
* deprecated default validation in `SymfonyQuestionHelper::ask`
|
||||
|
||||
3.2.0
|
||||
------
|
||||
|
||||
* added `setInputs()` method to CommandTester for ease testing of commands expecting inputs
|
||||
* added `setStream()` and `getStream()` methods to Input (implement StreamableInputInterface)
|
||||
* added StreamableInputInterface
|
||||
* added LockableTrait
|
||||
|
||||
3.1.0
|
||||
-----
|
||||
|
||||
|
||||
@@ -29,11 +29,17 @@ use Symfony\Component\Console\Exception\LogicException;
|
||||
*/
|
||||
class Command
|
||||
{
|
||||
/**
|
||||
* @var string|null The default command name
|
||||
*/
|
||||
protected static $defaultName;
|
||||
|
||||
private $application;
|
||||
private $name;
|
||||
private $processTitle;
|
||||
private $aliases = array();
|
||||
private $definition;
|
||||
private $hidden = false;
|
||||
private $help;
|
||||
private $description;
|
||||
private $ignoreValidationErrors = false;
|
||||
@@ -45,8 +51,17 @@ class Command
|
||||
private $helperSet;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @return string|null The default command name or null when no default name is set
|
||||
*/
|
||||
public static function getDefaultName()
|
||||
{
|
||||
$class = get_called_class();
|
||||
$r = new \ReflectionProperty($class, 'defaultName');
|
||||
|
||||
return $class === $r->class ? static::$defaultName : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|null $name The name of the command; passing null means it must be set in configure()
|
||||
*
|
||||
* @throws LogicException When the command name is empty
|
||||
@@ -55,15 +70,11 @@ class Command
|
||||
{
|
||||
$this->definition = new InputDefinition();
|
||||
|
||||
if (null !== $name) {
|
||||
if (null !== $name || null !== $name = static::getDefaultName()) {
|
||||
$this->setName($name);
|
||||
}
|
||||
|
||||
$this->configure();
|
||||
|
||||
if (!$this->name) {
|
||||
throw new LogicException(sprintf('The command defined in "%s" cannot have an empty name.', get_class($this)));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -76,11 +87,6 @@ class Command
|
||||
$this->ignoreValidationErrors = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the application instance for this command.
|
||||
*
|
||||
* @param Application $application An Application instance
|
||||
*/
|
||||
public function setApplication(Application $application = null)
|
||||
{
|
||||
$this->application = $application;
|
||||
@@ -91,11 +97,6 @@ class Command
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the helper set.
|
||||
*
|
||||
* @param HelperSet $helperSet A HelperSet instance
|
||||
*/
|
||||
public function setHelperSet(HelperSet $helperSet)
|
||||
{
|
||||
$this->helperSet = $helperSet;
|
||||
@@ -149,9 +150,6 @@ class Command
|
||||
* execute() method, you set the code to execute by passing
|
||||
* a Closure to the setCode() method.
|
||||
*
|
||||
* @param InputInterface $input An InputInterface instance
|
||||
* @param OutputInterface $output An OutputInterface instance
|
||||
*
|
||||
* @return null|int null or 0 if everything went fine, or an error code
|
||||
*
|
||||
* @throws LogicException When this abstract method is not implemented
|
||||
@@ -169,9 +167,6 @@ class Command
|
||||
* This method is executed before the InputDefinition is validated.
|
||||
* This means that this is the only place where the command can
|
||||
* interactively ask for values of missing required arguments.
|
||||
*
|
||||
* @param InputInterface $input An InputInterface instance
|
||||
* @param OutputInterface $output An OutputInterface instance
|
||||
*/
|
||||
protected function interact(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
@@ -182,9 +177,6 @@ class Command
|
||||
*
|
||||
* This is mainly useful when a lot of commands extends one main command
|
||||
* where some things need to be initialized based on the input arguments and options.
|
||||
*
|
||||
* @param InputInterface $input An InputInterface instance
|
||||
* @param OutputInterface $output An OutputInterface instance
|
||||
*/
|
||||
protected function initialize(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
@@ -197,12 +189,9 @@ class Command
|
||||
* setCode() method or by overriding the execute() method
|
||||
* in a sub-class.
|
||||
*
|
||||
* @param InputInterface $input An InputInterface instance
|
||||
* @param OutputInterface $output An OutputInterface instance
|
||||
*
|
||||
* @return int The command exit code
|
||||
*
|
||||
* @throws \Exception
|
||||
* @throws \Exception When binding input fails. Bypass this by calling {@link ignoreValidationErrors()}.
|
||||
*
|
||||
* @see setCode()
|
||||
* @see execute()
|
||||
@@ -229,7 +218,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()) {
|
||||
@@ -267,7 +263,7 @@ class Command
|
||||
*
|
||||
* @param callable $code A callable(InputInterface $input, OutputInterface $output)
|
||||
*
|
||||
* @return Command The current instance
|
||||
* @return $this
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*
|
||||
@@ -278,7 +274,15 @@ class Command
|
||||
if ($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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -319,7 +323,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)
|
||||
{
|
||||
@@ -367,7 +371,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)
|
||||
{
|
||||
@@ -385,7 +389,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)
|
||||
{
|
||||
@@ -404,7 +408,7 @@ class Command
|
||||
*
|
||||
* @param string $name The command name
|
||||
*
|
||||
* @return Command The current instance
|
||||
* @return $this
|
||||
*
|
||||
* @throws InvalidArgumentException When the name is invalid
|
||||
*/
|
||||
@@ -427,7 +431,7 @@ class Command
|
||||
*
|
||||
* @param string $title The process title
|
||||
*
|
||||
* @return Command The current instance
|
||||
* @return $this
|
||||
*/
|
||||
public function setProcessTitle($title)
|
||||
{
|
||||
@@ -446,12 +450,32 @@ class Command
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $hidden Whether or not the command should be hidden from the list of commands
|
||||
*
|
||||
* @return Command The current instance
|
||||
*/
|
||||
public function setHidden($hidden)
|
||||
{
|
||||
$this->hidden = (bool) $hidden;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool whether the command should be publicly shown or not
|
||||
*/
|
||||
public function isHidden()
|
||||
{
|
||||
return $this->hidden;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the description for the command.
|
||||
*
|
||||
* @param string $description The description for the command
|
||||
*
|
||||
* @return Command The current instance
|
||||
* @return $this
|
||||
*/
|
||||
public function setDescription($description)
|
||||
{
|
||||
@@ -475,7 +499,7 @@ class Command
|
||||
*
|
||||
* @param string $help The help for the command
|
||||
*
|
||||
* @return Command The current instance
|
||||
* @return $this
|
||||
*/
|
||||
public function setHelp($help)
|
||||
{
|
||||
@@ -521,7 +545,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
|
||||
*/
|
||||
@@ -573,7 +597,7 @@ class Command
|
||||
*
|
||||
* @param string $usage The usage, it'll be prefixed with the command name
|
||||
*
|
||||
* @return Command The current instance
|
||||
* @return $this
|
||||
*/
|
||||
public function addUsage($usage)
|
||||
{
|
||||
|
||||
@@ -56,11 +56,6 @@ EOF
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the command.
|
||||
*
|
||||
* @param Command $command The command to set
|
||||
*/
|
||||
public function setCommand(Command $command)
|
||||
{
|
||||
$this->command = $command;
|
||||
|
||||
72
lib/composer/vendor/symfony/console/Command/LockableTrait.php
vendored
Normal file
72
lib/composer/vendor/symfony/console/Command/LockableTrait.php
vendored
Normal file
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Console\Command;
|
||||
|
||||
use Symfony\Component\Console\Exception\LogicException;
|
||||
use Symfony\Component\Console\Exception\RuntimeException;
|
||||
use Symfony\Component\Lock\Factory;
|
||||
use Symfony\Component\Lock\Lock;
|
||||
use Symfony\Component\Lock\Store\FlockStore;
|
||||
use Symfony\Component\Lock\Store\SemaphoreStore;
|
||||
|
||||
/**
|
||||
* Basic lock feature for commands.
|
||||
*
|
||||
* @author Geoffrey Brier <geoffrey.brier@gmail.com>
|
||||
*/
|
||||
trait LockableTrait
|
||||
{
|
||||
/** @var Lock */
|
||||
private $lock;
|
||||
|
||||
/**
|
||||
* Locks a command.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function lock($name = null, $blocking = false)
|
||||
{
|
||||
if (!class_exists(SemaphoreStore::class)) {
|
||||
throw new RuntimeException('To enable the locking feature you must install the symfony/lock component.');
|
||||
}
|
||||
|
||||
if (null !== $this->lock) {
|
||||
throw new LogicException('A lock is already in place.');
|
||||
}
|
||||
|
||||
if (SemaphoreStore::isSupported($blocking)) {
|
||||
$store = new SemaphoreStore();
|
||||
} else {
|
||||
$store = new FlockStore();
|
||||
}
|
||||
|
||||
$this->lock = (new Factory($store))->createLock($name ?: $this->getName());
|
||||
if (!$this->lock->acquire($blocking)) {
|
||||
$this->lock = null;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Releases the command lock if there is one.
|
||||
*/
|
||||
private function release()
|
||||
{
|
||||
if ($this->lock) {
|
||||
$this->lock->release();
|
||||
$this->lock = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
37
lib/composer/vendor/symfony/console/CommandLoader/CommandLoaderInterface.php
vendored
Normal file
37
lib/composer/vendor/symfony/console/CommandLoader/CommandLoaderInterface.php
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
namespace Symfony\Component\Console\CommandLoader;
|
||||
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Exception\CommandNotFoundException;
|
||||
|
||||
/**
|
||||
* @author Robin Chalas <robin.chalas@gmail.com>
|
||||
*/
|
||||
interface CommandLoaderInterface
|
||||
{
|
||||
/**
|
||||
* Loads a command.
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return Command
|
||||
*
|
||||
* @throws CommandNotFoundException
|
||||
*/
|
||||
public function get($name);
|
||||
|
||||
/**
|
||||
* Checks if a command exists.
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function has($name);
|
||||
|
||||
/**
|
||||
* @return string[] All registered command names
|
||||
*/
|
||||
public function getNames();
|
||||
}
|
||||
55
lib/composer/vendor/symfony/console/CommandLoader/ContainerCommandLoader.php
vendored
Normal file
55
lib/composer/vendor/symfony/console/CommandLoader/ContainerCommandLoader.php
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
namespace Symfony\Component\Console\CommandLoader;
|
||||
|
||||
use Psr\Container\ContainerInterface;
|
||||
use Symfony\Component\Console\Exception\CommandNotFoundException;
|
||||
|
||||
/**
|
||||
* Loads commands from a PSR-11 container.
|
||||
*
|
||||
* @author Robin Chalas <robin.chalas@gmail.com>
|
||||
*/
|
||||
class ContainerCommandLoader implements CommandLoaderInterface
|
||||
{
|
||||
private $container;
|
||||
private $commandMap;
|
||||
|
||||
/**
|
||||
* @param ContainerInterface $container A container from which to load command services
|
||||
* @param array $commandMap An array with command names as keys and service ids as values
|
||||
*/
|
||||
public function __construct(ContainerInterface $container, array $commandMap)
|
||||
{
|
||||
$this->container = $container;
|
||||
$this->commandMap = $commandMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function get($name)
|
||||
{
|
||||
if (!$this->has($name)) {
|
||||
throw new CommandNotFoundException(sprintf('Command "%s" does not exist.', $name));
|
||||
}
|
||||
|
||||
return $this->container->get($this->commandMap[$name]);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function has($name)
|
||||
{
|
||||
return isset($this->commandMap[$name]) && $this->container->has($this->commandMap[$name]);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getNames()
|
||||
{
|
||||
return array_keys($this->commandMap);
|
||||
}
|
||||
}
|
||||
62
lib/composer/vendor/symfony/console/CommandLoader/FactoryCommandLoader.php
vendored
Normal file
62
lib/composer/vendor/symfony/console/CommandLoader/FactoryCommandLoader.php
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Console\CommandLoader;
|
||||
|
||||
use Symfony\Component\Console\Exception\CommandNotFoundException;
|
||||
|
||||
/**
|
||||
* A simple command loader using factories to instantiate commands lazily.
|
||||
*
|
||||
* @author Maxime Steinhausser <maxime.steinhausser@gmail.com>
|
||||
*/
|
||||
class FactoryCommandLoader implements CommandLoaderInterface
|
||||
{
|
||||
private $factories;
|
||||
|
||||
/**
|
||||
* @param callable[] $factories Indexed by command names
|
||||
*/
|
||||
public function __construct(array $factories)
|
||||
{
|
||||
$this->factories = $factories;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function has($name)
|
||||
{
|
||||
return isset($this->factories[$name]);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function get($name)
|
||||
{
|
||||
if (!isset($this->factories[$name])) {
|
||||
throw new CommandNotFoundException(sprintf('Command "%s" does not exist.', $name));
|
||||
}
|
||||
|
||||
$factory = $this->factories[$name];
|
||||
|
||||
return $factory();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getNames()
|
||||
{
|
||||
return array_keys($this->factories);
|
||||
}
|
||||
}
|
||||
@@ -24,8 +24,6 @@ final class ConsoleEvents
|
||||
* before they are handled to the command.
|
||||
*
|
||||
* @Event("Symfony\Component\Console\Event\ConsoleCommandEvent")
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const COMMAND = 'console.command';
|
||||
|
||||
@@ -34,20 +32,29 @@ final class ConsoleEvents
|
||||
* executed by the console.
|
||||
*
|
||||
* @Event("Symfony\Component\Console\Event\ConsoleTerminateEvent")
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const TERMINATE = 'console.terminate';
|
||||
|
||||
/**
|
||||
* The EXCEPTION event occurs when an uncaught exception appears.
|
||||
* The EXCEPTION event occurs when an uncaught exception appears
|
||||
* while executing Command#run().
|
||||
*
|
||||
* This event allows you to deal with the exception or
|
||||
* to modify the thrown exception.
|
||||
*
|
||||
* @Event("Symfony\Component\Console\Event\ConsoleExceptionEvent")
|
||||
*
|
||||
* @var string
|
||||
* @deprecated The console.exception event is deprecated since version 3.3 and will be removed in 4.0. Use the console.error event instead.
|
||||
*/
|
||||
const EXCEPTION = 'console.exception';
|
||||
|
||||
/**
|
||||
* The ERROR event occurs when an uncaught exception or error appears.
|
||||
*
|
||||
* This event allows you to deal with the exception/error or
|
||||
* to modify the thrown exception.
|
||||
*
|
||||
* @Event("Symfony\Component\Console\Event\ConsoleErrorEvent")
|
||||
*/
|
||||
const ERROR = 'console.error';
|
||||
}
|
||||
|
||||
106
lib/composer/vendor/symfony/console/DependencyInjection/AddConsoleCommandPass.php
vendored
Normal file
106
lib/composer/vendor/symfony/console/DependencyInjection/AddConsoleCommandPass.php
vendored
Normal file
@@ -0,0 +1,106 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Console\DependencyInjection;
|
||||
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\CommandLoader\ContainerCommandLoader;
|
||||
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
|
||||
use Symfony\Component\DependencyInjection\Compiler\ServiceLocatorTagPass;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\DependencyInjection\TypedReference;
|
||||
|
||||
/**
|
||||
* Registers console commands.
|
||||
*
|
||||
* @author Grégoire Pineau <lyrixx@lyrixx.info>
|
||||
*/
|
||||
class AddConsoleCommandPass implements CompilerPassInterface
|
||||
{
|
||||
private $commandLoaderServiceId;
|
||||
private $commandTag;
|
||||
|
||||
public function __construct($commandLoaderServiceId = 'console.command_loader', $commandTag = 'console.command')
|
||||
{
|
||||
$this->commandLoaderServiceId = $commandLoaderServiceId;
|
||||
$this->commandTag = $commandTag;
|
||||
}
|
||||
|
||||
public function process(ContainerBuilder $container)
|
||||
{
|
||||
$commandServices = $container->findTaggedServiceIds($this->commandTag, true);
|
||||
$lazyCommandMap = array();
|
||||
$lazyCommandRefs = array();
|
||||
$serviceIds = array();
|
||||
$lazyServiceIds = array();
|
||||
|
||||
foreach ($commandServices as $id => $tags) {
|
||||
$definition = $container->getDefinition($id);
|
||||
$class = $container->getParameterBag()->resolveValue($definition->getClass());
|
||||
|
||||
$commandId = 'console.command.'.strtolower(str_replace('\\', '_', $class));
|
||||
|
||||
if (isset($tags[0]['command'])) {
|
||||
$commandName = $tags[0]['command'];
|
||||
} else {
|
||||
if (!$r = $container->getReflectionClass($class)) {
|
||||
throw new InvalidArgumentException(sprintf('Class "%s" used for service "%s" cannot be found.', $class, $id));
|
||||
}
|
||||
if (!$r->isSubclassOf(Command::class)) {
|
||||
throw new InvalidArgumentException(sprintf('The service "%s" tagged "%s" must be a subclass of "%s".', $id, $this->commandTag, Command::class));
|
||||
}
|
||||
$commandName = $class::getDefaultName();
|
||||
}
|
||||
|
||||
if (null === $commandName) {
|
||||
if (isset($serviceIds[$commandId]) || $container->hasAlias($commandId)) {
|
||||
$commandId = $commandId.'_'.$id;
|
||||
}
|
||||
if (!$definition->isPublic() || $definition->isPrivate()) {
|
||||
$container->setAlias($commandId, $id)->setPublic(true);
|
||||
$id = $commandId;
|
||||
}
|
||||
$serviceIds[$commandId] = $id;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
$serviceIds[$commandId] = $id;
|
||||
$lazyServiceIds[$id] = true;
|
||||
unset($tags[0]);
|
||||
$lazyCommandMap[$commandName] = $id;
|
||||
$lazyCommandRefs[$id] = new TypedReference($id, $class);
|
||||
$aliases = array();
|
||||
|
||||
foreach ($tags as $tag) {
|
||||
if (isset($tag['command'])) {
|
||||
$aliases[] = $tag['command'];
|
||||
$lazyCommandMap[$tag['command']] = $id;
|
||||
}
|
||||
}
|
||||
|
||||
$definition->addMethodCall('setName', array($commandName));
|
||||
|
||||
if ($aliases) {
|
||||
$definition->addMethodCall('setAliases', array($aliases));
|
||||
}
|
||||
}
|
||||
|
||||
$container
|
||||
->register($this->commandLoaderServiceId, ContainerCommandLoader::class)
|
||||
->setPublic(true)
|
||||
->setArguments(array(ServiceLocatorTagPass::register($container, $lazyCommandRefs), $lazyCommandMap));
|
||||
|
||||
$container->setParameter('console.command.ids', $serviceIds);
|
||||
$container->setParameter('console.lazy_command.ids', $lazyServiceIds);
|
||||
}
|
||||
}
|
||||
@@ -24,15 +24,9 @@ class ApplicationDescription
|
||||
{
|
||||
const GLOBAL_NAMESPACE = '_global';
|
||||
|
||||
/**
|
||||
* @var Application
|
||||
*/
|
||||
private $application;
|
||||
|
||||
/**
|
||||
* @var null|string
|
||||
*/
|
||||
private $namespace;
|
||||
private $showHidden;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
@@ -50,15 +44,15 @@ class ApplicationDescription
|
||||
private $aliases;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param Application $application
|
||||
* @param string|null $namespace
|
||||
* @param bool $showHidden
|
||||
*/
|
||||
public function __construct(Application $application, $namespace = null)
|
||||
public function __construct(Application $application, $namespace = null, $showHidden = false)
|
||||
{
|
||||
$this->application = $application;
|
||||
$this->namespace = $namespace;
|
||||
$this->showHidden = $showHidden;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -112,7 +106,7 @@ class ApplicationDescription
|
||||
|
||||
/** @var Command $command */
|
||||
foreach ($commands as $name => $command) {
|
||||
if (!$command->getName()) {
|
||||
if (!$command->getName() || (!$this->showHidden && $command->isHidden())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -130,8 +124,6 @@ class ApplicationDescription
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $commands
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function sortCommands(array $commands)
|
||||
|
||||
@@ -73,9 +73,6 @@ abstract class Descriptor implements DescriptorInterface
|
||||
/**
|
||||
* Describes an InputArgument instance.
|
||||
*
|
||||
* @param InputArgument $argument
|
||||
* @param array $options
|
||||
*
|
||||
* @return string|mixed
|
||||
*/
|
||||
abstract protected function describeInputArgument(InputArgument $argument, array $options = array());
|
||||
@@ -83,9 +80,6 @@ abstract class Descriptor implements DescriptorInterface
|
||||
/**
|
||||
* Describes an InputOption instance.
|
||||
*
|
||||
* @param InputOption $option
|
||||
* @param array $options
|
||||
*
|
||||
* @return string|mixed
|
||||
*/
|
||||
abstract protected function describeInputOption(InputOption $option, array $options = array());
|
||||
@@ -93,9 +87,6 @@ abstract class Descriptor implements DescriptorInterface
|
||||
/**
|
||||
* Describes an InputDefinition instance.
|
||||
*
|
||||
* @param InputDefinition $definition
|
||||
* @param array $options
|
||||
*
|
||||
* @return string|mixed
|
||||
*/
|
||||
abstract protected function describeInputDefinition(InputDefinition $definition, array $options = array());
|
||||
@@ -103,9 +94,6 @@ abstract class Descriptor implements DescriptorInterface
|
||||
/**
|
||||
* Describes a Command instance.
|
||||
*
|
||||
* @param Command $command
|
||||
* @param array $options
|
||||
*
|
||||
* @return string|mixed
|
||||
*/
|
||||
abstract protected function describeCommand(Command $command, array $options = array());
|
||||
@@ -113,9 +101,6 @@ abstract class Descriptor implements DescriptorInterface
|
||||
/**
|
||||
* Describes an Application instance.
|
||||
*
|
||||
* @param Application $application
|
||||
* @param array $options
|
||||
*
|
||||
* @return string|mixed
|
||||
*/
|
||||
abstract protected function describeApplication(Application $application, array $options = array());
|
||||
|
||||
@@ -64,16 +64,28 @@ class JsonDescriptor extends Descriptor
|
||||
protected function describeApplication(Application $application, array $options = array())
|
||||
{
|
||||
$describedNamespace = isset($options['namespace']) ? $options['namespace'] : null;
|
||||
$description = new ApplicationDescription($application, $describedNamespace);
|
||||
$description = new ApplicationDescription($application, $describedNamespace, true);
|
||||
$commands = array();
|
||||
|
||||
foreach ($description->getCommands() as $command) {
|
||||
$commands[] = $this->getCommandData($command);
|
||||
}
|
||||
|
||||
$data = $describedNamespace
|
||||
? array('commands' => $commands, 'namespace' => $describedNamespace)
|
||||
: array('commands' => $commands, 'namespaces' => array_values($description->getNamespaces()));
|
||||
$data = array();
|
||||
if ('UNKNOWN' !== $application->getName()) {
|
||||
$data['application']['name'] = $application->getName();
|
||||
if ('UNKNOWN' !== $application->getVersion()) {
|
||||
$data['application']['version'] = $application->getVersion();
|
||||
}
|
||||
}
|
||||
|
||||
$data['commands'] = $commands;
|
||||
|
||||
if ($describedNamespace) {
|
||||
$data['namespace'] = $describedNamespace;
|
||||
} else {
|
||||
$data['namespaces'] = array_values($description->getNamespaces());
|
||||
}
|
||||
|
||||
$this->writeData($data, $options);
|
||||
}
|
||||
@@ -81,9 +93,6 @@ class JsonDescriptor extends Descriptor
|
||||
/**
|
||||
* Writes data as json.
|
||||
*
|
||||
* @param array $data
|
||||
* @param array $options
|
||||
*
|
||||
* @return array|string
|
||||
*/
|
||||
private function writeData(array $data, array $options)
|
||||
@@ -92,8 +101,6 @@ class JsonDescriptor extends Descriptor
|
||||
}
|
||||
|
||||
/**
|
||||
* @param InputArgument $argument
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function getInputArgumentData(InputArgument $argument)
|
||||
@@ -103,13 +110,11 @@ class JsonDescriptor extends Descriptor
|
||||
'is_required' => $argument->isRequired(),
|
||||
'is_array' => $argument->isArray(),
|
||||
'description' => preg_replace('/\s*[\r\n]\s*/', ' ', $argument->getDescription()),
|
||||
'default' => $argument->getDefault(),
|
||||
'default' => INF === $argument->getDefault() ? 'INF' : $argument->getDefault(),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param InputOption $option
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function getInputOptionData(InputOption $option)
|
||||
@@ -121,13 +126,11 @@ class JsonDescriptor extends Descriptor
|
||||
'is_value_required' => $option->isValueRequired(),
|
||||
'is_multiple' => $option->isArray(),
|
||||
'description' => preg_replace('/\s*[\r\n]\s*/', ' ', $option->getDescription()),
|
||||
'default' => $option->getDefault(),
|
||||
'default' => INF === $option->getDefault() ? 'INF' : $option->getDefault(),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param InputDefinition $definition
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function getInputDefinitionData(InputDefinition $definition)
|
||||
@@ -146,8 +149,6 @@ class JsonDescriptor extends Descriptor
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Command $command
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function getCommandData(Command $command)
|
||||
@@ -161,6 +162,7 @@ class JsonDescriptor extends Descriptor
|
||||
'description' => $command->getDescription(),
|
||||
'help' => $command->getProcessedHelp(),
|
||||
'definition' => $this->getInputDefinitionData($command->getNativeDefinition()),
|
||||
'hidden' => $command->isHidden(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,9 +13,11 @@ 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;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
/**
|
||||
* Markdown descriptor.
|
||||
@@ -26,17 +28,37 @@ use Symfony\Component\Console\Input\InputOption;
|
||||
*/
|
||||
class MarkdownDescriptor extends Descriptor
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function describe(OutputInterface $output, $object, array $options = array())
|
||||
{
|
||||
$decorated = $output->isDecorated();
|
||||
$output->setDecorated(false);
|
||||
|
||||
parent::describe($output, $object, $options);
|
||||
|
||||
$output->setDecorated($decorated);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function write($content, $decorated = true)
|
||||
{
|
||||
parent::write($content, $decorated);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function describeInputArgument(InputArgument $argument, array $options = array())
|
||||
{
|
||||
$this->write(
|
||||
'**'.$argument->getName().':**'."\n\n"
|
||||
.'* Name: '.($argument->getName() ?: '<none>')."\n"
|
||||
'#### `'.($argument->getName() ?: '<none>')."`\n\n"
|
||||
.($argument->getDescription() ? preg_replace('/\s*[\r\n]\s*/', "\n", $argument->getDescription())."\n\n" : '')
|
||||
.'* Is required: '.($argument->isRequired() ? 'yes' : 'no')."\n"
|
||||
.'* Is array: '.($argument->isArray() ? 'yes' : 'no')."\n"
|
||||
.'* Description: '.preg_replace('/\s*[\r\n]\s*/', "\n ", $argument->getDescription() ?: '<none>')."\n"
|
||||
.'* Default: `'.str_replace("\n", '', var_export($argument->getDefault(), true)).'`'
|
||||
);
|
||||
}
|
||||
@@ -46,14 +68,17 @@ class MarkdownDescriptor extends Descriptor
|
||||
*/
|
||||
protected function describeInputOption(InputOption $option, array $options = array())
|
||||
{
|
||||
$name = '--'.$option->getName();
|
||||
if ($option->getShortcut()) {
|
||||
$name .= '|-'.implode('|-', explode('|', $option->getShortcut())).'';
|
||||
}
|
||||
|
||||
$this->write(
|
||||
'**'.$option->getName().':**'."\n\n"
|
||||
.'* Name: `--'.$option->getName().'`'."\n"
|
||||
.'* Shortcut: '.($option->getShortcut() ? '`-'.implode('|-', explode('|', $option->getShortcut())).'`' : '<none>')."\n"
|
||||
'#### `'.$name.'`'."\n\n"
|
||||
.($option->getDescription() ? preg_replace('/\s*[\r\n]\s*/', "\n", $option->getDescription())."\n\n" : '')
|
||||
.'* Accept value: '.($option->acceptValue() ? 'yes' : 'no')."\n"
|
||||
.'* Is value required: '.($option->isValueRequired() ? 'yes' : 'no')."\n"
|
||||
.'* Is multiple: '.($option->isArray() ? 'yes' : 'no')."\n"
|
||||
.'* Description: '.preg_replace('/\s*[\r\n]\s*/', "\n ", $option->getDescription() ?: '<none>')."\n"
|
||||
.'* Default: `'.str_replace("\n", '', var_export($option->getDefault(), true)).'`'
|
||||
);
|
||||
}
|
||||
@@ -64,7 +89,7 @@ class MarkdownDescriptor extends Descriptor
|
||||
protected function describeInputDefinition(InputDefinition $definition, array $options = array())
|
||||
{
|
||||
if ($showArguments = count($definition->getArguments()) > 0) {
|
||||
$this->write('### Arguments:');
|
||||
$this->write('### Arguments');
|
||||
foreach ($definition->getArguments() as $argument) {
|
||||
$this->write("\n\n");
|
||||
$this->write($this->describeInputArgument($argument));
|
||||
@@ -76,7 +101,7 @@ class MarkdownDescriptor extends Descriptor
|
||||
$this->write("\n\n");
|
||||
}
|
||||
|
||||
$this->write('### Options:');
|
||||
$this->write('### Options');
|
||||
foreach ($definition->getOptions() as $option) {
|
||||
$this->write("\n\n");
|
||||
$this->write($this->describeInputOption($option));
|
||||
@@ -93,12 +118,12 @@ class MarkdownDescriptor extends Descriptor
|
||||
$command->mergeApplicationDefinition(false);
|
||||
|
||||
$this->write(
|
||||
$command->getName()."\n"
|
||||
.str_repeat('-', strlen($command->getName()))."\n\n"
|
||||
.'* Description: '.($command->getDescription() ?: '<none>')."\n"
|
||||
.'* Usage:'."\n\n"
|
||||
'`'.$command->getName()."`\n"
|
||||
.str_repeat('-', Helper::strlen($command->getName()) + 2)."\n\n"
|
||||
.($command->getDescription() ? $command->getDescription()."\n\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";
|
||||
})
|
||||
);
|
||||
|
||||
@@ -120,8 +145,9 @@ class MarkdownDescriptor extends Descriptor
|
||||
{
|
||||
$describedNamespace = isset($options['namespace']) ? $options['namespace'] : null;
|
||||
$description = new ApplicationDescription($application, $describedNamespace);
|
||||
$title = $this->getApplicationTitle($application);
|
||||
|
||||
$this->write($application->getName()."\n".str_repeat('=', strlen($application->getName())));
|
||||
$this->write($title."\n".str_repeat('=', Helper::strlen($title)));
|
||||
|
||||
foreach ($description->getNamespaces() as $namespace) {
|
||||
if (ApplicationDescription::GLOBAL_NAMESPACE !== $namespace['id']) {
|
||||
@@ -130,8 +156,8 @@ class MarkdownDescriptor extends Descriptor
|
||||
}
|
||||
|
||||
$this->write("\n\n");
|
||||
$this->write(implode("\n", array_map(function ($commandName) {
|
||||
return '* '.$commandName;
|
||||
$this->write(implode("\n", array_map(function ($commandName) use ($description) {
|
||||
return sprintf('* [`%s`](#%s)', $commandName, str_replace(':', '', $description->getCommand($commandName)->getName()));
|
||||
}, $namespace['commands'])));
|
||||
}
|
||||
|
||||
@@ -140,4 +166,17 @@ class MarkdownDescriptor extends Descriptor
|
||||
$this->write($this->describeCommand($command));
|
||||
}
|
||||
}
|
||||
|
||||
private function getApplicationTitle(Application $application)
|
||||
{
|
||||
if ('UNKNOWN' !== $application->getName()) {
|
||||
if ('UNKNOWN' !== $application->getVersion()) {
|
||||
return sprintf('%s %s', $application->getName(), $application->getVersion());
|
||||
}
|
||||
|
||||
return $application->getName();
|
||||
}
|
||||
|
||||
return 'Console Tool';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()) {
|
||||
@@ -141,7 +143,7 @@ class TextDescriptor extends Descriptor
|
||||
$this->writeText('<comment>Usage:</comment>', $options);
|
||||
foreach (array_merge(array($command->getSynopsis(true)), $command->getAliases(), $command->getUsages()) as $usage) {
|
||||
$this->writeText("\n");
|
||||
$this->writeText(' '.$usage, $options);
|
||||
$this->writeText(' '.OutputFormatter::escape($usage), $options);
|
||||
}
|
||||
$this->writeText("\n");
|
||||
|
||||
@@ -189,7 +191,20 @@ class TextDescriptor extends Descriptor
|
||||
$this->writeText("\n");
|
||||
$this->writeText("\n");
|
||||
|
||||
$width = $this->getColumnWidth($description->getCommands());
|
||||
$commands = $description->getCommands();
|
||||
$namespaces = $description->getNamespaces();
|
||||
if ($describedNamespace && $namespaces) {
|
||||
// make sure all alias commands are included when describing a specific namespace
|
||||
$describedNamespaceInfo = reset($namespaces);
|
||||
foreach ($describedNamespaceInfo['commands'] as $name) {
|
||||
$commands[$name] = $description->getCommand($name);
|
||||
}
|
||||
}
|
||||
|
||||
// calculate max. width based on available commands per namespace
|
||||
$width = $this->getColumnWidth(call_user_func_array('array_merge', array_map(function ($namespace) use ($commands) {
|
||||
return array_intersect($namespace['commands'], array_keys($commands));
|
||||
}, $namespaces)));
|
||||
|
||||
if ($describedNamespace) {
|
||||
$this->writeText(sprintf('<comment>Available commands for the "%s" namespace:</comment>', $describedNamespace), $options);
|
||||
@@ -197,8 +212,15 @@ class TextDescriptor extends Descriptor
|
||||
$this->writeText('<comment>Available commands:</comment>', $options);
|
||||
}
|
||||
|
||||
// add commands by namespace
|
||||
foreach ($description->getNamespaces() as $namespace) {
|
||||
foreach ($namespaces as $namespace) {
|
||||
$namespace['commands'] = array_filter($namespace['commands'], function ($name) use ($commands) {
|
||||
return isset($commands[$name]);
|
||||
});
|
||||
|
||||
if (!$namespace['commands']) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!$describedNamespace && ApplicationDescription::GLOBAL_NAMESPACE !== $namespace['id']) {
|
||||
$this->writeText("\n");
|
||||
$this->writeText(' <comment>'.$namespace['id'].'</comment>', $options);
|
||||
@@ -206,8 +228,10 @@ class TextDescriptor extends Descriptor
|
||||
|
||||
foreach ($namespace['commands'] as $name) {
|
||||
$this->writeText("\n");
|
||||
$spacingWidth = $width - strlen($name);
|
||||
$this->writeText(sprintf(' <info>%s</info>%s%s', $name, str_repeat(' ', $spacingWidth), $description->getCommand($name)->getDescription()), $options);
|
||||
$spacingWidth = $width - Helper::strlen($name);
|
||||
$command = $commands[$name];
|
||||
$commandAliases = $name === $command->getName() ? $this->getCommandAliasesText($command) : '';
|
||||
$this->writeText(sprintf(' <info>%s</info>%s%s', $name, str_repeat(' ', $spacingWidth), $commandAliases.$command->getDescription()), $options);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -226,6 +250,23 @@ class TextDescriptor extends Descriptor
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats command aliases to show them in the command description.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function getCommandAliasesText(Command $command)
|
||||
{
|
||||
$text = '';
|
||||
$aliases = $command->getAliases();
|
||||
|
||||
if ($aliases) {
|
||||
$text = '['.implode('|', $aliases).'] ';
|
||||
}
|
||||
|
||||
return $text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats input option/argument default value.
|
||||
*
|
||||
@@ -235,11 +276,25 @@ class TextDescriptor extends Descriptor
|
||||
*/
|
||||
private function formatDefaultValue($default)
|
||||
{
|
||||
if (INF === $default) {
|
||||
return 'INF';
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return str_replace('\\\\', '\\', json_encode($default, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Command[] $commands
|
||||
* @param (Command|string)[] $commands
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
@@ -248,13 +303,17 @@ class TextDescriptor extends Descriptor
|
||||
$widths = array();
|
||||
|
||||
foreach ($commands as $command) {
|
||||
$widths[] = strlen($command->getName());
|
||||
foreach ($command->getAliases() as $alias) {
|
||||
$widths[] = strlen($alias);
|
||||
if ($command instanceof Command) {
|
||||
$widths[] = Helper::strlen($command->getName());
|
||||
foreach ($command->getAliases() as $alias) {
|
||||
$widths[] = Helper::strlen($alias);
|
||||
}
|
||||
} else {
|
||||
$widths[] = Helper::strlen($command);
|
||||
}
|
||||
}
|
||||
|
||||
return max($widths) + 2;
|
||||
return $widths ? max($widths) + 2 : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -262,15 +321,15 @@ class TextDescriptor extends Descriptor
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
private function calculateTotalWidthForOptions($options)
|
||||
private function calculateTotalWidthForOptions(array $options)
|
||||
{
|
||||
$totalWidth = 0;
|
||||
foreach ($options as $option) {
|
||||
// "-" + shortcut + ", --" + name
|
||||
$nameLength = 1 + max(strlen($option->getShortcut()), 1) + 4 + strlen($option->getName());
|
||||
$nameLength = 1 + max(Helper::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;
|
||||
|
||||
@@ -27,8 +27,6 @@ use Symfony\Component\Console\Input\InputOption;
|
||||
class XmlDescriptor extends Descriptor
|
||||
{
|
||||
/**
|
||||
* @param InputDefinition $definition
|
||||
*
|
||||
* @return \DOMDocument
|
||||
*/
|
||||
public function getInputDefinitionDocument(InputDefinition $definition)
|
||||
@@ -50,8 +48,6 @@ class XmlDescriptor extends Descriptor
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Command $command
|
||||
*
|
||||
* @return \DOMDocument
|
||||
*/
|
||||
public function getCommandDocument(Command $command)
|
||||
@@ -64,6 +60,7 @@ class XmlDescriptor extends Descriptor
|
||||
|
||||
$commandXML->setAttribute('id', $command->getName());
|
||||
$commandXML->setAttribute('name', $command->getName());
|
||||
$commandXML->setAttribute('hidden', $command->isHidden() ? 1 : 0);
|
||||
|
||||
$commandXML->appendChild($usagesXML = $dom->createElement('usages'));
|
||||
|
||||
@@ -94,16 +91,16 @@ class XmlDescriptor extends Descriptor
|
||||
$dom = new \DOMDocument('1.0', 'UTF-8');
|
||||
$dom->appendChild($rootXml = $dom->createElement('symfony'));
|
||||
|
||||
if ($application->getName() !== 'UNKNOWN') {
|
||||
if ('UNKNOWN' !== $application->getName()) {
|
||||
$rootXml->setAttribute('name', $application->getName());
|
||||
if ($application->getVersion() !== 'UNKNOWN') {
|
||||
if ('UNKNOWN' !== $application->getVersion()) {
|
||||
$rootXml->setAttribute('version', $application->getVersion());
|
||||
}
|
||||
}
|
||||
|
||||
$rootXml->appendChild($commandsXML = $dom->createElement('commands'));
|
||||
|
||||
$description = new ApplicationDescription($application, $namespace);
|
||||
$description = new ApplicationDescription($application, $namespace, true);
|
||||
|
||||
if ($namespace) {
|
||||
$commandsXML->setAttribute('namespace', $namespace);
|
||||
@@ -172,9 +169,6 @@ class XmlDescriptor extends Descriptor
|
||||
|
||||
/**
|
||||
* Appends document children to parent node.
|
||||
*
|
||||
* @param \DOMNode $parentNode
|
||||
* @param \DOMNode $importedParent
|
||||
*/
|
||||
private function appendDocument(\DOMNode $parentNode, \DOMNode $importedParent)
|
||||
{
|
||||
@@ -186,8 +180,6 @@ class XmlDescriptor extends Descriptor
|
||||
/**
|
||||
* Writes DOM document.
|
||||
*
|
||||
* @param \DOMDocument $dom
|
||||
*
|
||||
* @return \DOMDocument|string
|
||||
*/
|
||||
private function writeDocument(\DOMDocument $dom)
|
||||
@@ -197,8 +189,6 @@ class XmlDescriptor extends Descriptor
|
||||
}
|
||||
|
||||
/**
|
||||
* @param InputArgument $argument
|
||||
*
|
||||
* @return \DOMDocument
|
||||
*/
|
||||
private function getInputArgumentDocument(InputArgument $argument)
|
||||
@@ -223,8 +213,6 @@ class XmlDescriptor extends Descriptor
|
||||
}
|
||||
|
||||
/**
|
||||
* @param InputOption $option
|
||||
*
|
||||
* @return \DOMDocument
|
||||
*/
|
||||
private function getInputOptionDocument(InputOption $option)
|
||||
|
||||
@@ -25,8 +25,6 @@ class ConsoleCommandEvent extends ConsoleEvent
|
||||
|
||||
/**
|
||||
* Indicates if the command should be run or skipped.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $commandShouldRun = true;
|
||||
|
||||
|
||||
83
lib/composer/vendor/symfony/console/Event/ConsoleErrorEvent.php
vendored
Normal file
83
lib/composer/vendor/symfony/console/Event/ConsoleErrorEvent.php
vendored
Normal file
@@ -0,0 +1,83 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Console\Event;
|
||||
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
/**
|
||||
* Allows to handle throwables thrown while running a command.
|
||||
*
|
||||
* @author Wouter de Jong <wouter@wouterj.nl>
|
||||
*/
|
||||
final class ConsoleErrorEvent extends ConsoleEvent
|
||||
{
|
||||
private $error;
|
||||
private $exitCode;
|
||||
|
||||
public function __construct(InputInterface $input, OutputInterface $output, $error, Command $command = null)
|
||||
{
|
||||
parent::__construct($command, $input, $output);
|
||||
|
||||
$this->setError($error);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the thrown error/exception.
|
||||
*
|
||||
* @return \Throwable
|
||||
*/
|
||||
public function getError()
|
||||
{
|
||||
return $this->error;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces the thrown error/exception.
|
||||
*
|
||||
* @param \Throwable $error
|
||||
*/
|
||||
public function setError($error)
|
||||
{
|
||||
if (!$error instanceof \Throwable && !$error instanceof \Exception) {
|
||||
throw new InvalidArgumentException(sprintf('The error passed to ConsoleErrorEvent must be an instance of \Throwable or \Exception, "%s" was passed instead.', is_object($error) ? get_class($error) : gettype($error)));
|
||||
}
|
||||
|
||||
$this->error = $error;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the exit code.
|
||||
*
|
||||
* @param int $exitCode The command exit code
|
||||
*/
|
||||
public function setExitCode($exitCode)
|
||||
{
|
||||
$this->exitCode = (int) $exitCode;
|
||||
|
||||
$r = new \ReflectionProperty($this->error, 'code');
|
||||
$r->setAccessible(true);
|
||||
$r->setValue($this->error, $this->exitCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the exit code.
|
||||
*
|
||||
* @return int The command exit code
|
||||
*/
|
||||
public function getExitCode()
|
||||
{
|
||||
return null !== $this->exitCode ? $this->exitCode : (is_int($this->error->getCode()) && 0 !== $this->error->getCode() ? $this->error->getCode() : 1);
|
||||
}
|
||||
}
|
||||
@@ -28,7 +28,7 @@ class ConsoleEvent extends Event
|
||||
private $input;
|
||||
private $output;
|
||||
|
||||
public function __construct(Command $command, InputInterface $input, OutputInterface $output)
|
||||
public function __construct(Command $command = null, InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$this->command = $command;
|
||||
$this->input = $input;
|
||||
@@ -38,7 +38,7 @@ class ConsoleEvent extends Event
|
||||
/**
|
||||
* Gets the command that is executed.
|
||||
*
|
||||
* @return Command A Command instance
|
||||
* @return Command|null A Command instance
|
||||
*/
|
||||
public function getCommand()
|
||||
{
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
|
||||
namespace Symfony\Component\Console\Event;
|
||||
|
||||
@trigger_error(sprintf('The "%s" class is deprecated since Symfony 3.3 and will be removed in 4.0. Use the ConsoleErrorEvent instead.', ConsoleExceptionEvent::class), E_USER_DEPRECATED);
|
||||
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
@@ -19,6 +21,8 @@ use Symfony\Component\Console\Output\OutputInterface;
|
||||
* Allows to handle exception thrown in a command.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* @deprecated since version 3.3, to be removed in 4.0. Use ConsoleErrorEvent instead.
|
||||
*/
|
||||
class ConsoleExceptionEvent extends ConsoleEvent
|
||||
{
|
||||
|
||||
91
lib/composer/vendor/symfony/console/EventListener/ErrorListener.php
vendored
Normal file
91
lib/composer/vendor/symfony/console/EventListener/ErrorListener.php
vendored
Normal file
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Console\EventListener;
|
||||
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Symfony\Component\Console\ConsoleEvents;
|
||||
use Symfony\Component\Console\Event\ConsoleErrorEvent;
|
||||
use Symfony\Component\Console\Event\ConsoleEvent;
|
||||
use Symfony\Component\Console\Event\ConsoleTerminateEvent;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
|
||||
/**
|
||||
* @author James Halsall <james.t.halsall@googlemail.com>
|
||||
* @author Robin Chalas <robin.chalas@gmail.com>
|
||||
*/
|
||||
class ErrorListener implements EventSubscriberInterface
|
||||
{
|
||||
private $logger;
|
||||
|
||||
public function __construct(LoggerInterface $logger = null)
|
||||
{
|
||||
$this->logger = $logger;
|
||||
}
|
||||
|
||||
public function onConsoleError(ConsoleErrorEvent $event)
|
||||
{
|
||||
if (null === $this->logger) {
|
||||
return;
|
||||
}
|
||||
|
||||
$error = $event->getError();
|
||||
|
||||
if (!$inputString = $this->getInputString($event)) {
|
||||
return $this->logger->error('An error occurred while using the console. Message: "{message}"', array('error' => $error, 'message' => $error->getMessage()));
|
||||
}
|
||||
|
||||
$this->logger->error('Error thrown while running command "{command}". Message: "{message}"', array('error' => $error, 'command' => $inputString, 'message' => $error->getMessage()));
|
||||
}
|
||||
|
||||
public function onConsoleTerminate(ConsoleTerminateEvent $event)
|
||||
{
|
||||
if (null === $this->logger) {
|
||||
return;
|
||||
}
|
||||
|
||||
$exitCode = $event->getExitCode();
|
||||
|
||||
if (0 === $exitCode) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!$inputString = $this->getInputString($event)) {
|
||||
return $this->logger->debug('The console exited with code "{code}"', array('code' => $exitCode));
|
||||
}
|
||||
|
||||
$this->logger->debug('Command "{command}" exited with code "{code}"', array('command' => $inputString, 'code' => $exitCode));
|
||||
}
|
||||
|
||||
public static function getSubscribedEvents()
|
||||
{
|
||||
return array(
|
||||
ConsoleEvents::ERROR => array('onConsoleError', -128),
|
||||
ConsoleEvents::TERMINATE => array('onConsoleTerminate', -128),
|
||||
);
|
||||
}
|
||||
|
||||
private static function getInputString(ConsoleEvent $event)
|
||||
{
|
||||
$commandName = $event->getCommand() ? $event->getCommand()->getName() : null;
|
||||
$input = $event->getInput();
|
||||
|
||||
if (method_exists($input, '__toString')) {
|
||||
if ($commandName) {
|
||||
return str_replace(array("'$commandName'", "\"$commandName\""), $commandName, (string) $input);
|
||||
}
|
||||
|
||||
return (string) $input;
|
||||
}
|
||||
|
||||
return $commandName;
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -35,10 +35,25 @@ 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, '\\');
|
||||
$text .= str_repeat('<<', $len - strlen($text));
|
||||
$text = str_replace("\0", '', $text);
|
||||
$text .= str_repeat("\0", $len - strlen($text));
|
||||
}
|
||||
|
||||
return $text;
|
||||
@@ -67,9 +82,7 @@ class OutputFormatter implements OutputFormatterInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the decorated flag.
|
||||
*
|
||||
* @param bool $decorated Whether to decorate the messages or not
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setDecorated($decorated)
|
||||
{
|
||||
@@ -77,9 +90,7 @@ class OutputFormatter implements OutputFormatterInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the decorated flag.
|
||||
*
|
||||
* @return bool true if the output will decorate messages, false otherwise
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isDecorated()
|
||||
{
|
||||
@@ -87,10 +98,7 @@ class OutputFormatter implements OutputFormatterInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a new style.
|
||||
*
|
||||
* @param string $name The style name
|
||||
* @param OutputFormatterStyleInterface $style The style instance
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setStyle($name, OutputFormatterStyleInterface $style)
|
||||
{
|
||||
@@ -98,11 +106,7 @@ class OutputFormatter implements OutputFormatterInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if output formatter has style with specified name.
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return bool
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function hasStyle($name)
|
||||
{
|
||||
@@ -110,13 +114,7 @@ class OutputFormatter implements OutputFormatterInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets style options from style with specified name.
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return OutputFormatterStyleInterface
|
||||
*
|
||||
* @throws InvalidArgumentException When style isn't defined
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getStyle($name)
|
||||
{
|
||||
@@ -128,18 +126,14 @@ class OutputFormatter implements OutputFormatterInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats a message according to the given styles.
|
||||
*
|
||||
* @param string $message The message to style
|
||||
*
|
||||
* @return string The styled message
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function format($message)
|
||||
{
|
||||
$message = (string) $message;
|
||||
$offset = 0;
|
||||
$output = '';
|
||||
$tagRegex = '[a-z][a-z0-9_=;-]*+';
|
||||
$tagRegex = '[a-z][a-z0-9,_=;-]*+';
|
||||
preg_match_all("#<(($tagRegex) | /($tagRegex)?)>#ix", $message, $matches, PREG_OFFSET_CAPTURE);
|
||||
foreach ($matches[0] as $i => $match) {
|
||||
$pos = $match[1];
|
||||
@@ -174,8 +168,8 @@ class OutputFormatter implements OutputFormatterInterface
|
||||
|
||||
$output .= $this->applyCurrentStyle(substr($message, $offset));
|
||||
|
||||
if (false !== strpos($output, '<<')) {
|
||||
return strtr($output, array('\\<' => '<', '<<' => '\\'));
|
||||
if (false !== strpos($output, "\0")) {
|
||||
return strtr($output, array("\0" => '\\', '\\<' => '<'));
|
||||
}
|
||||
|
||||
return str_replace('\\<', '<', $output);
|
||||
@@ -194,7 +188,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)
|
||||
{
|
||||
@@ -202,7 +196,7 @@ class OutputFormatter implements OutputFormatterInterface
|
||||
return $this->styles[$string];
|
||||
}
|
||||
|
||||
if (!preg_match_all('/([^=]+)=([^;]+)(;|$)/', strtolower($string), $matches, PREG_SET_ORDER)) {
|
||||
if (!preg_match_all('/([^=]+)=([^;]+)(;|$)/', $string, $matches, PREG_SET_ORDER)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -214,12 +208,20 @@ class OutputFormatter implements OutputFormatterInterface
|
||||
$style->setForeground($match[1]);
|
||||
} elseif ('bg' == $match[0]) {
|
||||
$style->setBackground($match[1]);
|
||||
} else {
|
||||
try {
|
||||
$style->setOption($match[1]);
|
||||
} catch (\InvalidArgumentException $e) {
|
||||
return false;
|
||||
} elseif ('options' === $match[0]) {
|
||||
preg_match_all('([^,;]+)', $match[1], $options);
|
||||
$options = array_shift($options);
|
||||
foreach ($options as $option) {
|
||||
try {
|
||||
$style->setOption($option);
|
||||
} catch (\InvalidArgumentException $e) {
|
||||
@trigger_error(sprintf('Unknown style options are deprecated since Symfony 3.2 and will be removed in 4.0. Exception "%s".', $e->getMessage()), E_USER_DEPRECATED);
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -55,6 +55,8 @@ interface OutputFormatterInterface
|
||||
* @param string $name
|
||||
*
|
||||
* @return OutputFormatterStyleInterface
|
||||
*
|
||||
* @throws \InvalidArgumentException When style isn't defined
|
||||
*/
|
||||
public function getStyle($name);
|
||||
|
||||
|
||||
@@ -172,9 +172,7 @@ class OutputFormatterStyle implements OutputFormatterStyleInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets multiple style options at once.
|
||||
*
|
||||
* @param array $options
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setOptions(array $options)
|
||||
{
|
||||
|
||||
@@ -48,8 +48,6 @@ interface OutputFormatterStyleInterface
|
||||
|
||||
/**
|
||||
* Sets multiple style options at once.
|
||||
*
|
||||
* @param array $options
|
||||
*/
|
||||
public function setOptions(array $options);
|
||||
|
||||
|
||||
@@ -23,16 +23,8 @@ class OutputFormatterStyleStack
|
||||
*/
|
||||
private $styles;
|
||||
|
||||
/**
|
||||
* @var OutputFormatterStyleInterface
|
||||
*/
|
||||
private $emptyStyle;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param OutputFormatterStyleInterface|null $emptyStyle
|
||||
*/
|
||||
public function __construct(OutputFormatterStyleInterface $emptyStyle = null)
|
||||
{
|
||||
$this->emptyStyle = $emptyStyle ?: new OutputFormatterStyle();
|
||||
@@ -49,8 +41,6 @@ class OutputFormatterStyleStack
|
||||
|
||||
/**
|
||||
* Pushes a style in the stack.
|
||||
*
|
||||
* @param OutputFormatterStyleInterface $style
|
||||
*/
|
||||
public function push(OutputFormatterStyleInterface $style)
|
||||
{
|
||||
@@ -60,8 +50,6 @@ class OutputFormatterStyleStack
|
||||
/**
|
||||
* Pops a style from the stack.
|
||||
*
|
||||
* @param OutputFormatterStyleInterface|null $style
|
||||
*
|
||||
* @return OutputFormatterStyleInterface
|
||||
*
|
||||
* @throws InvalidArgumentException When style tags incorrectly nested
|
||||
@@ -102,9 +90,7 @@ class OutputFormatterStyleStack
|
||||
}
|
||||
|
||||
/**
|
||||
* @param OutputFormatterStyleInterface $emptyStyle
|
||||
*
|
||||
* @return OutputFormatterStyleStack
|
||||
* @return $this
|
||||
*/
|
||||
public function setEmptyStyle(OutputFormatterStyleInterface $emptyStyle)
|
||||
{
|
||||
|
||||
@@ -31,9 +31,6 @@ class DescriptorHelper extends Helper
|
||||
*/
|
||||
private $descriptors = array();
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this
|
||||
@@ -78,7 +75,7 @@ class DescriptorHelper extends Helper
|
||||
* @param string $format
|
||||
* @param DescriptorInterface $descriptor
|
||||
*
|
||||
* @return DescriptorHelper
|
||||
* @return $this
|
||||
*/
|
||||
public function register($format, DescriptorInterface $descriptor)
|
||||
{
|
||||
|
||||
@@ -23,9 +23,7 @@ abstract class Helper implements HelperInterface
|
||||
protected $helperSet = null;
|
||||
|
||||
/**
|
||||
* Sets the helper set associated with this helper.
|
||||
*
|
||||
* @param HelperSet $helperSet A HelperSet instance
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setHelperSet(HelperSet $helperSet = null)
|
||||
{
|
||||
@@ -33,9 +31,7 @@ abstract class Helper implements HelperInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the helper set associated with this helper.
|
||||
*
|
||||
* @return HelperSet A HelperSet instance
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getHelperSet()
|
||||
{
|
||||
@@ -58,6 +54,24 @@ abstract class Helper implements HelperInterface
|
||||
return mb_strwidth($string, $encoding);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the subset of a string, using mb_substr if it is available.
|
||||
*
|
||||
* @param string $string String to subset
|
||||
* @param int $from Start offset
|
||||
* @param int|null $length Length to read
|
||||
*
|
||||
* @return string The string subset
|
||||
*/
|
||||
public static function substr($string, $from, $length = null)
|
||||
{
|
||||
if (false === $encoding = mb_detect_encoding($string, null, true)) {
|
||||
return substr($string, $from, $length);
|
||||
}
|
||||
|
||||
return mb_substr($string, $from, $length, $encoding);
|
||||
}
|
||||
|
||||
public static function formatTime($secs)
|
||||
{
|
||||
static $timeFormats = array(
|
||||
@@ -105,6 +119,11 @@ abstract class Helper implements HelperInterface
|
||||
}
|
||||
|
||||
public static function strlenWithoutDecoration(OutputFormatterInterface $formatter, $string)
|
||||
{
|
||||
return self::strlen(self::removeDecoration($formatter, $string));
|
||||
}
|
||||
|
||||
public static function removeDecoration(OutputFormatterInterface $formatter, $string)
|
||||
{
|
||||
$isDecorated = $formatter->isDecorated();
|
||||
$formatter->setDecorated(false);
|
||||
@@ -114,6 +133,6 @@ abstract class Helper implements HelperInterface
|
||||
$string = preg_replace("/\033\[[^m]*m/", '', $string);
|
||||
$formatter->setDecorated($isDecorated);
|
||||
|
||||
return self::strlen($string);
|
||||
return $string;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,8 +20,6 @@ interface HelperInterface
|
||||
{
|
||||
/**
|
||||
* Sets the helper set associated with this helper.
|
||||
*
|
||||
* @param HelperSet $helperSet A HelperSet instance
|
||||
*/
|
||||
public function setHelperSet(HelperSet $helperSet = null);
|
||||
|
||||
|
||||
@@ -28,8 +28,6 @@ class HelperSet implements \IteratorAggregate
|
||||
private $command;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param Helper[] $helpers An array of helper
|
||||
*/
|
||||
public function __construct(array $helpers = array())
|
||||
@@ -85,11 +83,6 @@ class HelperSet implements \IteratorAggregate
|
||||
return $this->helpers[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the command associated with this helper set.
|
||||
*
|
||||
* @param Command $command A Command instance
|
||||
*/
|
||||
public function setCommand(Command $command = null)
|
||||
{
|
||||
$this->command = $command;
|
||||
|
||||
@@ -15,7 +15,6 @@ use Symfony\Component\Console\Output\ConsoleOutputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Process\Exception\ProcessFailedException;
|
||||
use Symfony\Component\Process\Process;
|
||||
use Symfony\Component\Process\ProcessBuilder;
|
||||
|
||||
/**
|
||||
* The ProcessHelper class provides helpers to run external processes.
|
||||
@@ -44,9 +43,7 @@ class ProcessHelper extends Helper
|
||||
|
||||
$formatter = $this->getHelperSet()->get('debug_formatter');
|
||||
|
||||
if (is_array($cmd)) {
|
||||
$process = ProcessBuilder::create($cmd)->getProcess();
|
||||
} elseif ($cmd instanceof Process) {
|
||||
if ($cmd instanceof Process) {
|
||||
$process = $cmd;
|
||||
} else {
|
||||
$process = new Process($cmd);
|
||||
|
||||
@@ -14,6 +14,7 @@ namespace Symfony\Component\Console\Helper;
|
||||
use Symfony\Component\Console\Output\ConsoleOutputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Console\Exception\LogicException;
|
||||
use Symfony\Component\Console\Terminal;
|
||||
|
||||
/**
|
||||
* The ProgressBar provides helpers to display progress output.
|
||||
@@ -21,9 +22,8 @@ use Symfony\Component\Console\Exception\LogicException;
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
* @author Chris Jones <leeked@gmail.com>
|
||||
*/
|
||||
class ProgressBar
|
||||
final class ProgressBar
|
||||
{
|
||||
// options
|
||||
private $barWidth = 28;
|
||||
private $barChar;
|
||||
private $emptyBarChar = '-';
|
||||
@@ -31,10 +31,6 @@ class ProgressBar
|
||||
private $format;
|
||||
private $internalFormat;
|
||||
private $redrawFreq = 1;
|
||||
|
||||
/**
|
||||
* @var OutputInterface
|
||||
*/
|
||||
private $output;
|
||||
private $step = 0;
|
||||
private $max;
|
||||
@@ -44,14 +40,13 @@ class ProgressBar
|
||||
private $formatLineCount;
|
||||
private $messages = array();
|
||||
private $overwrite = true;
|
||||
private $terminal;
|
||||
private $firstRun = true;
|
||||
|
||||
private static $formatters;
|
||||
private static $formats;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param OutputInterface $output An OutputInterface instance
|
||||
* @param int $max Maximum steps (0 if unknown)
|
||||
*/
|
||||
@@ -63,6 +58,7 @@ class ProgressBar
|
||||
|
||||
$this->output = $output;
|
||||
$this->setMaxSteps($max);
|
||||
$this->terminal = new Terminal();
|
||||
|
||||
if (!$this->output->isDecorated()) {
|
||||
// disable overwrite when output does not support ANSI codes.
|
||||
@@ -218,7 +214,7 @@ class ProgressBar
|
||||
*/
|
||||
public function setBarWidth($size)
|
||||
{
|
||||
$this->barWidth = (int) $size;
|
||||
$this->barWidth = max(1, (int) $size);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -338,8 +334,6 @@ class ProgressBar
|
||||
* Advances the progress output X steps.
|
||||
*
|
||||
* @param int $step Number of steps to advance
|
||||
*
|
||||
* @throws LogicException
|
||||
*/
|
||||
public function advance($step = 1)
|
||||
{
|
||||
@@ -360,18 +354,15 @@ class ProgressBar
|
||||
* Sets the current progress.
|
||||
*
|
||||
* @param int $step The current progress
|
||||
*
|
||||
* @throws LogicException
|
||||
*/
|
||||
public function setProgress($step)
|
||||
{
|
||||
$step = (int) $step;
|
||||
if ($step < $this->step) {
|
||||
throw new LogicException('You can\'t regress the progress bar.');
|
||||
}
|
||||
|
||||
if ($this->max && $step > $this->max) {
|
||||
$this->max = $step;
|
||||
} elseif ($step < 0) {
|
||||
$step = 0;
|
||||
}
|
||||
|
||||
$prevPeriod = (int) ($this->step / $this->redrawFreq);
|
||||
@@ -413,21 +404,7 @@ class ProgressBar
|
||||
$this->setRealFormat($this->internalFormat ?: $this->determineBestFormat());
|
||||
}
|
||||
|
||||
$this->overwrite(preg_replace_callback("{%([a-z\-_]+)(?:\:([^%]+))?%}i", function ($matches) {
|
||||
if ($formatter = $this::getPlaceholderFormatterDefinition($matches[1])) {
|
||||
$text = call_user_func($formatter, $this, $this->output);
|
||||
} elseif (isset($this->messages[$matches[1]])) {
|
||||
$text = $this->messages[$matches[1]];
|
||||
} else {
|
||||
return $matches[0];
|
||||
}
|
||||
|
||||
if (isset($matches[2])) {
|
||||
$text = sprintf('%'.$matches[2], $text);
|
||||
}
|
||||
|
||||
return $text;
|
||||
}, $this->format));
|
||||
$this->overwrite($this->buildLine());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -597,4 +574,44 @@ class ProgressBar
|
||||
'debug_nomax' => ' %current% [%bar%] %elapsed:6s% %memory:6s%',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
private function buildLine()
|
||||
{
|
||||
$regex = "{%([a-z\-_]+)(?:\:([^%]+))?%}i";
|
||||
$callback = function ($matches) {
|
||||
if ($formatter = $this::getPlaceholderFormatterDefinition($matches[1])) {
|
||||
$text = call_user_func($formatter, $this, $this->output);
|
||||
} elseif (isset($this->messages[$matches[1]])) {
|
||||
$text = $this->messages[$matches[1]];
|
||||
} else {
|
||||
return $matches[0];
|
||||
}
|
||||
|
||||
if (isset($matches[2])) {
|
||||
$text = sprintf('%'.$matches[2], $text);
|
||||
}
|
||||
|
||||
return $text;
|
||||
};
|
||||
$line = preg_replace_callback($regex, $callback, $this->format);
|
||||
|
||||
// gets string length for each sub line with multiline format
|
||||
$linesLength = array_map(function ($subLine) {
|
||||
return Helper::strlenWithoutDecoration($this->output->getFormatter(), rtrim($subLine, "\r"));
|
||||
}, explode("\n", $line));
|
||||
|
||||
$linesWidth = max($linesLength);
|
||||
|
||||
$terminalWidth = $this->terminal->getWidth();
|
||||
if ($linesWidth <= $terminalWidth) {
|
||||
return $line;
|
||||
}
|
||||
|
||||
$this->setBarWidth($this->barWidth - $linesWidth + $terminalWidth);
|
||||
|
||||
return preg_replace_callback($regex, $callback, $this->format);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,6 @@ class ProgressIndicator
|
||||
private $indicatorCurrent;
|
||||
private $indicatorChangeInterval;
|
||||
private $indicatorUpdateTime;
|
||||
private $lastMessagesLength;
|
||||
private $started = false;
|
||||
|
||||
private static $formatters;
|
||||
@@ -89,7 +88,6 @@ class ProgressIndicator
|
||||
|
||||
$this->message = $message;
|
||||
$this->started = true;
|
||||
$this->lastMessagesLength = 0;
|
||||
$this->startTime = time();
|
||||
$this->indicatorUpdateTime = $this->getCurrentTimeInMilliseconds() + $this->indicatorChangeInterval;
|
||||
$this->indicatorCurrent = 0;
|
||||
@@ -226,27 +224,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()
|
||||
|
||||
@@ -13,10 +13,12 @@ namespace Symfony\Component\Console\Helper;
|
||||
|
||||
use Symfony\Component\Console\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\Console\Exception\RuntimeException;
|
||||
use Symfony\Component\Console\Formatter\OutputFormatter;
|
||||
use Symfony\Component\Console\Formatter\OutputFormatterStyle;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\StreamableInputInterface;
|
||||
use Symfony\Component\Console\Output\ConsoleOutputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Console\Formatter\OutputFormatterStyle;
|
||||
use Symfony\Component\Console\Question\Question;
|
||||
use Symfony\Component\Console\Question\ChoiceQuestion;
|
||||
|
||||
@@ -34,11 +36,7 @@ class QuestionHelper extends Helper
|
||||
/**
|
||||
* Asks a question to the user.
|
||||
*
|
||||
* @param InputInterface $input An InputInterface instance
|
||||
* @param OutputInterface $output An OutputInterface instance
|
||||
* @param Question $question The question to ask
|
||||
*
|
||||
* @return string The user answer
|
||||
* @return mixed The user answer
|
||||
*
|
||||
* @throws RuntimeException If there is no data to read in the input stream
|
||||
*/
|
||||
@@ -49,9 +47,19 @@ class QuestionHelper extends Helper
|
||||
}
|
||||
|
||||
if (!$input->isInteractive()) {
|
||||
if ($question instanceof ChoiceQuestion) {
|
||||
$choices = $question->getChoices();
|
||||
|
||||
return $choices[$question->getDefault()];
|
||||
}
|
||||
|
||||
return $question->getDefault();
|
||||
}
|
||||
|
||||
if ($input instanceof StreamableInputInterface && $stream = $input->getStream()) {
|
||||
$this->inputStream = $stream;
|
||||
}
|
||||
|
||||
if (!$question->getValidator()) {
|
||||
return $this->doAsk($output, $question);
|
||||
}
|
||||
@@ -68,12 +76,17 @@ class QuestionHelper extends Helper
|
||||
*
|
||||
* This is mainly useful for testing purpose.
|
||||
*
|
||||
* @deprecated since version 3.2, to be removed in 4.0. Use
|
||||
* StreamableInputInterface::setStream() instead.
|
||||
*
|
||||
* @param resource $stream The input stream
|
||||
*
|
||||
* @throws InvalidArgumentException In case the stream is not a resource
|
||||
*/
|
||||
public function setInputStream($stream)
|
||||
{
|
||||
@trigger_error(sprintf('The %s() method is deprecated since Symfony 3.2 and will be removed in 4.0. Use %s::setStream() instead.', __METHOD__, StreamableInputInterface::class), E_USER_DEPRECATED);
|
||||
|
||||
if (!is_resource($stream)) {
|
||||
throw new InvalidArgumentException('Input stream must be a valid resource.');
|
||||
}
|
||||
@@ -84,10 +97,17 @@ class QuestionHelper extends Helper
|
||||
/**
|
||||
* Returns the helper's input stream.
|
||||
*
|
||||
* @deprecated since version 3.2, to be removed in 4.0. Use
|
||||
* StreamableInputInterface::getStream() instead.
|
||||
*
|
||||
* @return resource
|
||||
*/
|
||||
public function getInputStream()
|
||||
{
|
||||
if (0 === func_num_args() || func_get_arg(0)) {
|
||||
@trigger_error(sprintf('The %s() method is deprecated since Symfony 3.2 and will be removed in 4.0. Use %s::getStream() instead.', __METHOD__, StreamableInputInterface::class), E_USER_DEPRECATED);
|
||||
}
|
||||
|
||||
return $this->inputStream;
|
||||
}
|
||||
|
||||
@@ -99,16 +119,20 @@ class QuestionHelper extends Helper
|
||||
return 'question';
|
||||
}
|
||||
|
||||
/**
|
||||
* Prevents usage of stty.
|
||||
*/
|
||||
public static function disableStty()
|
||||
{
|
||||
self::$stty = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Asks the question to the user.
|
||||
*
|
||||
* @param OutputInterface $output
|
||||
* @param Question $question
|
||||
*
|
||||
* @return bool|mixed|null|string
|
||||
*
|
||||
* @throws \Exception
|
||||
* @throws \RuntimeException
|
||||
* @throws RuntimeException In case the fallback is deactivated and the response cannot be hidden
|
||||
*/
|
||||
private function doAsk(OutputInterface $output, Question $question)
|
||||
{
|
||||
@@ -122,7 +146,7 @@ class QuestionHelper extends Helper
|
||||
if ($question->isHidden()) {
|
||||
try {
|
||||
$ret = trim($this->getHiddenResponse($output, $inputStream));
|
||||
} catch (\RuntimeException $e) {
|
||||
} catch (RuntimeException $e) {
|
||||
if (!$question->isHiddenFallback()) {
|
||||
throw $e;
|
||||
}
|
||||
@@ -132,12 +156,12 @@ 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);
|
||||
}
|
||||
} else {
|
||||
$ret = trim($this->autocomplete($output, $question, $inputStream));
|
||||
$ret = trim($this->autocomplete($output, $question, $inputStream, is_array($autocomplete) ? $autocomplete : iterator_to_array($autocomplete, false)));
|
||||
}
|
||||
|
||||
$ret = strlen($ret) > 0 ? $ret : $question->getDefault();
|
||||
@@ -151,9 +175,6 @@ class QuestionHelper extends Helper
|
||||
|
||||
/**
|
||||
* Outputs the question prompt.
|
||||
*
|
||||
* @param OutputInterface $output
|
||||
* @param Question $question
|
||||
*/
|
||||
protected function writePrompt(OutputInterface $output, Question $question)
|
||||
{
|
||||
@@ -178,9 +199,6 @@ class QuestionHelper extends Helper
|
||||
|
||||
/**
|
||||
* Outputs an error message.
|
||||
*
|
||||
* @param OutputInterface $output
|
||||
* @param \Exception $error
|
||||
*/
|
||||
protected function writeError(OutputInterface $output, \Exception $error)
|
||||
{
|
||||
@@ -199,12 +217,12 @@ class QuestionHelper extends Helper
|
||||
* @param OutputInterface $output
|
||||
* @param Question $question
|
||||
* @param resource $inputStream
|
||||
* @param array $autocomplete
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function autocomplete(OutputInterface $output, Question $question, $inputStream)
|
||||
private function autocomplete(OutputInterface $output, Question $question, $inputStream, array $autocomplete)
|
||||
{
|
||||
$autocomplete = $question->getAutocompleterValues();
|
||||
$ret = '';
|
||||
|
||||
$i = 0;
|
||||
@@ -232,7 +250,7 @@ class QuestionHelper extends Helper
|
||||
$output->write("\033[1D");
|
||||
}
|
||||
|
||||
if ($i === 0) {
|
||||
if (0 === $i) {
|
||||
$ofs = -1;
|
||||
$matches = $autocomplete;
|
||||
$numMatches = count($matches);
|
||||
@@ -300,7 +318,7 @@ class QuestionHelper extends Helper
|
||||
// Save cursor position
|
||||
$output->write("\0337");
|
||||
// Write highlighted text
|
||||
$output->write('<hl>'.substr($matches[$ofs], $i).'</hl>');
|
||||
$output->write('<hl>'.OutputFormatter::escapeTrailingBackslash(substr($matches[$ofs], $i)).'</hl>');
|
||||
// Restore cursor position
|
||||
$output->write("\0338");
|
||||
}
|
||||
@@ -362,7 +380,7 @@ class QuestionHelper extends Helper
|
||||
}
|
||||
|
||||
if (false !== $shell = $this->getShell()) {
|
||||
$readCmd = $shell === 'csh' ? 'set mypassword = $<' : 'read -r mypassword';
|
||||
$readCmd = 'csh' === $shell ? 'set mypassword = $<' : 'read -r mypassword';
|
||||
$command = sprintf("/usr/bin/env %s -c 'stty -echo; %s; stty echo; echo \$mypassword'", $shell, $readCmd);
|
||||
$value = rtrim(shell_exec($command));
|
||||
$output->writeln('');
|
||||
@@ -380,7 +398,7 @@ class QuestionHelper extends Helper
|
||||
* @param OutputInterface $output An Output instance
|
||||
* @param Question $question A Question instance
|
||||
*
|
||||
* @return string The validated response
|
||||
* @return mixed The validated response
|
||||
*
|
||||
* @throws \Exception In case the max number of attempts has been reached and no valid response has been given
|
||||
*/
|
||||
@@ -395,6 +413,8 @@ class QuestionHelper extends Helper
|
||||
|
||||
try {
|
||||
return call_user_func($question->getValidator(), $interviewer());
|
||||
} catch (RuntimeException $e) {
|
||||
throw $e;
|
||||
} catch (\Exception $error) {
|
||||
}
|
||||
}
|
||||
@@ -442,6 +462,6 @@ class QuestionHelper extends Helper
|
||||
|
||||
exec('stty 2>&1', $output, $exitcode);
|
||||
|
||||
return self::$stty = $exitcode === 0;
|
||||
return self::$stty = 0 === $exitcode;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,6 +29,8 @@ class SymfonyQuestionHelper extends QuestionHelper
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* To be removed in 4.0
|
||||
*/
|
||||
public function ask(InputInterface $input, OutputInterface $output, Question $question)
|
||||
{
|
||||
@@ -39,6 +41,8 @@ class SymfonyQuestionHelper extends QuestionHelper
|
||||
} else {
|
||||
// make required
|
||||
if (!is_array($value) && !is_bool($value) && 0 === strlen($value)) {
|
||||
@trigger_error('The default question validator is deprecated since Symfony 3.3 and will not be used anymore in version 4.0. Set a custom question validator if needed.', E_USER_DEPRECATED);
|
||||
|
||||
throw new LogicException('A value is required.');
|
||||
}
|
||||
}
|
||||
@@ -54,7 +58,7 @@ class SymfonyQuestionHelper extends QuestionHelper
|
||||
*/
|
||||
protected function writePrompt(OutputInterface $output, Question $question)
|
||||
{
|
||||
$text = OutputFormatter::escape($question->getQuestion());
|
||||
$text = OutputFormatter::escapeTrailingBackslash($question->getQuestion());
|
||||
$default = $question->getDefault();
|
||||
|
||||
switch (true) {
|
||||
|
||||
@@ -26,29 +26,23 @@ class Table
|
||||
{
|
||||
/**
|
||||
* Table headers.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $headers = array();
|
||||
|
||||
/**
|
||||
* Table rows.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $rows = array();
|
||||
|
||||
/**
|
||||
* Column widths cache.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $effectiveColumnWidths = array();
|
||||
|
||||
/**
|
||||
* Number of columns cache.
|
||||
*
|
||||
* @var array
|
||||
* @var int
|
||||
*/
|
||||
private $numberOfColumns;
|
||||
|
||||
@@ -107,7 +101,7 @@ class Table
|
||||
*
|
||||
* @param string $name The style name
|
||||
*
|
||||
* @return TableStyle A TableStyle instance
|
||||
* @return TableStyle
|
||||
*/
|
||||
public static function getStyleDefinition($name)
|
||||
{
|
||||
@@ -127,7 +121,7 @@ class Table
|
||||
*
|
||||
* @param TableStyle|string $name The style name or a TableStyle instance
|
||||
*
|
||||
* @return Table
|
||||
* @return $this
|
||||
*/
|
||||
public function setStyle($name)
|
||||
{
|
||||
@@ -152,11 +146,11 @@ 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);
|
||||
$columnIndex = (int) $columnIndex;
|
||||
|
||||
$this->columnStyles[$columnIndex] = $this->resolveStyle($name);
|
||||
|
||||
@@ -187,11 +181,11 @@ class Table
|
||||
* @param int $columnIndex Column index
|
||||
* @param int $width Minimum column width in characters
|
||||
*
|
||||
* @return Table
|
||||
* @return $this
|
||||
*/
|
||||
public function setColumnWidth($columnIndex, $width)
|
||||
{
|
||||
$this->columnWidths[intval($columnIndex)] = intval($width);
|
||||
$this->columnWidths[(int) $columnIndex] = (int) $width;
|
||||
|
||||
return $this;
|
||||
}
|
||||
@@ -201,7 +195,7 @@ class Table
|
||||
*
|
||||
* @param array $widths
|
||||
*
|
||||
* @return Table
|
||||
* @return $this
|
||||
*/
|
||||
public function setColumnWidths(array $widths)
|
||||
{
|
||||
@@ -269,6 +263,7 @@ class Table
|
||||
* Renders table to output.
|
||||
*
|
||||
* Example:
|
||||
* <code>
|
||||
* +---------------+-----------------------+------------------+
|
||||
* | ISBN | Title | Author |
|
||||
* +---------------+-----------------------+------------------+
|
||||
@@ -276,6 +271,7 @@ class Table
|
||||
* | 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens |
|
||||
* | 960-425-059-0 | The Lord of the Rings | J. R. R. Tolkien |
|
||||
* +---------------+-----------------------+------------------+
|
||||
* </code>
|
||||
*/
|
||||
public function render()
|
||||
{
|
||||
@@ -309,7 +305,7 @@ class Table
|
||||
/**
|
||||
* Renders horizontal header separator.
|
||||
*
|
||||
* Example: +-----+-----------+-------+
|
||||
* Example: <code>+-----+-----------+-------+</code>
|
||||
*/
|
||||
private function renderRowSeparator()
|
||||
{
|
||||
@@ -340,7 +336,7 @@ class Table
|
||||
/**
|
||||
* Renders table row.
|
||||
*
|
||||
* Example: | 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens |
|
||||
* Example: <code>| 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens |</code>
|
||||
*
|
||||
* @param array $row
|
||||
* @param string $cellFormat
|
||||
@@ -426,7 +422,7 @@ class Table
|
||||
if (!strstr($cell, "\n")) {
|
||||
continue;
|
||||
}
|
||||
$lines = explode("\n", $cell);
|
||||
$lines = explode("\n", str_replace("\n", "<fg=default;bg=default>\n</>", $cell));
|
||||
foreach ($lines as $lineKey => $line) {
|
||||
if ($cell instanceof TableCell) {
|
||||
$line = new TableCell($line, array('colspan' => $cell->getColspan()));
|
||||
@@ -459,7 +455,7 @@ class Table
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function fillNextRows($rows, $line)
|
||||
private function fillNextRows(array $rows, $line)
|
||||
{
|
||||
$unmergedRows = array();
|
||||
foreach ($rows[$line] as $column => $cell) {
|
||||
@@ -467,7 +463,7 @@ class Table
|
||||
$nbLines = $cell->getRowspan() - 1;
|
||||
$lines = array($cell);
|
||||
if (strstr($cell, "\n")) {
|
||||
$lines = explode("\n", $cell);
|
||||
$lines = explode("\n", str_replace("\n", "<fg=default;bg=default>\n</>", $cell));
|
||||
$nbLines = count($lines) > $nbLines ? substr_count($cell, "\n") : $nbLines;
|
||||
|
||||
$rows[$line][$column] = new TableCell($lines[0], array('colspan' => $cell->getColspan()));
|
||||
@@ -479,6 +475,9 @@ class Table
|
||||
foreach ($unmergedRows as $unmergedRowKey => $unmergedRow) {
|
||||
$value = isset($lines[$unmergedRowKey - $line]) ? $lines[$unmergedRowKey - $line] : '';
|
||||
$unmergedRows[$unmergedRowKey][$column] = new TableCell($value, array('colspan' => $cell->getColspan()));
|
||||
if ($nbLines === $unmergedRowKey - $line) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -507,8 +506,6 @@ class Table
|
||||
/**
|
||||
* fill cells for a row that contains colspan > 1.
|
||||
*
|
||||
* @param array $row
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function fillCells($row)
|
||||
@@ -533,7 +530,7 @@ class Table
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function copyRow($rows, $line)
|
||||
private function copyRow(array $rows, $line)
|
||||
{
|
||||
$row = $rows[$line];
|
||||
foreach ($row as $cellKey => $cellValue) {
|
||||
@@ -549,8 +546,6 @@ class Table
|
||||
/**
|
||||
* Gets number of columns by row.
|
||||
*
|
||||
* @param array $row
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
private function getNumberOfColumns(array $row)
|
||||
@@ -566,11 +561,9 @@ class Table
|
||||
/**
|
||||
* Gets list of columns for the given row.
|
||||
*
|
||||
* @param array $row
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function getRowColumns($row)
|
||||
private function getRowColumns(array $row)
|
||||
{
|
||||
$columns = range(0, $this->numberOfColumns - 1);
|
||||
foreach ($row as $cellKey => $cell) {
|
||||
@@ -585,10 +578,8 @@ class Table
|
||||
|
||||
/**
|
||||
* Calculates columns widths.
|
||||
*
|
||||
* @param array $rows
|
||||
*/
|
||||
private function calculateColumnsWidth($rows)
|
||||
private function calculateColumnsWidth(array $rows)
|
||||
{
|
||||
for ($column = 0; $column < $this->numberOfColumns; ++$column) {
|
||||
$lengths = array();
|
||||
@@ -599,9 +590,10 @@ class Table
|
||||
|
||||
foreach ($row as $i => $cell) {
|
||||
if ($cell instanceof TableCell) {
|
||||
$textLength = strlen($cell);
|
||||
$textContent = Helper::removeDecoration($this->output->getFormatter(), $cell);
|
||||
$textLength = Helper::strlen($textContent);
|
||||
if ($textLength > 0) {
|
||||
$contentColumns = str_split($cell, ceil($textLength / $cell->getColspan()));
|
||||
$contentColumns = str_split($textContent, ceil($textLength / $cell->getColspan()));
|
||||
foreach ($contentColumns as $position => $content) {
|
||||
$row[$i + $position] = $content;
|
||||
}
|
||||
|
||||
@@ -18,14 +18,7 @@ use Symfony\Component\Console\Exception\InvalidArgumentException;
|
||||
*/
|
||||
class TableCell
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $value;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $options = array(
|
||||
'rowspan' => 1,
|
||||
'colspan' => 1,
|
||||
@@ -37,6 +30,10 @@ class TableCell
|
||||
*/
|
||||
public function __construct($value = '', array $options = array())
|
||||
{
|
||||
if (is_numeric($value) && !is_string($value)) {
|
||||
$value = (string) $value;
|
||||
}
|
||||
|
||||
$this->value = $value;
|
||||
|
||||
// check option names
|
||||
|
||||
@@ -18,9 +18,6 @@ namespace Symfony\Component\Console\Helper;
|
||||
*/
|
||||
class TableSeparator extends TableCell
|
||||
{
|
||||
/**
|
||||
* @param array $options
|
||||
*/
|
||||
public function __construct(array $options = array())
|
||||
{
|
||||
parent::__construct('', $options);
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -44,8 +44,6 @@ class ArgvInput extends Input
|
||||
private $parsed;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param array|null $argv An array of parameters from the CLI (in the argv format)
|
||||
* @param InputDefinition|null $definition A InputDefinition instance
|
||||
*/
|
||||
@@ -148,7 +146,12 @@ class ArgvInput extends Input
|
||||
|
||||
if (false !== $pos = strpos($name, '=')) {
|
||||
if (0 === strlen($value = substr($name, $pos + 1))) {
|
||||
array_unshift($this->parsed, null);
|
||||
// if no value after "=" then substr() returns "" since php7 only, false before
|
||||
// see http://php.net/manual/fr/migration70.incompatible.php#119151
|
||||
if (\PHP_VERSION_ID < 70000 && false === $value) {
|
||||
$value = '';
|
||||
}
|
||||
array_unshift($this->parsed, $value);
|
||||
}
|
||||
$this->addLongOption(substr($name, 0, $pos), $value);
|
||||
} else {
|
||||
@@ -221,23 +224,16 @@ class ArgvInput extends Input
|
||||
|
||||
$option = $this->definition->getOption($name);
|
||||
|
||||
// Convert empty values to null
|
||||
if (!isset($value[0])) {
|
||||
$value = null;
|
||||
}
|
||||
|
||||
if (null !== $value && !$option->acceptValue()) {
|
||||
throw new RuntimeException(sprintf('The "--%s" option does not accept a value.', $name));
|
||||
}
|
||||
|
||||
if (null === $value && $option->acceptValue() && count($this->parsed)) {
|
||||
if (in_array($value, array('', null), true) && $option->acceptValue() && count($this->parsed)) {
|
||||
// if option accepts an optional or mandatory argument
|
||||
// let's see if there is one provided
|
||||
$next = array_shift($this->parsed);
|
||||
if (isset($next[0]) && '-' !== $next[0]) {
|
||||
if ((isset($next[0]) && '-' !== $next[0]) || in_array($next, array('', null), true)) {
|
||||
$value = $next;
|
||||
} elseif (empty($next)) {
|
||||
$value = null;
|
||||
} else {
|
||||
array_unshift($this->parsed, $next);
|
||||
}
|
||||
@@ -248,8 +244,8 @@ class ArgvInput extends Input
|
||||
throw new RuntimeException(sprintf('The "--%s" option requires a value.', $name));
|
||||
}
|
||||
|
||||
if (!$option->isArray()) {
|
||||
$value = $option->isValueOptional() ? $option->getDefault() : true;
|
||||
if (!$option->isArray() && !$option->isValueOptional()) {
|
||||
$value = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -282,13 +278,23 @@ class ArgvInput extends Input
|
||||
$values = (array) $values;
|
||||
|
||||
foreach ($this->tokens as $token) {
|
||||
if ($onlyParams && $token === '--') {
|
||||
if ($onlyParams && '--' === $token) {
|
||||
return false;
|
||||
}
|
||||
foreach ($values as $value) {
|
||||
if ($token === $value || 0 === strpos($token, $value.'=')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (0 === strpos($token, '-') && 0 !== strpos($token, '--')) {
|
||||
$noValue = explode('=', $token);
|
||||
$token = $noValue[0];
|
||||
$searchableToken = str_replace('-', '', $token);
|
||||
$searchableValue = str_replace('-', '', $value);
|
||||
if ('' !== $searchableToken && '' !== $searchableValue && false !== strpos($searchableToken, $searchableValue)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -305,7 +311,7 @@ class ArgvInput extends Input
|
||||
|
||||
while (0 < count($tokens)) {
|
||||
$token = array_shift($tokens);
|
||||
if ($onlyParams && $token === '--') {
|
||||
if ($onlyParams && '--' === $token) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -335,7 +341,7 @@ class ArgvInput extends Input
|
||||
return $match[1].$this->escapeToken($match[2]);
|
||||
}
|
||||
|
||||
if ($token && $token[0] !== '-') {
|
||||
if ($token && '-' !== $token[0]) {
|
||||
return $this->escapeToken($token);
|
||||
}
|
||||
|
||||
|
||||
@@ -27,12 +27,6 @@ class ArrayInput extends Input
|
||||
{
|
||||
private $parameters;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param array $parameters An array of parameters
|
||||
* @param InputDefinition|null $definition A InputDefinition instance
|
||||
*/
|
||||
public function __construct(array $parameters, InputDefinition $definition = null)
|
||||
{
|
||||
$this->parameters = $parameters;
|
||||
@@ -66,7 +60,7 @@ class ArrayInput extends Input
|
||||
$v = $k;
|
||||
}
|
||||
|
||||
if ($onlyParams && $v === '--') {
|
||||
if ($onlyParams && '--' === $v) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -86,7 +80,7 @@ class ArrayInput extends Input
|
||||
$values = (array) $values;
|
||||
|
||||
foreach ($this->parameters as $k => $v) {
|
||||
if ($onlyParams && ($k === '--' || (is_int($k) && $v === '--'))) {
|
||||
if ($onlyParams && ('--' === $k || (is_int($k) && '--' === $v))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -112,9 +106,15 @@ class ArrayInput extends Input
|
||||
$params = array();
|
||||
foreach ($this->parameters as $param => $val) {
|
||||
if ($param && '-' === $param[0]) {
|
||||
$params[] = $param.('' != $val ? '='.$this->escapeToken($val) : '');
|
||||
if (is_array($val)) {
|
||||
foreach ($val as $v) {
|
||||
$params[] = $param.('' != $v ? '='.$this->escapeToken($v) : '');
|
||||
}
|
||||
} else {
|
||||
$params[] = $param.('' != $val ? '='.$this->escapeToken($val) : '');
|
||||
}
|
||||
} else {
|
||||
$params[] = $this->escapeToken($val);
|
||||
$params[] = is_array($val) ? array_map(array($this, 'escapeToken'), $val) : $this->escapeToken($val);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -127,7 +127,7 @@ class ArrayInput extends Input
|
||||
protected function parse()
|
||||
{
|
||||
foreach ($this->parameters as $key => $value) {
|
||||
if ($key === '--') {
|
||||
if ('--' === $key) {
|
||||
return;
|
||||
}
|
||||
if (0 === strpos($key, '--')) {
|
||||
@@ -179,7 +179,9 @@ class ArrayInput extends Input
|
||||
throw new InvalidOptionException(sprintf('The "--%s" option requires a value.', $name));
|
||||
}
|
||||
|
||||
$value = $option->isValueOptional() ? $option->getDefault() : true;
|
||||
if (!$option->isValueOptional()) {
|
||||
$value = true;
|
||||
}
|
||||
}
|
||||
|
||||
$this->options[$name] = $value;
|
||||
|
||||
@@ -25,21 +25,14 @@ use Symfony\Component\Console\Exception\RuntimeException;
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
abstract class Input implements InputInterface
|
||||
abstract class Input implements InputInterface, StreamableInputInterface
|
||||
{
|
||||
/**
|
||||
* @var InputDefinition
|
||||
*/
|
||||
protected $definition;
|
||||
protected $stream;
|
||||
protected $options = array();
|
||||
protected $arguments = array();
|
||||
protected $interactive = true;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param InputDefinition|null $definition A InputDefinition instance
|
||||
*/
|
||||
public function __construct(InputDefinition $definition = null)
|
||||
{
|
||||
if (null === $definition) {
|
||||
@@ -157,7 +150,7 @@ abstract class Input implements InputInterface
|
||||
throw new InvalidArgumentException(sprintf('The "%s" option does not exist.', $name));
|
||||
}
|
||||
|
||||
return isset($this->options[$name]) ? $this->options[$name] : $this->definition->getOption($name)->getDefault();
|
||||
return array_key_exists($name, $this->options) ? $this->options[$name] : $this->definition->getOption($name)->getDefault();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -191,4 +184,20 @@ abstract class Input implements InputInterface
|
||||
{
|
||||
return preg_match('{^[\w-]+$}', $token) ? $token : escapeshellarg($token);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setStream($stream)
|
||||
{
|
||||
$this->stream = $stream;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getStream()
|
||||
{
|
||||
return $this->stream;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,8 +31,6 @@ class InputArgument
|
||||
private $description;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $name The argument name
|
||||
* @param int $mode The argument mode: self::REQUIRED or self::OPTIONAL
|
||||
* @param string $description A description text
|
||||
|
||||
@@ -36,8 +36,6 @@ class InputDefinition
|
||||
private $shortcuts;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param array $definition An array of InputArgument and InputOption instance
|
||||
*/
|
||||
public function __construct(array $definition = array())
|
||||
@@ -47,8 +45,6 @@ class InputDefinition
|
||||
|
||||
/**
|
||||
* Sets the definition of the input.
|
||||
*
|
||||
* @param array $definition The definition array
|
||||
*/
|
||||
public function setDefinition(array $definition)
|
||||
{
|
||||
@@ -95,10 +91,6 @@ class InputDefinition
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an InputArgument object.
|
||||
*
|
||||
* @param InputArgument $argument An InputArgument object
|
||||
*
|
||||
* @throws LogicException When incorrect argument is given
|
||||
*/
|
||||
public function addArgument(InputArgument $argument)
|
||||
@@ -232,10 +224,6 @@ class InputDefinition
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an InputOption object.
|
||||
*
|
||||
* @param InputOption $option An InputOption object
|
||||
*
|
||||
* @throws LogicException When option given already exist
|
||||
*/
|
||||
public function addOption(InputOption $option)
|
||||
@@ -318,7 +306,7 @@ class InputDefinition
|
||||
/**
|
||||
* Gets an InputOption by shortcut.
|
||||
*
|
||||
* @param string $shortcut the Shortcut name
|
||||
* @param string $shortcut The Shortcut name
|
||||
*
|
||||
* @return InputOption An InputOption object
|
||||
*/
|
||||
|
||||
@@ -24,7 +24,7 @@ interface InputInterface
|
||||
/**
|
||||
* Returns the first argument from the raw parameters (not parsed).
|
||||
*
|
||||
* @return string The value of the first argument or null otherwise
|
||||
* @return string|null The value of the first argument or null otherwise
|
||||
*/
|
||||
public function getFirstArgument();
|
||||
|
||||
@@ -57,8 +57,6 @@ interface InputInterface
|
||||
|
||||
/**
|
||||
* Binds the current Input instance with the given arguments and options.
|
||||
*
|
||||
* @param InputDefinition $definition A InputDefinition instance
|
||||
*/
|
||||
public function bind(InputDefinition $definition);
|
||||
|
||||
|
||||
@@ -33,8 +33,6 @@ class InputOption
|
||||
private $description;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $name The option name
|
||||
* @param string|array $shortcut The shortcuts, can be null, a string of shortcuts delimited by | or an array of shortcuts
|
||||
* @param int $mode The option mode: One of the VALUE_* constants
|
||||
@@ -195,8 +193,6 @@ class InputOption
|
||||
/**
|
||||
* Checks whether the given option equals this one.
|
||||
*
|
||||
* @param InputOption $option option to compare
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function equals(InputOption $option)
|
||||
|
||||
37
lib/composer/vendor/symfony/console/Input/StreamableInputInterface.php
vendored
Normal file
37
lib/composer/vendor/symfony/console/Input/StreamableInputInterface.php
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Console\Input;
|
||||
|
||||
/**
|
||||
* StreamableInputInterface is the interface implemented by all input classes
|
||||
* that have an input stream.
|
||||
*
|
||||
* @author Robin Chalas <robin.chalas@gmail.com>
|
||||
*/
|
||||
interface StreamableInputInterface extends InputInterface
|
||||
{
|
||||
/**
|
||||
* Sets the input stream to read from when interacting with the user.
|
||||
*
|
||||
* This is mainly useful for testing purpose.
|
||||
*
|
||||
* @param resource $stream The input stream
|
||||
*/
|
||||
public function setStream($stream);
|
||||
|
||||
/**
|
||||
* Returns the input stream.
|
||||
*
|
||||
* @return resource|null
|
||||
*/
|
||||
public function getStream();
|
||||
}
|
||||
@@ -28,8 +28,6 @@ class StringInput extends ArgvInput
|
||||
const REGEX_QUOTED_STRING = '(?:"([^"\\\\]*(?:\\\\.[^"\\\\]*)*)"|\'([^\'\\\\]*(?:\\\\.[^\'\\\\]*)*)\')';
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $input An array of parameters from the CLI (in the argv format)
|
||||
*/
|
||||
public function __construct($input)
|
||||
|
||||
2
lib/composer/vendor/symfony/console/LICENSE
vendored
2
lib/composer/vendor/symfony/console/LICENSE
vendored
@@ -1,4 +1,4 @@
|
||||
Copyright (c) 2004-2016 Fabien Potencier
|
||||
Copyright (c) 2004-2018 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
|
||||
|
||||
@@ -22,20 +22,14 @@ 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
|
||||
{
|
||||
const INFO = 'info';
|
||||
const ERROR = 'error';
|
||||
|
||||
/**
|
||||
* @var OutputInterface
|
||||
*/
|
||||
private $output;
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $verbosityLevelMap = array(
|
||||
LogLevel::EMERGENCY => OutputInterface::VERBOSITY_NORMAL,
|
||||
LogLevel::ALERT => OutputInterface::VERBOSITY_NORMAL,
|
||||
@@ -46,9 +40,6 @@ class ConsoleLogger extends AbstractLogger
|
||||
LogLevel::INFO => OutputInterface::VERBOSITY_VERY_VERBOSE,
|
||||
LogLevel::DEBUG => OutputInterface::VERBOSITY_DEBUG,
|
||||
);
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $formatLevelMap = array(
|
||||
LogLevel::EMERGENCY => self::ERROR,
|
||||
LogLevel::ALERT => self::ERROR,
|
||||
@@ -59,12 +50,8 @@ class ConsoleLogger extends AbstractLogger
|
||||
LogLevel::INFO => self::INFO,
|
||||
LogLevel::DEBUG => self::INFO,
|
||||
);
|
||||
private $errored = false;
|
||||
|
||||
/**
|
||||
* @param OutputInterface $output
|
||||
* @param array $verbosityLevelMap
|
||||
* @param array $formatLevelMap
|
||||
*/
|
||||
public function __construct(OutputInterface $output, array $verbosityLevelMap = array(), array $formatLevelMap = array())
|
||||
{
|
||||
$this->output = $output;
|
||||
@@ -81,18 +68,33 @@ class ConsoleLogger extends AbstractLogger
|
||||
throw new InvalidArgumentException(sprintf('The log level "%s" does not exist.', $level));
|
||||
}
|
||||
|
||||
$output = $this->output;
|
||||
|
||||
// Write to the error output if necessary and available
|
||||
if ($this->formatLevelMap[$level] === self::ERROR && $this->output instanceof ConsoleOutputInterface) {
|
||||
$output = $this->output->getErrorOutput();
|
||||
} else {
|
||||
$output = $this->output;
|
||||
if (self::ERROR === $this->formatLevelMap[$level]) {
|
||||
if ($this->output instanceof ConsoleOutputInterface) {
|
||||
$output = $output->getErrorOutput();
|
||||
}
|
||||
$this->errored = true;
|
||||
}
|
||||
|
||||
// the if condition check isn't necessary -- it's the same one that $output will do internally anyway.
|
||||
// We only do it for efficiency here as the message formatting is relatively expensive.
|
||||
if ($output->getVerbosity() >= $this->verbosityLevelMap[$level]) {
|
||||
$output->writeln(sprintf('<%1$s>[%2$s] %3$s</%1$s>', $this->formatLevelMap[$level], $level, $this->interpolate($message, $context)));
|
||||
$output->writeln(sprintf('<%1$s>[%2$s] %3$s</%1$s>', $this->formatLevelMap[$level], $level, $this->interpolate($message, $context)), $this->verbosityLevelMap[$level]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true when any messages have been logged at error levels.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasErrored()
|
||||
{
|
||||
return $this->errored;
|
||||
}
|
||||
|
||||
/**
|
||||
* Interpolates context values into the message placeholders.
|
||||
*
|
||||
@@ -105,15 +107,23 @@ class ConsoleLogger extends AbstractLogger
|
||||
*/
|
||||
private function interpolate($message, array $context)
|
||||
{
|
||||
// build a replacement array with braces around the context keys
|
||||
$replace = array();
|
||||
if (false === strpos($message, '{')) {
|
||||
return $message;
|
||||
}
|
||||
|
||||
$replacements = array();
|
||||
foreach ($context as $key => $val) {
|
||||
if (!is_array($val) && (!is_object($val) || method_exists($val, '__toString'))) {
|
||||
$replace[sprintf('{%s}', $key)] = $val;
|
||||
if (null === $val || is_scalar($val) || (\is_object($val) && method_exists($val, '__toString'))) {
|
||||
$replacements["{{$key}}"] = $val;
|
||||
} elseif ($val instanceof \DateTimeInterface) {
|
||||
$replacements["{{$key}}"] = $val->format(\DateTime::RFC3339);
|
||||
} elseif (\is_object($val)) {
|
||||
$replacements["{{$key}}"] = '[object '.\get_class($val).']';
|
||||
} else {
|
||||
$replacements["{{$key}}"] = '['.\gettype($val).']';
|
||||
}
|
||||
}
|
||||
|
||||
// interpolate replacement values into the message and return
|
||||
return strtr($message, $replace);
|
||||
return strtr($message, $replacements);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,9 +16,6 @@ namespace Symfony\Component\Console\Output;
|
||||
*/
|
||||
class BufferedOutput extends Output
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $buffer = '';
|
||||
|
||||
/**
|
||||
@@ -42,7 +39,7 @@ class BufferedOutput extends Output
|
||||
$this->buffer .= $message;
|
||||
|
||||
if ($newline) {
|
||||
$this->buffer .= "\n";
|
||||
$this->buffer .= PHP_EOL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,14 +29,9 @@ use Symfony\Component\Console\Formatter\OutputFormatterInterface;
|
||||
*/
|
||||
class ConsoleOutput extends StreamOutput implements ConsoleOutputInterface
|
||||
{
|
||||
/**
|
||||
* @var StreamOutput
|
||||
*/
|
||||
private $stderr;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param int $verbosity The verbosity level (one of the VERBOSITY constants in OutputInterface)
|
||||
* @param bool|null $decorated Whether to decorate messages (null for auto-guessing)
|
||||
* @param OutputFormatterInterface|null $formatter Output formatter instance (null to use default OutputFormatter)
|
||||
|
||||
@@ -26,10 +26,5 @@ interface ConsoleOutputInterface extends OutputInterface
|
||||
*/
|
||||
public function getErrorOutput();
|
||||
|
||||
/**
|
||||
* Sets the OutputInterface used for errors.
|
||||
*
|
||||
* @param OutputInterface $error
|
||||
*/
|
||||
public function setErrorOutput(OutputInterface $error);
|
||||
}
|
||||
|
||||
@@ -33,8 +33,6 @@ abstract class Output implements OutputInterface
|
||||
private $formatter;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param int $verbosity The verbosity level (one of the VERBOSITY constants in OutputInterface)
|
||||
* @param bool $decorated Whether to decorate messages
|
||||
* @param OutputFormatterInterface|null $formatter Output formatter instance (null to use default OutputFormatter)
|
||||
|
||||
@@ -103,11 +103,6 @@ interface OutputInterface
|
||||
*/
|
||||
public function isDecorated();
|
||||
|
||||
/**
|
||||
* Sets output formatter.
|
||||
*
|
||||
* @param OutputFormatterInterface $formatter
|
||||
*/
|
||||
public function setFormatter(OutputFormatterInterface $formatter);
|
||||
|
||||
/**
|
||||
|
||||
@@ -33,8 +33,6 @@ class StreamOutput extends Output
|
||||
private $stream;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param resource $stream A stream resource
|
||||
* @param int $verbosity The verbosity level (one of the VERBOSITY constants in OutputInterface)
|
||||
* @param bool|null $decorated Whether to decorate messages (null for auto-guessing)
|
||||
|
||||
@@ -26,14 +26,16 @@ class ChoiceQuestion extends Question
|
||||
private $errorMessage = 'Value "%s" is invalid';
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $question The question to ask to the user
|
||||
* @param array $choices The list of available choices
|
||||
* @param mixed $default The default answer to return
|
||||
*/
|
||||
public function __construct($question, array $choices, $default = null)
|
||||
{
|
||||
if (!$choices) {
|
||||
throw new \LogicException('Choice question must have at least 1 choice available.');
|
||||
}
|
||||
|
||||
parent::__construct($question, $default);
|
||||
|
||||
$this->choices = $choices;
|
||||
@@ -58,7 +60,7 @@ class ChoiceQuestion extends Question
|
||||
*
|
||||
* @param bool $multiselect
|
||||
*
|
||||
* @return ChoiceQuestion The current instance
|
||||
* @return $this
|
||||
*/
|
||||
public function setMultiselect($multiselect)
|
||||
{
|
||||
@@ -93,7 +95,7 @@ class ChoiceQuestion extends Question
|
||||
*
|
||||
* @param string $prompt
|
||||
*
|
||||
* @return ChoiceQuestion The current instance
|
||||
* @return $this
|
||||
*/
|
||||
public function setPrompt($prompt)
|
||||
{
|
||||
@@ -109,7 +111,7 @@ class ChoiceQuestion extends Question
|
||||
*
|
||||
* @param string $errorMessage
|
||||
*
|
||||
* @return ChoiceQuestion The current instance
|
||||
* @return $this
|
||||
*/
|
||||
public function setErrorMessage($errorMessage)
|
||||
{
|
||||
@@ -137,7 +139,7 @@ class ChoiceQuestion extends Question
|
||||
|
||||
if ($multiselect) {
|
||||
// Check for a separated comma values
|
||||
if (!preg_match('/^[a-zA-Z0-9_-]+(?:,[a-zA-Z0-9_-]+)*$/', $selectedChoices, $matches)) {
|
||||
if (!preg_match('/^[^,]+(?:,[^,]+)*$/', $selectedChoices, $matches)) {
|
||||
throw new InvalidArgumentException(sprintf($errorMessage, $selected));
|
||||
}
|
||||
$selectedChoices = explode(',', $selectedChoices);
|
||||
|
||||
@@ -21,8 +21,6 @@ class ConfirmationQuestion extends Question
|
||||
private $trueAnswerRegex;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $question The question to ask to the user
|
||||
* @param bool $default The default answer to return, true or false
|
||||
* @param string $trueAnswerRegex A regex to match the "yes" answer
|
||||
|
||||
@@ -31,8 +31,6 @@ class Question
|
||||
private $normalizer;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $question The question to ask to the user
|
||||
* @param mixed $default The default answer to return if the user enters nothing
|
||||
*/
|
||||
@@ -77,7 +75,7 @@ class Question
|
||||
*
|
||||
* @param bool $hidden
|
||||
*
|
||||
* @return Question The current instance
|
||||
* @return $this
|
||||
*
|
||||
* @throws LogicException In case the autocompleter is also used
|
||||
*/
|
||||
@@ -107,7 +105,7 @@ class Question
|
||||
*
|
||||
* @param bool $fallback
|
||||
*
|
||||
* @return Question The current instance
|
||||
* @return $this
|
||||
*/
|
||||
public function setHiddenFallback($fallback)
|
||||
{
|
||||
@@ -119,7 +117,7 @@ class Question
|
||||
/**
|
||||
* Gets values for the autocompleter.
|
||||
*
|
||||
* @return null|array|\Traversable
|
||||
* @return null|iterable
|
||||
*/
|
||||
public function getAutocompleterValues()
|
||||
{
|
||||
@@ -129,9 +127,9 @@ class Question
|
||||
/**
|
||||
* Sets values for the autocompleter.
|
||||
*
|
||||
* @param null|array|\Traversable $values
|
||||
* @param null|iterable $values
|
||||
*
|
||||
* @return Question The current instance
|
||||
* @return $this
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
* @throws LogicException
|
||||
@@ -142,10 +140,8 @@ class Question
|
||||
$values = $this->isAssoc($values) ? array_merge(array_keys($values), array_values($values)) : array_values($values);
|
||||
}
|
||||
|
||||
if (null !== $values && !is_array($values)) {
|
||||
if (!$values instanceof \Traversable || !$values instanceof \Countable) {
|
||||
throw new InvalidArgumentException('Autocompleter values can be either an array, `null` or an object implementing both `Countable` and `Traversable` interfaces.');
|
||||
}
|
||||
if (null !== $values && !is_array($values) && !$values instanceof \Traversable) {
|
||||
throw new InvalidArgumentException('Autocompleter values can be either an array, `null` or a `Traversable` object.');
|
||||
}
|
||||
|
||||
if ($this->hidden) {
|
||||
@@ -162,7 +158,7 @@ class Question
|
||||
*
|
||||
* @param null|callable $validator
|
||||
*
|
||||
* @return Question The current instance
|
||||
* @return $this
|
||||
*/
|
||||
public function setValidator(callable $validator = null)
|
||||
{
|
||||
@@ -188,9 +184,9 @@ class Question
|
||||
*
|
||||
* @param null|int $attempts
|
||||
*
|
||||
* @return Question The current instance
|
||||
* @return $this
|
||||
*
|
||||
* @throws InvalidArgumentException In case the number of attempts is invalid.
|
||||
* @throws InvalidArgumentException in case the number of attempts is invalid
|
||||
*/
|
||||
public function setMaxAttempts($attempts)
|
||||
{
|
||||
@@ -222,7 +218,7 @@ class Question
|
||||
*
|
||||
* @param callable $normalizer
|
||||
*
|
||||
* @return Question The current instance
|
||||
* @return $this
|
||||
*/
|
||||
public function setNormalizer(callable $normalizer)
|
||||
{
|
||||
|
||||
@@ -14,6 +14,7 @@ namespace Symfony\Component\Console\Style;
|
||||
use Symfony\Component\Console\Formatter\OutputFormatterInterface;
|
||||
use Symfony\Component\Console\Helper\ProgressBar;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Console\Output\ConsoleOutputInterface;
|
||||
|
||||
/**
|
||||
* Decorates output to add console style guide helpers.
|
||||
@@ -24,9 +25,6 @@ abstract class OutputStyle implements OutputInterface, StyleInterface
|
||||
{
|
||||
private $output;
|
||||
|
||||
/**
|
||||
* @param OutputInterface $output
|
||||
*/
|
||||
public function __construct(OutputInterface $output)
|
||||
{
|
||||
$this->output = $output;
|
||||
@@ -145,4 +143,13 @@ abstract class OutputStyle implements OutputInterface, StyleInterface
|
||||
{
|
||||
return $this->output->isDebug();
|
||||
}
|
||||
|
||||
protected function getErrorOutput()
|
||||
{
|
||||
if (!$this->output instanceof ConsoleOutputInterface) {
|
||||
return $this->output;
|
||||
}
|
||||
|
||||
return $this->output->getErrorOutput();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,8 +34,6 @@ interface StyleInterface
|
||||
|
||||
/**
|
||||
* Formats a list.
|
||||
*
|
||||
* @param array $elements
|
||||
*/
|
||||
public function listing(array $elements);
|
||||
|
||||
@@ -83,9 +81,6 @@ interface StyleInterface
|
||||
|
||||
/**
|
||||
* Formats a table.
|
||||
*
|
||||
* @param array $headers
|
||||
* @param array $rows
|
||||
*/
|
||||
public function table(array $headers, array $rows);
|
||||
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
|
||||
namespace Symfony\Component\Console\Style;
|
||||
|
||||
use Symfony\Component\Console\Application;
|
||||
use Symfony\Component\Console\Exception\RuntimeException;
|
||||
use Symfony\Component\Console\Formatter\OutputFormatter;
|
||||
use Symfony\Component\Console\Helper\Helper;
|
||||
@@ -24,6 +23,7 @@ use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Console\Question\ChoiceQuestion;
|
||||
use Symfony\Component\Console\Question\ConfirmationQuestion;
|
||||
use Symfony\Component\Console\Question\Question;
|
||||
use Symfony\Component\Console\Terminal;
|
||||
|
||||
/**
|
||||
* Output decorator helpers for the Symfony Style Guide.
|
||||
@@ -40,16 +40,13 @@ class SymfonyStyle extends OutputStyle
|
||||
private $lineLength;
|
||||
private $bufferedOutput;
|
||||
|
||||
/**
|
||||
* @param InputInterface $input
|
||||
* @param OutputInterface $output
|
||||
*/
|
||||
public function __construct(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$this->input = $input;
|
||||
$this->bufferedOutput = new BufferedOutput($output->getVerbosity(), false, clone $output->getFormatter());
|
||||
// Windows cmd wraps lines as soon as the terminal width is reached, whether there are following chars or not.
|
||||
$this->lineLength = min($this->getTerminalWidth() - (int) (DIRECTORY_SEPARATOR === '\\'), self::MAX_LINE_LENGTH);
|
||||
$width = (new Terminal())->getWidth() ?: self::MAX_LINE_LENGTH;
|
||||
$this->lineLength = min($width - (int) (DIRECTORY_SEPARATOR === '\\'), self::MAX_LINE_LENGTH);
|
||||
|
||||
parent::__construct($output);
|
||||
}
|
||||
@@ -62,13 +59,14 @@ class SymfonyStyle extends OutputStyle
|
||||
* @param string|null $style The style to apply to the whole block
|
||||
* @param string $prefix The prefix for the block
|
||||
* @param bool $padding Whether to add vertical padding
|
||||
* @param bool $escape Whether to escape the message
|
||||
*/
|
||||
public function block($messages, $type = null, $style = null, $prefix = ' ', $padding = false)
|
||||
public function block($messages, $type = null, $style = null, $prefix = ' ', $padding = false, $escape = true)
|
||||
{
|
||||
$messages = is_array($messages) ? array_values($messages) : array($messages);
|
||||
|
||||
$this->autoPrependBlock();
|
||||
$this->writeln($this->createBlock($messages, $type, $style, $prefix, $padding, true));
|
||||
$this->writeln($this->createBlock($messages, $type, $style, $prefix, $padding, $escape));
|
||||
$this->newLine();
|
||||
}
|
||||
|
||||
@@ -79,7 +77,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();
|
||||
@@ -92,7 +90,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();
|
||||
@@ -132,11 +130,7 @@ class SymfonyStyle extends OutputStyle
|
||||
*/
|
||||
public function comment($message)
|
||||
{
|
||||
$messages = is_array($message) ? array_values($message) : array($message);
|
||||
|
||||
$this->autoPrependBlock();
|
||||
$this->writeln($this->createBlock($messages, null, null, '<fg=default;bg=default> // </>'));
|
||||
$this->newLine();
|
||||
$this->block($message, null, null, '<fg=default;bg=default> // </>', false, false);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -285,8 +279,6 @@ class SymfonyStyle extends OutputStyle
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Question $question
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function askQuestion(Question $question)
|
||||
@@ -336,6 +328,16 @@ class SymfonyStyle extends OutputStyle
|
||||
$this->bufferedOutput->write(str_repeat("\n", $count));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new instance which makes use of stderr if available.
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function getErrorStyle()
|
||||
{
|
||||
return new self($this->input, $this->getErrorOutput());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ProgressBar
|
||||
*/
|
||||
@@ -348,14 +350,6 @@ class SymfonyStyle extends OutputStyle
|
||||
return $this->progressBar;
|
||||
}
|
||||
|
||||
private function getTerminalWidth()
|
||||
{
|
||||
$application = new Application();
|
||||
$dimensions = $application->getTerminalDimensions();
|
||||
|
||||
return $dimensions[0] ?: self::MAX_LINE_LENGTH;
|
||||
}
|
||||
|
||||
private function autoPrependBlock()
|
||||
{
|
||||
$chars = substr(str_replace(PHP_EOL, "\n", $this->bufferedOutput->fetch()), -2);
|
||||
|
||||
137
lib/composer/vendor/symfony/console/Terminal.php
vendored
Normal file
137
lib/composer/vendor/symfony/console/Terminal.php
vendored
Normal file
@@ -0,0 +1,137 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Console;
|
||||
|
||||
class Terminal
|
||||
{
|
||||
private static $width;
|
||||
private static $height;
|
||||
|
||||
/**
|
||||
* Gets the terminal width.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getWidth()
|
||||
{
|
||||
$width = getenv('COLUMNS');
|
||||
if (false !== $width) {
|
||||
return (int) trim($width);
|
||||
}
|
||||
|
||||
if (null === self::$width) {
|
||||
self::initDimensions();
|
||||
}
|
||||
|
||||
return self::$width ?: 80;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the terminal height.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getHeight()
|
||||
{
|
||||
$height = getenv('LINES');
|
||||
if (false !== $height) {
|
||||
return (int) trim($height);
|
||||
}
|
||||
|
||||
if (null === self::$height) {
|
||||
self::initDimensions();
|
||||
}
|
||||
|
||||
return self::$height ?: 50;
|
||||
}
|
||||
|
||||
private static function initDimensions()
|
||||
{
|
||||
if ('\\' === DIRECTORY_SEPARATOR) {
|
||||
if (preg_match('/^(\d+)x(\d+)(?: \((\d+)x(\d+)\))?$/', trim(getenv('ANSICON')), $matches)) {
|
||||
// extract [w, H] from "wxh (WxH)"
|
||||
// or [w, h] from "wxh"
|
||||
self::$width = (int) $matches[1];
|
||||
self::$height = isset($matches[4]) ? (int) $matches[4] : (int) $matches[2];
|
||||
} elseif (null !== $dimensions = self::getConsoleMode()) {
|
||||
// extract [w, h] from "wxh"
|
||||
self::$width = (int) $dimensions[0];
|
||||
self::$height = (int) $dimensions[1];
|
||||
}
|
||||
} elseif ($sttyString = self::getSttyColumns()) {
|
||||
if (preg_match('/rows.(\d+);.columns.(\d+);/i', $sttyString, $matches)) {
|
||||
// extract [w, h] from "rows h; columns w;"
|
||||
self::$width = (int) $matches[2];
|
||||
self::$height = (int) $matches[1];
|
||||
} elseif (preg_match('/;.(\d+).rows;.(\d+).columns/i', $sttyString, $matches)) {
|
||||
// extract [w, h] from "; h rows; w columns"
|
||||
self::$width = (int) $matches[2];
|
||||
self::$height = (int) $matches[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs and parses mode CON if it's available, suppressing any error output.
|
||||
*
|
||||
* @return int[]|null An array composed of the width and the height or null if it could not be parsed
|
||||
*/
|
||||
private static function getConsoleMode()
|
||||
{
|
||||
if (!function_exists('proc_open')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$descriptorspec = array(
|
||||
1 => array('pipe', 'w'),
|
||||
2 => array('pipe', 'w'),
|
||||
);
|
||||
$process = proc_open('mode CON', $descriptorspec, $pipes, null, null, array('suppress_errors' => true));
|
||||
if (is_resource($process)) {
|
||||
$info = stream_get_contents($pipes[1]);
|
||||
fclose($pipes[1]);
|
||||
fclose($pipes[2]);
|
||||
proc_close($process);
|
||||
|
||||
if (preg_match('/--------+\r?\n.+?(\d+)\r?\n.+?(\d+)\r?\n/', $info, $matches)) {
|
||||
return array((int) $matches[2], (int) $matches[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs and parses stty -a if it's available, suppressing any error output.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
private static function getSttyColumns()
|
||||
{
|
||||
if (!function_exists('proc_open')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$descriptorspec = array(
|
||||
1 => array('pipe', 'w'),
|
||||
2 => array('pipe', 'w'),
|
||||
);
|
||||
|
||||
$process = proc_open('stty -a | grep columns', $descriptorspec, $pipes, null, null, array('suppress_errors' => true));
|
||||
if (is_resource($process)) {
|
||||
$info = stream_get_contents($pipes[1]);
|
||||
fclose($pipes[1]);
|
||||
fclose($pipes[2]);
|
||||
proc_close($process);
|
||||
|
||||
return $info;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -21,19 +21,16 @@ use Symfony\Component\Console\Output\OutputInterface;
|
||||
* Eases the testing of console commands.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
* @author Robin Chalas <robin.chalas@gmail.com>
|
||||
*/
|
||||
class CommandTester
|
||||
{
|
||||
private $command;
|
||||
private $input;
|
||||
private $output;
|
||||
private $inputs = array();
|
||||
private $statusCode;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param Command $command A Command instance to test
|
||||
*/
|
||||
public function __construct(Command $command)
|
||||
{
|
||||
$this->command = $command;
|
||||
@@ -65,14 +62,16 @@ class CommandTester
|
||||
}
|
||||
|
||||
$this->input = new ArrayInput($input);
|
||||
if ($this->inputs) {
|
||||
$this->input->setStream(self::createStream($this->inputs));
|
||||
}
|
||||
|
||||
if (isset($options['interactive'])) {
|
||||
$this->input->setInteractive($options['interactive']);
|
||||
}
|
||||
|
||||
$this->output = new StreamOutput(fopen('php://memory', 'w', false));
|
||||
if (isset($options['decorated'])) {
|
||||
$this->output->setDecorated($options['decorated']);
|
||||
}
|
||||
$this->output->setDecorated(isset($options['decorated']) ? $options['decorated'] : false);
|
||||
if (isset($options['verbosity'])) {
|
||||
$this->output->setVerbosity($options['verbosity']);
|
||||
}
|
||||
@@ -129,4 +128,29 @@ class CommandTester
|
||||
{
|
||||
return $this->statusCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the user inputs.
|
||||
*
|
||||
* @param array $inputs An array of strings representing each input
|
||||
* passed to the command input stream
|
||||
*
|
||||
* @return CommandTester
|
||||
*/
|
||||
public function setInputs(array $inputs)
|
||||
{
|
||||
$this->inputs = $inputs;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
private static function createStream(array $inputs)
|
||||
{
|
||||
$stream = fopen('php://memory', 'r+', false);
|
||||
|
||||
fwrite($stream, implode(PHP_EOL, $inputs));
|
||||
rewind($stream);
|
||||
|
||||
return $stream;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,11 @@
|
||||
|
||||
namespace Symfony\Component\Console\Tests;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\Console\Application;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\CommandLoader\FactoryCommandLoader;
|
||||
use Symfony\Component\Console\DependencyInjection\AddConsoleCommandPass;
|
||||
use Symfony\Component\Console\Helper\HelperSet;
|
||||
use Symfony\Component\Console\Helper\FormatterHelper;
|
||||
use Symfony\Component\Console\Input\ArgvInput;
|
||||
@@ -26,11 +30,14 @@ use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Console\Output\StreamOutput;
|
||||
use Symfony\Component\Console\Tester\ApplicationTester;
|
||||
use Symfony\Component\Console\Event\ConsoleCommandEvent;
|
||||
use Symfony\Component\Console\Event\ConsoleErrorEvent;
|
||||
use Symfony\Component\Console\Event\ConsoleExceptionEvent;
|
||||
use Symfony\Component\Console\Event\ConsoleTerminateEvent;
|
||||
use Symfony\Component\Console\Exception\CommandNotFoundException;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcher;
|
||||
|
||||
class ApplicationTest extends \PHPUnit_Framework_TestCase
|
||||
class ApplicationTest extends TestCase
|
||||
{
|
||||
protected static $fixturesPath;
|
||||
|
||||
@@ -38,15 +45,20 @@ class ApplicationTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
self::$fixturesPath = realpath(__DIR__.'/Fixtures/');
|
||||
require_once self::$fixturesPath.'/FooCommand.php';
|
||||
require_once self::$fixturesPath.'/FooOptCommand.php';
|
||||
require_once self::$fixturesPath.'/Foo1Command.php';
|
||||
require_once self::$fixturesPath.'/Foo2Command.php';
|
||||
require_once self::$fixturesPath.'/Foo3Command.php';
|
||||
require_once self::$fixturesPath.'/Foo4Command.php';
|
||||
require_once self::$fixturesPath.'/Foo5Command.php';
|
||||
require_once self::$fixturesPath.'/FooSameCaseUppercaseCommand.php';
|
||||
require_once self::$fixturesPath.'/FooSameCaseLowercaseCommand.php';
|
||||
require_once self::$fixturesPath.'/FoobarCommand.php';
|
||||
require_once self::$fixturesPath.'/BarBucCommand.php';
|
||||
require_once self::$fixturesPath.'/FooSubnamespaced1Command.php';
|
||||
require_once self::$fixturesPath.'/FooSubnamespaced2Command.php';
|
||||
require_once self::$fixturesPath.'/TestTiti.php';
|
||||
require_once self::$fixturesPath.'/TestToto.php';
|
||||
}
|
||||
|
||||
protected function normalizeLineBreaks($text)
|
||||
@@ -91,7 +103,7 @@ class ApplicationTest extends \PHPUnit_Framework_TestCase
|
||||
public function testGetLongVersion()
|
||||
{
|
||||
$application = new Application('foo', 'bar');
|
||||
$this->assertEquals('<info>foo</info> version <comment>bar</comment>', $application->getLongVersion(), '->getLongVersion() returns the long version of the application');
|
||||
$this->assertEquals('foo <info>bar</info>', $application->getLongVersion(), '->getLongVersion() returns the long version of the application');
|
||||
}
|
||||
|
||||
public function testHelp()
|
||||
@@ -111,6 +123,25 @@ class ApplicationTest extends \PHPUnit_Framework_TestCase
|
||||
$this->assertCount(1, $commands, '->all() takes a namespace as its first argument');
|
||||
}
|
||||
|
||||
public function testAllWithCommandLoader()
|
||||
{
|
||||
$application = new Application();
|
||||
$commands = $application->all();
|
||||
$this->assertInstanceOf('Symfony\\Component\\Console\\Command\\HelpCommand', $commands['help'], '->all() returns the registered commands');
|
||||
|
||||
$application->add(new \FooCommand());
|
||||
$commands = $application->all('foo');
|
||||
$this->assertCount(1, $commands, '->all() takes a namespace as its first argument');
|
||||
|
||||
$application->setCommandLoader(new FactoryCommandLoader(array(
|
||||
'foo:bar1' => function () { return new \Foo1Command(); },
|
||||
)));
|
||||
$commands = $application->all('foo');
|
||||
$this->assertCount(2, $commands, '->all() takes a namespace as its first argument');
|
||||
$this->assertInstanceOf(\FooCommand::class, $commands['foo:bar'], '->all() returns the registered commands');
|
||||
$this->assertInstanceOf(\Foo1Command::class, $commands['foo:bar1'], '->all() returns the registered commands');
|
||||
}
|
||||
|
||||
public function testRegister()
|
||||
{
|
||||
$application = new Application();
|
||||
@@ -163,6 +194,30 @@ class ApplicationTest extends \PHPUnit_Framework_TestCase
|
||||
$this->assertInstanceOf('Symfony\Component\Console\Command\HelpCommand', $command, '->get() returns the help command if --help is provided as the input');
|
||||
}
|
||||
|
||||
public function testHasGetWithCommandLoader()
|
||||
{
|
||||
$application = new Application();
|
||||
$this->assertTrue($application->has('list'), '->has() returns true if a named command is registered');
|
||||
$this->assertFalse($application->has('afoobar'), '->has() returns false if a named command is not registered');
|
||||
|
||||
$application->add($foo = new \FooCommand());
|
||||
$this->assertTrue($application->has('afoobar'), '->has() returns true if an alias is registered');
|
||||
$this->assertEquals($foo, $application->get('foo:bar'), '->get() returns a command by name');
|
||||
$this->assertEquals($foo, $application->get('afoobar'), '->get() returns a command by alias');
|
||||
|
||||
$application->setCommandLoader(new FactoryCommandLoader(array(
|
||||
'foo:bar1' => function () { return new \Foo1Command(); },
|
||||
)));
|
||||
|
||||
$this->assertTrue($application->has('afoobar'), '->has() returns true if an instance is registered for an alias even with command loader');
|
||||
$this->assertEquals($foo, $application->get('foo:bar'), '->get() returns an instance by name even with command loader');
|
||||
$this->assertEquals($foo, $application->get('afoobar'), '->get() returns an instance by alias even with command loader');
|
||||
$this->assertTrue($application->has('foo:bar1'), '->has() returns true for commands registered in the loader');
|
||||
$this->assertInstanceOf(\Foo1Command::class, $foo1 = $application->get('foo:bar1'), '->get() returns a command by name from the command loader');
|
||||
$this->assertTrue($application->has('afoobar1'), '->has() returns true for commands registered in the loader');
|
||||
$this->assertEquals($foo1, $application->get('afoobar1'), '->get() returns a command by name from the command loader');
|
||||
}
|
||||
|
||||
public function testSilentHelp()
|
||||
{
|
||||
$application = new Application();
|
||||
@@ -211,19 +266,33 @@ class ApplicationTest extends \PHPUnit_Framework_TestCase
|
||||
$this->assertEquals('foo', $application->findNamespace('foo'), '->findNamespace() returns commands even if the commands are only contained in subnamespaces');
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\Console\Exception\CommandNotFoundException
|
||||
* @expectedExceptionMessage The namespace "f" is ambiguous (foo, foo1).
|
||||
*/
|
||||
public function testFindAmbiguousNamespace()
|
||||
{
|
||||
$application = new Application();
|
||||
$application->add(new \BarBucCommand());
|
||||
$application->add(new \FooCommand());
|
||||
$application->add(new \Foo2Command());
|
||||
|
||||
$expectedMsg = "The namespace \"f\" is ambiguous.\nDid you mean one of these?\n foo\n foo1";
|
||||
|
||||
if (method_exists($this, 'expectException')) {
|
||||
$this->expectException(CommandNotFoundException::class);
|
||||
$this->expectExceptionMessage($expectedMsg);
|
||||
} else {
|
||||
$this->setExpectedException(CommandNotFoundException::class, $expectedMsg);
|
||||
}
|
||||
|
||||
$application->findNamespace('f');
|
||||
}
|
||||
|
||||
public function testFindNonAmbiguous()
|
||||
{
|
||||
$application = new Application();
|
||||
$application->add(new \TestTiti());
|
||||
$application->add(new \TestToto());
|
||||
$this->assertEquals('test-toto', $application->find('test')->getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\Console\Exception\CommandNotFoundException
|
||||
* @expectedExceptionMessage There are no commands defined in the "bar" namespace.
|
||||
@@ -260,12 +329,66 @@ class ApplicationTest extends \PHPUnit_Framework_TestCase
|
||||
$this->assertInstanceOf('FooCommand', $application->find('a'), '->find() returns a command if the abbreviation exists for an alias');
|
||||
}
|
||||
|
||||
public function testFindCaseSensitiveFirst()
|
||||
{
|
||||
$application = new Application();
|
||||
$application->add(new \FooSameCaseUppercaseCommand());
|
||||
$application->add(new \FooSameCaseLowercaseCommand());
|
||||
|
||||
$this->assertInstanceOf('FooSameCaseUppercaseCommand', $application->find('f:B'), '->find() returns a command if the abbreviation is the correct case');
|
||||
$this->assertInstanceOf('FooSameCaseUppercaseCommand', $application->find('f:BAR'), '->find() returns a command if the abbreviation is the correct case');
|
||||
$this->assertInstanceOf('FooSameCaseLowercaseCommand', $application->find('f:b'), '->find() returns a command if the abbreviation is the correct case');
|
||||
$this->assertInstanceOf('FooSameCaseLowercaseCommand', $application->find('f:bar'), '->find() returns a command if the abbreviation is the correct case');
|
||||
}
|
||||
|
||||
public function testFindCaseInsensitiveAsFallback()
|
||||
{
|
||||
$application = new Application();
|
||||
$application->add(new \FooSameCaseLowercaseCommand());
|
||||
|
||||
$this->assertInstanceOf('FooSameCaseLowercaseCommand', $application->find('f:b'), '->find() returns a command if the abbreviation is the correct case');
|
||||
$this->assertInstanceOf('FooSameCaseLowercaseCommand', $application->find('f:B'), '->find() will fallback to case insensitivity');
|
||||
$this->assertInstanceOf('FooSameCaseLowercaseCommand', $application->find('FoO:BaR'), '->find() will fallback to case insensitivity');
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\Console\Exception\CommandNotFoundException
|
||||
* @expectedExceptionMessage Command "FoO:BaR" is ambiguous
|
||||
*/
|
||||
public function testFindCaseInsensitiveSuggestions()
|
||||
{
|
||||
$application = new Application();
|
||||
$application->add(new \FooSameCaseLowercaseCommand());
|
||||
$application->add(new \FooSameCaseUppercaseCommand());
|
||||
|
||||
$this->assertInstanceOf('FooSameCaseLowercaseCommand', $application->find('FoO:BaR'), '->find() will find two suggestions with case insensitivity');
|
||||
}
|
||||
|
||||
public function testFindWithCommandLoader()
|
||||
{
|
||||
$application = new Application();
|
||||
$application->setCommandLoader(new FactoryCommandLoader(array(
|
||||
'foo:bar' => $f = function () { return new \FooCommand(); },
|
||||
)));
|
||||
|
||||
$this->assertInstanceOf('FooCommand', $application->find('foo:bar'), '->find() returns a command if its name exists');
|
||||
$this->assertInstanceOf('Symfony\Component\Console\Command\HelpCommand', $application->find('h'), '->find() returns a command if its name exists');
|
||||
$this->assertInstanceOf('FooCommand', $application->find('f:bar'), '->find() returns a command if the abbreviation for the namespace exists');
|
||||
$this->assertInstanceOf('FooCommand', $application->find('f:b'), '->find() returns a command if the abbreviation for the namespace and the command name exist');
|
||||
$this->assertInstanceOf('FooCommand', $application->find('a'), '->find() returns a command if the abbreviation exists for an alias');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideAmbiguousAbbreviations
|
||||
*/
|
||||
public function testFindWithAmbiguousAbbreviations($abbreviation, $expectedExceptionMessage)
|
||||
{
|
||||
$this->setExpectedException('Symfony\Component\Console\Exception\CommandNotFoundException', $expectedExceptionMessage);
|
||||
if (method_exists($this, 'expectException')) {
|
||||
$this->expectException('Symfony\Component\Console\Exception\CommandNotFoundException');
|
||||
$this->expectExceptionMessage($expectedExceptionMessage);
|
||||
} else {
|
||||
$this->setExpectedException('Symfony\Component\Console\Exception\CommandNotFoundException', $expectedExceptionMessage);
|
||||
}
|
||||
|
||||
$application = new Application();
|
||||
$application->add(new \FooCommand());
|
||||
@@ -279,8 +402,20 @@ class ApplicationTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
return array(
|
||||
array('f', 'Command "f" is not defined.'),
|
||||
array('a', 'Command "a" is ambiguous (afoobar, afoobar1 and 1 more).'),
|
||||
array('foo:b', 'Command "foo:b" is ambiguous (foo:bar, foo:bar1 and 1 more).'),
|
||||
array(
|
||||
'a',
|
||||
"Command \"a\" is ambiguous.\nDid you mean one of these?\n".
|
||||
" afoobar The foo:bar command\n".
|
||||
" afoobar1 The foo:bar1 command\n".
|
||||
' afoobar2 The foo1:bar command',
|
||||
),
|
||||
array(
|
||||
'foo:b',
|
||||
"Command \"foo:b\" is ambiguous.\nDid you mean one of these?\n".
|
||||
" foo:bar The foo:bar command\n".
|
||||
" foo:bar1 The foo:bar1 command\n".
|
||||
' foo1:bar The foo1:bar command',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -326,8 +461,8 @@ class ApplicationTest extends \PHPUnit_Framework_TestCase
|
||||
public function provideInvalidCommandNamesSingle()
|
||||
{
|
||||
return array(
|
||||
array('foo3:baR'),
|
||||
array('foO3:bar'),
|
||||
array('foo3:barr'),
|
||||
array('fooo3:bar'),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -452,9 +587,39 @@ class ApplicationTest extends \PHPUnit_Framework_TestCase
|
||||
}
|
||||
}
|
||||
|
||||
public function testFindAlternativesOutput()
|
||||
{
|
||||
$application = new Application();
|
||||
|
||||
$application->add(new \FooCommand());
|
||||
$application->add(new \Foo1Command());
|
||||
$application->add(new \Foo2Command());
|
||||
$application->add(new \Foo3Command());
|
||||
|
||||
$expectedAlternatives = array(
|
||||
'afoobar',
|
||||
'afoobar1',
|
||||
'afoobar2',
|
||||
'foo1:bar',
|
||||
'foo3:bar',
|
||||
'foo:bar',
|
||||
'foo:bar1',
|
||||
);
|
||||
|
||||
try {
|
||||
$application->find('foo');
|
||||
$this->fail('->find() throws a CommandNotFoundException if command is not defined');
|
||||
} catch (\Exception $e) {
|
||||
$this->assertInstanceOf('Symfony\Component\Console\Exception\CommandNotFoundException', $e, '->find() throws a CommandNotFoundException if command is not defined');
|
||||
$this->assertSame($expectedAlternatives, $e->getAlternatives());
|
||||
|
||||
$this->assertRegExp('/Command "foo" is not defined\..*Did you mean one of these\?.*/Ums', $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function testFindNamespaceDoesNotFailOnDeepSimilarNamespaces()
|
||||
{
|
||||
$application = $this->getMock('Symfony\Component\Console\Application', array('getNamespaces'));
|
||||
$application = $this->getMockBuilder('Symfony\Component\Console\Application')->setMethods(array('getNamespaces'))->getMock();
|
||||
$application->expects($this->once())
|
||||
->method('getNamespaces')
|
||||
->will($this->returnValue(array('foo:sublong', 'bar:sub')));
|
||||
@@ -476,11 +641,9 @@ class ApplicationTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
public function testSetCatchExceptions()
|
||||
{
|
||||
$application = $this->getMock('Symfony\Component\Console\Application', array('getTerminalWidth'));
|
||||
$application = new Application();
|
||||
$application->setAutoExit(false);
|
||||
$application->expects($this->any())
|
||||
->method('getTerminalWidth')
|
||||
->will($this->returnValue(120));
|
||||
putenv('COLUMNS=120');
|
||||
$tester = new ApplicationTester($application);
|
||||
|
||||
$application->setCatchExceptions(true);
|
||||
@@ -514,11 +677,9 @@ class ApplicationTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
public function testRenderException()
|
||||
{
|
||||
$application = $this->getMock('Symfony\Component\Console\Application', array('getTerminalWidth'));
|
||||
$application = new Application();
|
||||
$application->setAutoExit(false);
|
||||
$application->expects($this->any())
|
||||
->method('getTerminalWidth')
|
||||
->will($this->returnValue(120));
|
||||
putenv('COLUMNS=120');
|
||||
$tester = new ApplicationTester($application);
|
||||
|
||||
$tester->run(array('command' => 'foo'), array('decorated' => false, 'capture_stderr_separately' => true));
|
||||
@@ -546,24 +707,21 @@ class ApplicationTest extends \PHPUnit_Framework_TestCase
|
||||
$tester->run(array('command' => 'foo3:bar'), array('decorated' => true, 'capture_stderr_separately' => true));
|
||||
$this->assertStringEqualsFile(self::$fixturesPath.'/application_renderexception3decorated.txt', $tester->getErrorOutput(true), '->renderException() renders a pretty exceptions with previous exceptions');
|
||||
|
||||
$application = $this->getMock('Symfony\Component\Console\Application', array('getTerminalWidth'));
|
||||
$application = new Application();
|
||||
$application->setAutoExit(false);
|
||||
$application->expects($this->any())
|
||||
->method('getTerminalWidth')
|
||||
->will($this->returnValue(32));
|
||||
putenv('COLUMNS=32');
|
||||
$tester = new ApplicationTester($application);
|
||||
|
||||
$tester->run(array('command' => 'foo'), array('decorated' => false, 'capture_stderr_separately' => true));
|
||||
$this->assertStringEqualsFile(self::$fixturesPath.'/application_renderexception4.txt', $tester->getErrorOutput(true), '->renderException() wraps messages when they are bigger than the terminal');
|
||||
putenv('COLUMNS=120');
|
||||
}
|
||||
|
||||
public function testRenderExceptionWithDoubleWidthCharacters()
|
||||
{
|
||||
$application = $this->getMock('Symfony\Component\Console\Application', array('getTerminalWidth'));
|
||||
$application = new Application();
|
||||
$application->setAutoExit(false);
|
||||
$application->expects($this->any())
|
||||
->method('getTerminalWidth')
|
||||
->will($this->returnValue(120));
|
||||
putenv('COLUMNS=120');
|
||||
$application->register('foo')->setCode(function () {
|
||||
throw new \Exception('エラーメッセージ');
|
||||
});
|
||||
@@ -575,17 +733,47 @@ class ApplicationTest extends \PHPUnit_Framework_TestCase
|
||||
$tester->run(array('command' => 'foo'), array('decorated' => true, 'capture_stderr_separately' => true));
|
||||
$this->assertStringEqualsFile(self::$fixturesPath.'/application_renderexception_doublewidth1decorated.txt', $tester->getErrorOutput(true), '->renderException() renders a pretty exceptions with previous exceptions');
|
||||
|
||||
$application = $this->getMock('Symfony\Component\Console\Application', array('getTerminalWidth'));
|
||||
$application = new Application();
|
||||
$application->setAutoExit(false);
|
||||
$application->expects($this->any())
|
||||
->method('getTerminalWidth')
|
||||
->will($this->returnValue(32));
|
||||
putenv('COLUMNS=32');
|
||||
$application->register('foo')->setCode(function () {
|
||||
throw new \Exception('コマンドの実行中にエラーが発生しました。');
|
||||
});
|
||||
$tester = new ApplicationTester($application);
|
||||
$tester->run(array('command' => 'foo'), array('decorated' => false, 'capture_stderr_separately' => true));
|
||||
$this->assertStringEqualsFile(self::$fixturesPath.'/application_renderexception_doublewidth2.txt', $tester->getErrorOutput(true), '->renderException() wraps messages when they are bigger than the terminal');
|
||||
putenv('COLUMNS=120');
|
||||
}
|
||||
|
||||
public function testRenderExceptionEscapesLines()
|
||||
{
|
||||
$application = new Application();
|
||||
$application->setAutoExit(false);
|
||||
putenv('COLUMNS=22');
|
||||
$application->register('foo')->setCode(function () {
|
||||
throw new \Exception('dont break here <info>!</info>');
|
||||
});
|
||||
$tester = new ApplicationTester($application);
|
||||
|
||||
$tester->run(array('command' => 'foo'), array('decorated' => false));
|
||||
$this->assertStringEqualsFile(self::$fixturesPath.'/application_renderexception_escapeslines.txt', $tester->getDisplay(true), '->renderException() escapes lines containing formatting');
|
||||
putenv('COLUMNS=120');
|
||||
}
|
||||
|
||||
public function testRenderExceptionLineBreaks()
|
||||
{
|
||||
$application = $this->getMockBuilder('Symfony\Component\Console\Application')->setMethods(array('getTerminalWidth'))->getMock();
|
||||
$application->setAutoExit(false);
|
||||
$application->expects($this->any())
|
||||
->method('getTerminalWidth')
|
||||
->will($this->returnValue(120));
|
||||
$application->register('foo')->setCode(function () {
|
||||
throw new \InvalidArgumentException("\n\nline 1 with extra spaces \nline 2\n\nline 4\n");
|
||||
});
|
||||
$tester = new ApplicationTester($application);
|
||||
|
||||
$tester->run(array('command' => 'foo'), array('decorated' => false));
|
||||
$this->assertStringEqualsFile(self::$fixturesPath.'/application_renderexception_linebreaks.txt', $tester->getDisplay(true), '->renderException() keep multiple line breaks');
|
||||
}
|
||||
|
||||
public function testRun()
|
||||
@@ -701,15 +889,19 @@ class ApplicationTest extends \PHPUnit_Framework_TestCase
|
||||
$input = new ArgvInput(array('cli.php', '-v', 'foo:bar'));
|
||||
$application->run($input, $output);
|
||||
|
||||
$this->addToAssertionCount(1);
|
||||
|
||||
$input = new ArgvInput(array('cli.php', '--verbose', 'foo:bar'));
|
||||
$application->run($input, $output);
|
||||
|
||||
$this->addToAssertionCount(1);
|
||||
}
|
||||
|
||||
public function testRunReturnsIntegerExitCode()
|
||||
{
|
||||
$exception = new \Exception('', 4);
|
||||
|
||||
$application = $this->getMock('Symfony\Component\Console\Application', array('doRun'));
|
||||
$application = $this->getMockBuilder('Symfony\Component\Console\Application')->setMethods(array('doRun'))->getMock();
|
||||
$application->setAutoExit(false);
|
||||
$application->expects($this->once())
|
||||
->method('doRun')
|
||||
@@ -724,7 +916,7 @@ class ApplicationTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
$exception = new \Exception('', 0);
|
||||
|
||||
$application = $this->getMock('Symfony\Component\Console\Application', array('doRun'));
|
||||
$application = $this->getMockBuilder('Symfony\Component\Console\Application')->setMethods(array('doRun'))->getMock();
|
||||
$application->setAutoExit(false);
|
||||
$application->expects($this->once())
|
||||
->method('doRun')
|
||||
@@ -918,7 +1110,7 @@ class ApplicationTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
/**
|
||||
* @expectedException \LogicException
|
||||
* @expectedExceptionMessage caught
|
||||
* @expectedExceptionMessage error
|
||||
*/
|
||||
public function testRunWithExceptionAndDispatcher()
|
||||
{
|
||||
@@ -949,12 +1141,155 @@ class ApplicationTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
$tester = new ApplicationTester($application);
|
||||
$tester->run(array('command' => 'foo'));
|
||||
$this->assertContains('before.foo.caught.after.', $tester->getDisplay());
|
||||
$this->assertContains('before.foo.error.after.', $tester->getDisplay());
|
||||
}
|
||||
|
||||
public function testRunDispatchesAllEventsWithExceptionInListener()
|
||||
{
|
||||
$dispatcher = $this->getDispatcher();
|
||||
$dispatcher->addListener('console.command', function () {
|
||||
throw new \RuntimeException('foo');
|
||||
});
|
||||
|
||||
$application = new Application();
|
||||
$application->setDispatcher($dispatcher);
|
||||
$application->setAutoExit(false);
|
||||
|
||||
$application->register('foo')->setCode(function (InputInterface $input, OutputInterface $output) {
|
||||
$output->write('foo.');
|
||||
});
|
||||
|
||||
$tester = new ApplicationTester($application);
|
||||
$tester->run(array('command' => 'foo'));
|
||||
$this->assertContains('before.error.after.', $tester->getDisplay());
|
||||
}
|
||||
|
||||
/**
|
||||
* @requires PHP 7
|
||||
*/
|
||||
public function testRunWithError()
|
||||
{
|
||||
$application = new Application();
|
||||
$application->setAutoExit(false);
|
||||
$application->setCatchExceptions(false);
|
||||
|
||||
$application->register('dym')->setCode(function (InputInterface $input, OutputInterface $output) {
|
||||
$output->write('dym.');
|
||||
|
||||
throw new \Error('dymerr');
|
||||
});
|
||||
|
||||
$tester = new ApplicationTester($application);
|
||||
|
||||
try {
|
||||
$tester->run(array('command' => 'dym'));
|
||||
$this->fail('Error expected.');
|
||||
} catch (\Error $e) {
|
||||
$this->assertSame('dymerr', $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function testRunAllowsErrorListenersToSilenceTheException()
|
||||
{
|
||||
$dispatcher = $this->getDispatcher();
|
||||
$dispatcher->addListener('console.error', function (ConsoleErrorEvent $event) {
|
||||
$event->getOutput()->write('silenced.');
|
||||
|
||||
$event->setExitCode(0);
|
||||
});
|
||||
|
||||
$dispatcher->addListener('console.command', function () {
|
||||
throw new \RuntimeException('foo');
|
||||
});
|
||||
|
||||
$application = new Application();
|
||||
$application->setDispatcher($dispatcher);
|
||||
$application->setAutoExit(false);
|
||||
|
||||
$application->register('foo')->setCode(function (InputInterface $input, OutputInterface $output) {
|
||||
$output->write('foo.');
|
||||
});
|
||||
|
||||
$tester = new ApplicationTester($application);
|
||||
$tester->run(array('command' => 'foo'));
|
||||
$this->assertContains('before.error.silenced.after.', $tester->getDisplay());
|
||||
$this->assertEquals(ConsoleCommandEvent::RETURN_CODE_DISABLED, $tester->getStatusCode());
|
||||
}
|
||||
|
||||
public function testConsoleErrorEventIsTriggeredOnCommandNotFound()
|
||||
{
|
||||
$dispatcher = new EventDispatcher();
|
||||
$dispatcher->addListener('console.error', function (ConsoleErrorEvent $event) {
|
||||
$this->assertNull($event->getCommand());
|
||||
$this->assertInstanceOf(CommandNotFoundException::class, $event->getError());
|
||||
$event->getOutput()->write('silenced command not found');
|
||||
});
|
||||
|
||||
$application = new Application();
|
||||
$application->setDispatcher($dispatcher);
|
||||
$application->setAutoExit(false);
|
||||
|
||||
$tester = new ApplicationTester($application);
|
||||
$tester->run(array('command' => 'unknown'));
|
||||
$this->assertContains('silenced command not found', $tester->getDisplay());
|
||||
$this->assertEquals(1, $tester->getStatusCode());
|
||||
}
|
||||
|
||||
/**
|
||||
* @group legacy
|
||||
* @expectedDeprecation The "ConsoleEvents::EXCEPTION" event is deprecated since Symfony 3.3 and will be removed in 4.0. Listen to the "ConsoleEvents::ERROR" event instead.
|
||||
*/
|
||||
public function testLegacyExceptionListenersAreStillTriggered()
|
||||
{
|
||||
$dispatcher = $this->getDispatcher();
|
||||
$dispatcher->addListener('console.exception', function (ConsoleExceptionEvent $event) {
|
||||
$event->getOutput()->write('caught.');
|
||||
|
||||
$event->setException(new \RuntimeException('replaced in caught.'));
|
||||
});
|
||||
|
||||
$application = new Application();
|
||||
$application->setDispatcher($dispatcher);
|
||||
$application->setAutoExit(false);
|
||||
|
||||
$application->register('foo')->setCode(function (InputInterface $input, OutputInterface $output) {
|
||||
throw new \RuntimeException('foo');
|
||||
});
|
||||
|
||||
$tester = new ApplicationTester($application);
|
||||
$tester->run(array('command' => 'foo'));
|
||||
$this->assertContains('before.caught.error.after.', $tester->getDisplay());
|
||||
$this->assertContains('replaced in caught.', $tester->getDisplay());
|
||||
}
|
||||
|
||||
/**
|
||||
* @requires PHP 7
|
||||
*/
|
||||
public function testErrorIsRethrownIfNotHandledByConsoleErrorEvent()
|
||||
{
|
||||
$application = new Application();
|
||||
$application->setAutoExit(false);
|
||||
$application->setCatchExceptions(false);
|
||||
$application->setDispatcher(new EventDispatcher());
|
||||
|
||||
$application->register('dym')->setCode(function (InputInterface $input, OutputInterface $output) {
|
||||
new \UnknownClass();
|
||||
});
|
||||
|
||||
$tester = new ApplicationTester($application);
|
||||
|
||||
try {
|
||||
$tester->run(array('command' => 'dym'));
|
||||
$this->fail('->run() should rethrow PHP errors if not handled via ConsoleErrorEvent.');
|
||||
} catch (\Error $e) {
|
||||
$this->assertSame($e->getMessage(), 'Class \'UnknownClass\' not found');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @requires PHP 7
|
||||
* @expectedException \LogicException
|
||||
* @expectedExceptionMessage caught
|
||||
* @expectedExceptionMessage error
|
||||
*/
|
||||
public function testRunWithErrorAndDispatcher()
|
||||
{
|
||||
@@ -971,9 +1306,12 @@ class ApplicationTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
$tester = new ApplicationTester($application);
|
||||
$tester->run(array('command' => 'dym'));
|
||||
$this->assertContains('before.dym.caught.after.', $tester->getDisplay(), 'The PHP Error did not dispached events');
|
||||
$this->assertContains('before.dym.error.after.', $tester->getDisplay(), 'The PHP Error did not dispached events');
|
||||
}
|
||||
|
||||
/**
|
||||
* @requires PHP 7
|
||||
*/
|
||||
public function testRunDispatchesAllEventsWithError()
|
||||
{
|
||||
$application = new Application();
|
||||
@@ -988,9 +1326,12 @@ class ApplicationTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
$tester = new ApplicationTester($application);
|
||||
$tester->run(array('command' => 'dym'));
|
||||
$this->assertContains('before.dym.caught.after.', $tester->getDisplay(), 'The PHP Error did not dispached events');
|
||||
$this->assertContains('before.dym.error.after.', $tester->getDisplay(), 'The PHP Error did not dispached events');
|
||||
}
|
||||
|
||||
/**
|
||||
* @requires PHP 7
|
||||
*/
|
||||
public function testRunWithErrorFailingStatusCode()
|
||||
{
|
||||
$application = new Application();
|
||||
@@ -1081,6 +1422,9 @@ class ApplicationTest extends \PHPUnit_Framework_TestCase
|
||||
$this->assertEquals('some test value', $extraValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group legacy
|
||||
*/
|
||||
public function testTerminalDimensions()
|
||||
{
|
||||
$application = new Application();
|
||||
@@ -1096,6 +1440,132 @@ class ApplicationTest extends \PHPUnit_Framework_TestCase
|
||||
$this->assertSame(array($width, 80), $application->getTerminalDimensions());
|
||||
}
|
||||
|
||||
public function testSetRunCustomDefaultCommand()
|
||||
{
|
||||
$command = new \FooCommand();
|
||||
|
||||
$application = new Application();
|
||||
$application->setAutoExit(false);
|
||||
$application->add($command);
|
||||
$application->setDefaultCommand($command->getName());
|
||||
|
||||
$tester = new ApplicationTester($application);
|
||||
$tester->run(array(), array('interactive' => false));
|
||||
$this->assertEquals('called'.PHP_EOL, $tester->getDisplay(), 'Application runs the default set command if different from \'list\' command');
|
||||
|
||||
$application = new CustomDefaultCommandApplication();
|
||||
$application->setAutoExit(false);
|
||||
|
||||
$tester = new ApplicationTester($application);
|
||||
$tester->run(array(), array('interactive' => false));
|
||||
|
||||
$this->assertEquals('called'.PHP_EOL, $tester->getDisplay(), 'Application runs the default set command if different from \'list\' command');
|
||||
}
|
||||
|
||||
public function testSetRunCustomDefaultCommandWithOption()
|
||||
{
|
||||
$command = new \FooOptCommand();
|
||||
|
||||
$application = new Application();
|
||||
$application->setAutoExit(false);
|
||||
$application->add($command);
|
||||
$application->setDefaultCommand($command->getName());
|
||||
|
||||
$tester = new ApplicationTester($application);
|
||||
$tester->run(array('--fooopt' => 'opt'), array('interactive' => false));
|
||||
|
||||
$this->assertEquals('called'.PHP_EOL.'opt'.PHP_EOL, $tester->getDisplay(), 'Application runs the default set command if different from \'list\' command');
|
||||
}
|
||||
|
||||
public function testSetRunCustomSingleCommand()
|
||||
{
|
||||
$command = new \FooCommand();
|
||||
|
||||
$application = new Application();
|
||||
$application->setAutoExit(false);
|
||||
$application->add($command);
|
||||
$application->setDefaultCommand($command->getName(), true);
|
||||
|
||||
$tester = new ApplicationTester($application);
|
||||
|
||||
$tester->run(array());
|
||||
$this->assertContains('called', $tester->getDisplay());
|
||||
|
||||
$tester->run(array('--help' => true));
|
||||
$this->assertContains('The foo:bar command', $tester->getDisplay());
|
||||
}
|
||||
|
||||
/**
|
||||
* @requires function posix_isatty
|
||||
*/
|
||||
public function testCanCheckIfTerminalIsInteractive()
|
||||
{
|
||||
$application = new CustomDefaultCommandApplication();
|
||||
$application->setAutoExit(false);
|
||||
|
||||
$tester = new ApplicationTester($application);
|
||||
$tester->run(array('command' => 'help'));
|
||||
|
||||
$this->assertFalse($tester->getInput()->hasParameterOption(array('--no-interaction', '-n')));
|
||||
|
||||
$inputStream = $tester->getInput()->getStream();
|
||||
$this->assertEquals($tester->getInput()->isInteractive(), @posix_isatty($inputStream));
|
||||
}
|
||||
|
||||
public function testRunLazyCommandService()
|
||||
{
|
||||
$container = new ContainerBuilder();
|
||||
$container->addCompilerPass(new AddConsoleCommandPass());
|
||||
$container
|
||||
->register('lazy-command', LazyCommand::class)
|
||||
->addTag('console.command', array('command' => 'lazy:command'))
|
||||
->addTag('console.command', array('command' => 'lazy:alias'))
|
||||
->addTag('console.command', array('command' => 'lazy:alias2'));
|
||||
$container->compile();
|
||||
|
||||
$application = new Application();
|
||||
$application->setCommandLoader($container->get('console.command_loader'));
|
||||
$application->setAutoExit(false);
|
||||
|
||||
$tester = new ApplicationTester($application);
|
||||
|
||||
$tester->run(array('command' => 'lazy:command'));
|
||||
$this->assertSame("lazy-command called\n", $tester->getDisplay(true));
|
||||
|
||||
$tester->run(array('command' => 'lazy:alias'));
|
||||
$this->assertSame("lazy-command called\n", $tester->getDisplay(true));
|
||||
|
||||
$tester->run(array('command' => 'lazy:alias2'));
|
||||
$this->assertSame("lazy-command called\n", $tester->getDisplay(true));
|
||||
|
||||
$command = $application->get('lazy:command');
|
||||
$this->assertSame(array('lazy:alias', 'lazy:alias2'), $command->getAliases());
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\Console\Exception\CommandNotFoundException
|
||||
*/
|
||||
public function testGetDisabledLazyCommand()
|
||||
{
|
||||
$application = new Application();
|
||||
$application->setCommandLoader(new FactoryCommandLoader(array('disabled' => function () { return new DisabledCommand(); })));
|
||||
$application->get('disabled');
|
||||
}
|
||||
|
||||
public function testHasReturnsFalseForDisabledLazyCommand()
|
||||
{
|
||||
$application = new Application();
|
||||
$application->setCommandLoader(new FactoryCommandLoader(array('disabled' => function () { return new DisabledCommand(); })));
|
||||
$this->assertFalse($application->has('disabled'));
|
||||
}
|
||||
|
||||
public function testAllExcludesDisabledLazyCommand()
|
||||
{
|
||||
$application = new Application();
|
||||
$application->setCommandLoader(new FactoryCommandLoader(array('disabled' => function () { return new DisabledCommand(); })));
|
||||
$this->assertArrayNotHasKey('disabled', $application->all());
|
||||
}
|
||||
|
||||
protected function getDispatcher($skipCommand = false)
|
||||
{
|
||||
$dispatcher = new EventDispatcher();
|
||||
@@ -1110,55 +1580,46 @@ class ApplicationTest extends \PHPUnit_Framework_TestCase
|
||||
$event->getOutput()->writeln('after.');
|
||||
|
||||
if (!$skipCommand) {
|
||||
$event->setExitCode(113);
|
||||
$event->setExitCode(ConsoleCommandEvent::RETURN_CODE_DISABLED);
|
||||
}
|
||||
});
|
||||
$dispatcher->addListener('console.exception', function (ConsoleExceptionEvent $event) {
|
||||
$event->getOutput()->write('caught.');
|
||||
$dispatcher->addListener('console.error', function (ConsoleErrorEvent $event) {
|
||||
$event->getOutput()->write('error.');
|
||||
|
||||
$event->setException(new \LogicException('caught.', $event->getExitCode(), $event->getException()));
|
||||
$event->setError(new \LogicException('error.', $event->getExitCode(), $event->getError()));
|
||||
});
|
||||
|
||||
return $dispatcher;
|
||||
}
|
||||
|
||||
public function testSetRunCustomDefaultCommand()
|
||||
/**
|
||||
* @requires PHP 7
|
||||
*/
|
||||
public function testErrorIsRethrownIfNotHandledByConsoleErrorEventWithCatchingEnabled()
|
||||
{
|
||||
$command = new \FooCommand();
|
||||
|
||||
$application = new Application();
|
||||
$application->setAutoExit(false);
|
||||
$application->add($command);
|
||||
$application->setDefaultCommand($command->getName());
|
||||
$application->setDispatcher(new EventDispatcher());
|
||||
|
||||
$application->register('dym')->setCode(function (InputInterface $input, OutputInterface $output) {
|
||||
new \UnknownClass();
|
||||
});
|
||||
|
||||
$tester = new ApplicationTester($application);
|
||||
$tester->run(array());
|
||||
$this->assertEquals('interact called'.PHP_EOL.'called'.PHP_EOL, $tester->getDisplay(), 'Application runs the default set command if different from \'list\' command');
|
||||
|
||||
$application = new CustomDefaultCommandApplication();
|
||||
$application->setAutoExit(false);
|
||||
|
||||
$tester = new ApplicationTester($application);
|
||||
$tester->run(array());
|
||||
|
||||
$this->assertEquals('interact called'.PHP_EOL.'called'.PHP_EOL, $tester->getDisplay(), 'Application runs the default set command if different from \'list\' command');
|
||||
try {
|
||||
$tester->run(array('command' => 'dym'));
|
||||
$this->fail('->run() should rethrow PHP errors if not handled via ConsoleErrorEvent.');
|
||||
} catch (\Error $e) {
|
||||
$this->assertSame($e->getMessage(), 'Class \'UnknownClass\' not found');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @requires function posix_isatty
|
||||
*/
|
||||
public function testCanCheckIfTerminalIsInteractive()
|
||||
protected function tearDown()
|
||||
{
|
||||
$application = new CustomDefaultCommandApplication();
|
||||
$application->setAutoExit(false);
|
||||
|
||||
$tester = new ApplicationTester($application);
|
||||
$tester->run(array('command' => 'help'));
|
||||
|
||||
$this->assertFalse($tester->getInput()->hasParameterOption(array('--no-interaction', '-n')));
|
||||
|
||||
$inputStream = $application->getHelperSet()->get('question')->getInputStream();
|
||||
$this->assertEquals($tester->getInput()->isInteractive(), @posix_isatty($inputStream));
|
||||
putenv('SHELL_VERBOSITY');
|
||||
unset($_ENV['SHELL_VERBOSITY']);
|
||||
unset($_SERVER['SHELL_VERBOSITY']);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1199,3 +1660,19 @@ class CustomDefaultCommandApplication extends Application
|
||||
$this->setDefaultCommand($command->getName());
|
||||
}
|
||||
}
|
||||
|
||||
class LazyCommand extends Command
|
||||
{
|
||||
public function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$output->writeln('lazy-command called');
|
||||
}
|
||||
}
|
||||
|
||||
class DisabledCommand extends Command
|
||||
{
|
||||
public function isEnabled()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
namespace Symfony\Component\Console\Tests\Command;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Helper\FormatterHelper;
|
||||
use Symfony\Component\Console\Application;
|
||||
@@ -23,7 +24,7 @@ use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Console\Output\NullOutput;
|
||||
use Symfony\Component\Console\Tester\CommandTester;
|
||||
|
||||
class CommandTest extends \PHPUnit_Framework_TestCase
|
||||
class CommandTest extends TestCase
|
||||
{
|
||||
protected static $fixturesPath;
|
||||
|
||||
@@ -45,7 +46,7 @@ class CommandTest extends \PHPUnit_Framework_TestCase
|
||||
*/
|
||||
public function testCommandNameCannotBeEmpty()
|
||||
{
|
||||
new Command();
|
||||
(new Application())->add(new Command());
|
||||
}
|
||||
|
||||
public function testSetApplication()
|
||||
@@ -54,6 +55,14 @@ class CommandTest extends \PHPUnit_Framework_TestCase
|
||||
$command = new \TestCommand();
|
||||
$command->setApplication($application);
|
||||
$this->assertEquals($application, $command->getApplication(), '->setApplication() sets the current application');
|
||||
$this->assertEquals($application->getHelperSet(), $command->getHelperSet());
|
||||
}
|
||||
|
||||
public function testSetApplicationNull()
|
||||
{
|
||||
$command = new \TestCommand();
|
||||
$command->setApplication(null);
|
||||
$this->assertNull($command->getHelperSet());
|
||||
}
|
||||
|
||||
public function testSetGetDefinition()
|
||||
@@ -84,6 +93,13 @@ class CommandTest extends \PHPUnit_Framework_TestCase
|
||||
$this->assertTrue($command->getDefinition()->hasOption('foo'), '->addOption() adds an option to the command');
|
||||
}
|
||||
|
||||
public function testSetHidden()
|
||||
{
|
||||
$command = new \TestCommand();
|
||||
$command->setHidden(true);
|
||||
$this->assertTrue($command->isHidden());
|
||||
}
|
||||
|
||||
public function testGetNamespaceGetNameSetName()
|
||||
{
|
||||
$command = new \TestCommand();
|
||||
@@ -101,7 +117,12 @@ class CommandTest extends \PHPUnit_Framework_TestCase
|
||||
*/
|
||||
public function testInvalidCommandNames($name)
|
||||
{
|
||||
$this->setExpectedException('InvalidArgumentException', sprintf('Command name "%s" is invalid.', $name));
|
||||
if (method_exists($this, 'expectException')) {
|
||||
$this->expectException('InvalidArgumentException');
|
||||
$this->expectExceptionMessage(sprintf('Command name "%s" is invalid.', $name));
|
||||
} else {
|
||||
$this->setExpectedException('InvalidArgumentException', sprintf('Command name "%s" is invalid.', $name));
|
||||
}
|
||||
|
||||
$command = new \TestCommand();
|
||||
$command->setName($name);
|
||||
@@ -156,6 +177,13 @@ class CommandTest extends \PHPUnit_Framework_TestCase
|
||||
$this->assertEquals(array('name1'), $command->getAliases(), '->setAliases() sets the aliases');
|
||||
}
|
||||
|
||||
public function testSetAliasesNull()
|
||||
{
|
||||
$command = new \TestCommand();
|
||||
$this->{method_exists($this, $_ = 'expectException') ? $_ : 'setExpectedException'}('InvalidArgumentException');
|
||||
$command->setAliases(null);
|
||||
}
|
||||
|
||||
public function testGetSynopsis()
|
||||
{
|
||||
$command = new \TestCommand();
|
||||
@@ -164,6 +192,15 @@ class CommandTest extends \PHPUnit_Framework_TestCase
|
||||
$this->assertEquals('namespace:name [--foo] [--] [<bar>]', $command->getSynopsis(), '->getSynopsis() returns the synopsis');
|
||||
}
|
||||
|
||||
public function testAddGetUsages()
|
||||
{
|
||||
$command = new \TestCommand();
|
||||
$command->addUsage('foo1');
|
||||
$command->addUsage('foo2');
|
||||
$this->assertContains('namespace:name foo1', $command->getUsages());
|
||||
$this->assertContains('namespace:name foo2', $command->getUsages());
|
||||
}
|
||||
|
||||
public function testGetHelper()
|
||||
{
|
||||
$application = new Application();
|
||||
@@ -273,10 +310,10 @@ class CommandTest extends \PHPUnit_Framework_TestCase
|
||||
$exitCode = $command->run(new StringInput(''), new NullOutput());
|
||||
$this->assertSame(0, $exitCode, '->run() returns integer exit code (treats null as 0)');
|
||||
|
||||
$command = $this->getMock('TestCommand', array('execute'));
|
||||
$command = $this->getMockBuilder('TestCommand')->setMethods(array('execute'))->getMock();
|
||||
$command->expects($this->once())
|
||||
->method('execute')
|
||||
->will($this->returnValue('2.3'));
|
||||
->method('execute')
|
||||
->will($this->returnValue('2.3'));
|
||||
$exitCode = $command->run(new StringInput(''), new NullOutput());
|
||||
$this->assertSame(2, $exitCode, '->run() returns integer exit code (casts numeric to int)');
|
||||
}
|
||||
@@ -297,6 +334,20 @@ class CommandTest extends \PHPUnit_Framework_TestCase
|
||||
$this->assertSame(0, $command->run(new StringInput(''), new NullOutput()));
|
||||
}
|
||||
|
||||
public function testRunWithProcessTitle()
|
||||
{
|
||||
$command = new \TestCommand();
|
||||
$command->setApplication(new Application());
|
||||
$command->setProcessTitle('foo');
|
||||
$this->assertSame(0, $command->run(new StringInput(''), new NullOutput()));
|
||||
if (function_exists('cli_set_process_title')) {
|
||||
if (null === @cli_get_process_title() && 'Darwin' === PHP_OS) {
|
||||
$this->markTestSkipped('Running "cli_get_process_title" as an unprivileged user is not supported on MacOS.');
|
||||
}
|
||||
$this->assertEquals('foo', cli_get_process_title());
|
||||
}
|
||||
}
|
||||
|
||||
public function testSetCode()
|
||||
{
|
||||
$command = new \TestCommand();
|
||||
@@ -334,6 +385,29 @@ class CommandTest extends \PHPUnit_Framework_TestCase
|
||||
$this->assertEquals('interact called'.PHP_EOL.$expected.PHP_EOL, $tester->getDisplay());
|
||||
}
|
||||
|
||||
public function testSetCodeWithStaticClosure()
|
||||
{
|
||||
$command = new \TestCommand();
|
||||
$command->setCode(self::createClosure());
|
||||
$tester = new CommandTester($command);
|
||||
$tester->execute(array());
|
||||
|
||||
if (\PHP_VERSION_ID < 70000) {
|
||||
// Cannot bind static closures in PHP 5
|
||||
$this->assertEquals('interact called'.PHP_EOL.'not bound'.PHP_EOL, $tester->getDisplay());
|
||||
} else {
|
||||
// Can bind static closures in PHP 7
|
||||
$this->assertEquals('interact called'.PHP_EOL.'bound'.PHP_EOL, $tester->getDisplay());
|
||||
}
|
||||
}
|
||||
|
||||
private static function createClosure()
|
||||
{
|
||||
return function (InputInterface $input, OutputInterface $output) {
|
||||
$output->writeln(isset($this) ? 'bound' : 'not bound');
|
||||
};
|
||||
}
|
||||
|
||||
public function testSetCodeWithNonClosureCallable()
|
||||
{
|
||||
$command = new \TestCommand();
|
||||
|
||||
@@ -11,12 +11,13 @@
|
||||
|
||||
namespace Symfony\Component\Console\Tests\Command;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\Console\Tester\CommandTester;
|
||||
use Symfony\Component\Console\Command\HelpCommand;
|
||||
use Symfony\Component\Console\Command\ListCommand;
|
||||
use Symfony\Component\Console\Application;
|
||||
|
||||
class HelpCommandTest extends \PHPUnit_Framework_TestCase
|
||||
class HelpCommandTest extends TestCase
|
||||
{
|
||||
public function testExecuteForCommandAlias()
|
||||
{
|
||||
|
||||
@@ -11,10 +11,11 @@
|
||||
|
||||
namespace Symfony\Component\Console\Tests\Command;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\Console\Tester\CommandTester;
|
||||
use Symfony\Component\Console\Application;
|
||||
|
||||
class ListCommandTest extends \PHPUnit_Framework_TestCase
|
||||
class ListCommandTest extends TestCase
|
||||
{
|
||||
public function testExecuteListsCommands()
|
||||
{
|
||||
@@ -30,7 +31,7 @@ class ListCommandTest extends \PHPUnit_Framework_TestCase
|
||||
$application = new Application();
|
||||
$commandTester = new CommandTester($command = $application->get('list'));
|
||||
$commandTester->execute(array('command' => $command->getName(), '--format' => 'xml'));
|
||||
$this->assertRegExp('/<command id="list" name="list">/', $commandTester->getDisplay(), '->execute() returns a list of available commands in XML if --xml is passed');
|
||||
$this->assertRegExp('/<command id="list" name="list" hidden="0">/', $commandTester->getDisplay(), '->execute() returns a list of available commands in XML if --xml is passed');
|
||||
}
|
||||
|
||||
public function testExecuteListsCommandsWithRawOption()
|
||||
|
||||
67
lib/composer/vendor/symfony/console/Tests/Command/LockableTraitTest.php
vendored
Normal file
67
lib/composer/vendor/symfony/console/Tests/Command/LockableTraitTest.php
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Console\Tests\Command;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\Console\Tester\CommandTester;
|
||||
use Symfony\Component\Lock\Factory;
|
||||
use Symfony\Component\Lock\Store\FlockStore;
|
||||
use Symfony\Component\Lock\Store\SemaphoreStore;
|
||||
|
||||
class LockableTraitTest extends TestCase
|
||||
{
|
||||
protected static $fixturesPath;
|
||||
|
||||
public static function setUpBeforeClass()
|
||||
{
|
||||
self::$fixturesPath = __DIR__.'/../Fixtures/';
|
||||
require_once self::$fixturesPath.'/FooLockCommand.php';
|
||||
require_once self::$fixturesPath.'/FooLock2Command.php';
|
||||
}
|
||||
|
||||
public function testLockIsReleased()
|
||||
{
|
||||
$command = new \FooLockCommand();
|
||||
|
||||
$tester = new CommandTester($command);
|
||||
$this->assertSame(2, $tester->execute(array()));
|
||||
$this->assertSame(2, $tester->execute(array()));
|
||||
}
|
||||
|
||||
public function testLockReturnsFalseIfAlreadyLockedByAnotherCommand()
|
||||
{
|
||||
$command = new \FooLockCommand();
|
||||
|
||||
if (SemaphoreStore::isSupported(false)) {
|
||||
$store = new SemaphoreStore();
|
||||
} else {
|
||||
$store = new FlockStore();
|
||||
}
|
||||
|
||||
$lock = (new Factory($store))->createLock($command->getName());
|
||||
$lock->acquire();
|
||||
|
||||
$tester = new CommandTester($command);
|
||||
$this->assertSame(1, $tester->execute(array()));
|
||||
|
||||
$lock->release();
|
||||
$this->assertSame(2, $tester->execute(array()));
|
||||
}
|
||||
|
||||
public function testMultipleLockCallsThrowLogicException()
|
||||
{
|
||||
$command = new \FooLock2Command();
|
||||
|
||||
$tester = new CommandTester($command);
|
||||
$this->assertSame(1, $tester->execute(array()));
|
||||
}
|
||||
}
|
||||
61
lib/composer/vendor/symfony/console/Tests/CommandLoader/ContainerCommandLoaderTest.php
vendored
Normal file
61
lib/composer/vendor/symfony/console/Tests/CommandLoader/ContainerCommandLoaderTest.php
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Console\Tests\CommandLoader;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\CommandLoader\ContainerCommandLoader;
|
||||
use Symfony\Component\DependencyInjection\ServiceLocator;
|
||||
|
||||
class ContainerCommandLoaderTest extends TestCase
|
||||
{
|
||||
public function testHas()
|
||||
{
|
||||
$loader = new ContainerCommandLoader(new ServiceLocator(array(
|
||||
'foo-service' => function () { return new Command('foo'); },
|
||||
'bar-service' => function () { return new Command('bar'); },
|
||||
)), array('foo' => 'foo-service', 'bar' => 'bar-service'));
|
||||
|
||||
$this->assertTrue($loader->has('foo'));
|
||||
$this->assertTrue($loader->has('bar'));
|
||||
$this->assertFalse($loader->has('baz'));
|
||||
}
|
||||
|
||||
public function testGet()
|
||||
{
|
||||
$loader = new ContainerCommandLoader(new ServiceLocator(array(
|
||||
'foo-service' => function () { return new Command('foo'); },
|
||||
'bar-service' => function () { return new Command('bar'); },
|
||||
)), array('foo' => 'foo-service', 'bar' => 'bar-service'));
|
||||
|
||||
$this->assertInstanceOf(Command::class, $loader->get('foo'));
|
||||
$this->assertInstanceOf(Command::class, $loader->get('bar'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\Console\Exception\CommandNotFoundException
|
||||
*/
|
||||
public function testGetUnknownCommandThrows()
|
||||
{
|
||||
(new ContainerCommandLoader(new ServiceLocator(array()), array()))->get('unknown');
|
||||
}
|
||||
|
||||
public function testGetCommandNames()
|
||||
{
|
||||
$loader = new ContainerCommandLoader(new ServiceLocator(array(
|
||||
'foo-service' => function () { return new Command('foo'); },
|
||||
'bar-service' => function () { return new Command('bar'); },
|
||||
)), array('foo' => 'foo-service', 'bar' => 'bar-service'));
|
||||
|
||||
$this->assertSame(array('foo', 'bar'), $loader->getNames());
|
||||
}
|
||||
}
|
||||
60
lib/composer/vendor/symfony/console/Tests/CommandLoader/FactoryCommandLoaderTest.php
vendored
Normal file
60
lib/composer/vendor/symfony/console/Tests/CommandLoader/FactoryCommandLoaderTest.php
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Console\Tests\CommandLoader;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\CommandLoader\FactoryCommandLoader;
|
||||
|
||||
class FactoryCommandLoaderTest extends TestCase
|
||||
{
|
||||
public function testHas()
|
||||
{
|
||||
$loader = new FactoryCommandLoader(array(
|
||||
'foo' => function () { return new Command('foo'); },
|
||||
'bar' => function () { return new Command('bar'); },
|
||||
));
|
||||
|
||||
$this->assertTrue($loader->has('foo'));
|
||||
$this->assertTrue($loader->has('bar'));
|
||||
$this->assertFalse($loader->has('baz'));
|
||||
}
|
||||
|
||||
public function testGet()
|
||||
{
|
||||
$loader = new FactoryCommandLoader(array(
|
||||
'foo' => function () { return new Command('foo'); },
|
||||
'bar' => function () { return new Command('bar'); },
|
||||
));
|
||||
|
||||
$this->assertInstanceOf(Command::class, $loader->get('foo'));
|
||||
$this->assertInstanceOf(Command::class, $loader->get('bar'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\Console\Exception\CommandNotFoundException
|
||||
*/
|
||||
public function testGetUnknownCommandThrows()
|
||||
{
|
||||
(new FactoryCommandLoader(array()))->get('unknown');
|
||||
}
|
||||
|
||||
public function testGetCommandNames()
|
||||
{
|
||||
$loader = new FactoryCommandLoader(array(
|
||||
'foo' => function () { return new Command('foo'); },
|
||||
'bar' => function () { return new Command('bar'); },
|
||||
));
|
||||
|
||||
$this->assertSame(array('foo', 'bar'), $loader->getNames());
|
||||
}
|
||||
}
|
||||
187
lib/composer/vendor/symfony/console/Tests/DependencyInjection/AddConsoleCommandPassTest.php
vendored
Normal file
187
lib/composer/vendor/symfony/console/Tests/DependencyInjection/AddConsoleCommandPassTest.php
vendored
Normal file
@@ -0,0 +1,187 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Console\Tests\DependencyInjection;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\Console\CommandLoader\ContainerCommandLoader;
|
||||
use Symfony\Component\Console\DependencyInjection\AddConsoleCommandPass;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
use Symfony\Component\DependencyInjection\TypedReference;
|
||||
|
||||
class AddConsoleCommandPassTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider visibilityProvider
|
||||
*/
|
||||
public function testProcess($public)
|
||||
{
|
||||
$container = new ContainerBuilder();
|
||||
$container->addCompilerPass(new AddConsoleCommandPass());
|
||||
$container->setParameter('my-command.class', 'Symfony\Component\Console\Tests\DependencyInjection\MyCommand');
|
||||
|
||||
$definition = new Definition('%my-command.class%');
|
||||
$definition->setPublic($public);
|
||||
$definition->addTag('console.command');
|
||||
$container->setDefinition('my-command', $definition);
|
||||
|
||||
$container->compile();
|
||||
|
||||
$alias = 'console.command.symfony_component_console_tests_dependencyinjection_mycommand';
|
||||
|
||||
if ($public) {
|
||||
$this->assertFalse($container->hasAlias($alias));
|
||||
$id = 'my-command';
|
||||
} else {
|
||||
$id = $alias;
|
||||
// The alias is replaced by a Definition by the ReplaceAliasByActualDefinitionPass
|
||||
// in case the original service is private
|
||||
$this->assertFalse($container->hasDefinition('my-command'));
|
||||
$this->assertTrue($container->hasDefinition($alias));
|
||||
}
|
||||
|
||||
$this->assertTrue($container->hasParameter('console.command.ids'));
|
||||
$this->assertSame(array($alias => $id), $container->getParameter('console.command.ids'));
|
||||
}
|
||||
|
||||
public function testProcessRegistersLazyCommands()
|
||||
{
|
||||
$container = new ContainerBuilder();
|
||||
$command = $container
|
||||
->register('my-command', MyCommand::class)
|
||||
->setPublic(false)
|
||||
->addTag('console.command', array('command' => 'my:command'))
|
||||
->addTag('console.command', array('command' => 'my:alias'))
|
||||
;
|
||||
|
||||
(new AddConsoleCommandPass())->process($container);
|
||||
|
||||
$commandLoader = $container->getDefinition('console.command_loader');
|
||||
$commandLocator = $container->getDefinition((string) $commandLoader->getArgument(0));
|
||||
|
||||
$this->assertSame(ContainerCommandLoader::class, $commandLoader->getClass());
|
||||
$this->assertSame(array('my:command' => 'my-command', 'my:alias' => 'my-command'), $commandLoader->getArgument(1));
|
||||
$this->assertEquals(array(array('my-command' => new ServiceClosureArgument(new TypedReference('my-command', MyCommand::class)))), $commandLocator->getArguments());
|
||||
$this->assertSame(array('console.command.symfony_component_console_tests_dependencyinjection_mycommand' => 'my-command'), $container->getParameter('console.command.ids'));
|
||||
$this->assertSame(array('my-command' => true), $container->getParameter('console.lazy_command.ids'));
|
||||
$this->assertSame(array(array('setName', array('my:command')), array('setAliases', array(array('my:alias')))), $command->getMethodCalls());
|
||||
}
|
||||
|
||||
public function testProcessFallsBackToDefaultName()
|
||||
{
|
||||
$container = new ContainerBuilder();
|
||||
$container
|
||||
->register('with-default-name', NamedCommand::class)
|
||||
->setPublic(false)
|
||||
->addTag('console.command')
|
||||
;
|
||||
|
||||
$pass = new AddConsoleCommandPass();
|
||||
$pass->process($container);
|
||||
|
||||
$commandLoader = $container->getDefinition('console.command_loader');
|
||||
$commandLocator = $container->getDefinition((string) $commandLoader->getArgument(0));
|
||||
|
||||
$this->assertSame(ContainerCommandLoader::class, $commandLoader->getClass());
|
||||
$this->assertSame(array('default' => 'with-default-name'), $commandLoader->getArgument(1));
|
||||
$this->assertEquals(array(array('with-default-name' => new ServiceClosureArgument(new TypedReference('with-default-name', NamedCommand::class)))), $commandLocator->getArguments());
|
||||
$this->assertSame(array('console.command.symfony_component_console_tests_dependencyinjection_namedcommand' => 'with-default-name'), $container->getParameter('console.command.ids'));
|
||||
$this->assertSame(array('with-default-name' => true), $container->getParameter('console.lazy_command.ids'));
|
||||
|
||||
$container = new ContainerBuilder();
|
||||
$container
|
||||
->register('with-default-name', NamedCommand::class)
|
||||
->setPublic(false)
|
||||
->addTag('console.command', array('command' => 'new-name'))
|
||||
;
|
||||
|
||||
$pass->process($container);
|
||||
|
||||
$this->assertSame(array('new-name' => 'with-default-name'), $container->getDefinition('console.command_loader')->getArgument(1));
|
||||
}
|
||||
|
||||
public function visibilityProvider()
|
||||
{
|
||||
return array(
|
||||
array(true),
|
||||
array(false),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \InvalidArgumentException
|
||||
* @expectedExceptionMessage The service "my-command" tagged "console.command" must not be abstract.
|
||||
*/
|
||||
public function testProcessThrowAnExceptionIfTheServiceIsAbstract()
|
||||
{
|
||||
$container = new ContainerBuilder();
|
||||
$container->setResourceTracking(false);
|
||||
$container->addCompilerPass(new AddConsoleCommandPass());
|
||||
|
||||
$definition = new Definition('Symfony\Component\Console\Tests\DependencyInjection\MyCommand');
|
||||
$definition->addTag('console.command');
|
||||
$definition->setAbstract(true);
|
||||
$container->setDefinition('my-command', $definition);
|
||||
|
||||
$container->compile();
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \InvalidArgumentException
|
||||
* @expectedExceptionMessage The service "my-command" tagged "console.command" must be a subclass of "Symfony\Component\Console\Command\Command".
|
||||
*/
|
||||
public function testProcessThrowAnExceptionIfTheServiceIsNotASubclassOfCommand()
|
||||
{
|
||||
$container = new ContainerBuilder();
|
||||
$container->setResourceTracking(false);
|
||||
$container->addCompilerPass(new AddConsoleCommandPass());
|
||||
|
||||
$definition = new Definition('SplObjectStorage');
|
||||
$definition->addTag('console.command');
|
||||
$container->setDefinition('my-command', $definition);
|
||||
|
||||
$container->compile();
|
||||
}
|
||||
|
||||
public function testProcessPrivateServicesWithSameCommand()
|
||||
{
|
||||
$container = new ContainerBuilder();
|
||||
$className = 'Symfony\Component\Console\Tests\DependencyInjection\MyCommand';
|
||||
|
||||
$definition1 = new Definition($className);
|
||||
$definition1->addTag('console.command')->setPublic(false);
|
||||
|
||||
$definition2 = new Definition($className);
|
||||
$definition2->addTag('console.command')->setPublic(false);
|
||||
|
||||
$container->setDefinition('my-command1', $definition1);
|
||||
$container->setDefinition('my-command2', $definition2);
|
||||
|
||||
(new AddConsoleCommandPass())->process($container);
|
||||
|
||||
$alias1 = 'console.command.symfony_component_console_tests_dependencyinjection_mycommand';
|
||||
$alias2 = $alias1.'_my-command2';
|
||||
$this->assertTrue($container->hasAlias($alias1));
|
||||
$this->assertTrue($container->hasAlias($alias2));
|
||||
}
|
||||
}
|
||||
|
||||
class MyCommand extends Command
|
||||
{
|
||||
}
|
||||
|
||||
class NamedCommand extends Command
|
||||
{
|
||||
protected static $defaultName = 'default';
|
||||
}
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
namespace Symfony\Component\Console\Tests\Descriptor;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\Console\Application;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
@@ -18,7 +19,7 @@ use Symfony\Component\Console\Input\InputDefinition;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\BufferedOutput;
|
||||
|
||||
abstract class AbstractDescriptorTest extends \PHPUnit_Framework_TestCase
|
||||
abstract class AbstractDescriptorTest extends TestCase
|
||||
{
|
||||
/** @dataProvider getDescribeInputArgumentTestData */
|
||||
public function testDescribeInputArgument(InputArgument $argument, $expectedDescription)
|
||||
@@ -86,7 +87,7 @@ abstract class AbstractDescriptorTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
abstract protected function getFormat();
|
||||
|
||||
private function getDescriptionTestData(array $objects)
|
||||
protected function getDescriptionTestData(array $objects)
|
||||
{
|
||||
$data = array();
|
||||
foreach ($objects as $name => $object) {
|
||||
@@ -97,10 +98,10 @@ abstract class AbstractDescriptorTest extends \PHPUnit_Framework_TestCase
|
||||
return $data;
|
||||
}
|
||||
|
||||
protected function assertDescription($expectedDescription, $describedObject)
|
||||
protected function assertDescription($expectedDescription, $describedObject, array $options = array())
|
||||
{
|
||||
$output = new BufferedOutput(BufferedOutput::VERBOSITY_NORMAL, true);
|
||||
$this->getDescriptor()->describe($output, $describedObject, array('raw_output' => true));
|
||||
$this->getDescriptor()->describe($output, $describedObject, $options + array('raw_output' => true));
|
||||
$this->assertEquals(trim($expectedDescription), trim(str_replace(PHP_EOL, "\n", $output->fetch())));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,10 +26,10 @@ class JsonDescriptorTest extends AbstractDescriptorTest
|
||||
return 'json';
|
||||
}
|
||||
|
||||
protected function assertDescription($expectedDescription, $describedObject)
|
||||
protected function assertDescription($expectedDescription, $describedObject, array $options = array())
|
||||
{
|
||||
$output = new BufferedOutput(BufferedOutput::VERBOSITY_NORMAL, true);
|
||||
$this->getDescriptor()->describe($output, $describedObject, array('raw_output' => true));
|
||||
$this->getDescriptor()->describe($output, $describedObject, $options + array('raw_output' => true));
|
||||
$this->assertEquals(json_decode(trim($expectedDescription), true), json_decode(trim(str_replace(PHP_EOL, "\n", $output->fetch())), true));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,9 +12,27 @@
|
||||
namespace Symfony\Component\Console\Tests\Descriptor;
|
||||
|
||||
use Symfony\Component\Console\Descriptor\MarkdownDescriptor;
|
||||
use Symfony\Component\Console\Tests\Fixtures\DescriptorApplicationMbString;
|
||||
use Symfony\Component\Console\Tests\Fixtures\DescriptorCommandMbString;
|
||||
|
||||
class MarkdownDescriptorTest extends AbstractDescriptorTest
|
||||
{
|
||||
public function getDescribeCommandTestData()
|
||||
{
|
||||
return $this->getDescriptionTestData(array_merge(
|
||||
ObjectsProvider::getCommands(),
|
||||
array('command_mbstring' => new DescriptorCommandMbString())
|
||||
));
|
||||
}
|
||||
|
||||
public function getDescribeApplicationTestData()
|
||||
{
|
||||
return $this->getDescriptionTestData(array_merge(
|
||||
ObjectsProvider::getApplications(),
|
||||
array('application_mbstring' => new DescriptorApplicationMbString())
|
||||
));
|
||||
}
|
||||
|
||||
protected function getDescriptor()
|
||||
{
|
||||
return new MarkdownDescriptor();
|
||||
|
||||
@@ -31,6 +31,8 @@ class ObjectsProvider
|
||||
'input_argument_2' => new InputArgument('argument_name', InputArgument::IS_ARRAY, 'argument description'),
|
||||
'input_argument_3' => new InputArgument('argument_name', InputArgument::OPTIONAL, 'argument description', 'default_value'),
|
||||
'input_argument_4' => new InputArgument('argument_name', InputArgument::REQUIRED, "multiline\nargument description"),
|
||||
'input_argument_with_style' => new InputArgument('argument_name', InputArgument::OPTIONAL, 'argument description', '<comment>style</>'),
|
||||
'input_argument_with_default_inf_value' => new InputArgument('argument_name', InputArgument::OPTIONAL, 'argument description', INF),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -43,6 +45,9 @@ class ObjectsProvider
|
||||
'input_option_4' => new InputOption('option_name', 'o', InputOption::VALUE_IS_ARRAY | InputOption::VALUE_OPTIONAL, 'option description', array()),
|
||||
'input_option_5' => new InputOption('option_name', 'o', InputOption::VALUE_REQUIRED, "multiline\noption description"),
|
||||
'input_option_6' => new InputOption('option_name', array('o', 'O'), InputOption::VALUE_REQUIRED, 'option with multiple shortcuts'),
|
||||
'input_option_with_style' => new InputOption('option_name', 'o', InputOption::VALUE_REQUIRED, 'option description', '<comment>style</>'),
|
||||
'input_option_with_style_array' => new InputOption('option_name', 'o', InputOption::VALUE_IS_ARRAY | InputOption::VALUE_REQUIRED, 'option description', array('<comment>Hello</comment>', '<info>world</info>')),
|
||||
'input_option_with_default_inf_value' => new InputOption('option_name', 'o', InputOption::VALUE_OPTIONAL, 'option description', INF),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -12,9 +12,35 @@
|
||||
namespace Symfony\Component\Console\Tests\Descriptor;
|
||||
|
||||
use Symfony\Component\Console\Descriptor\TextDescriptor;
|
||||
use Symfony\Component\Console\Tests\Fixtures\DescriptorApplication2;
|
||||
use Symfony\Component\Console\Tests\Fixtures\DescriptorApplicationMbString;
|
||||
use Symfony\Component\Console\Tests\Fixtures\DescriptorCommandMbString;
|
||||
|
||||
class TextDescriptorTest extends AbstractDescriptorTest
|
||||
{
|
||||
public function getDescribeCommandTestData()
|
||||
{
|
||||
return $this->getDescriptionTestData(array_merge(
|
||||
ObjectsProvider::getCommands(),
|
||||
array('command_mbstring' => new DescriptorCommandMbString())
|
||||
));
|
||||
}
|
||||
|
||||
public function getDescribeApplicationTestData()
|
||||
{
|
||||
return $this->getDescriptionTestData(array_merge(
|
||||
ObjectsProvider::getApplications(),
|
||||
array('application_mbstring' => new DescriptorApplicationMbString())
|
||||
));
|
||||
}
|
||||
|
||||
public function testDescribeApplicationWithFilteredNamespace()
|
||||
{
|
||||
$application = new DescriptorApplication2();
|
||||
|
||||
$this->assertDescription(file_get_contents(__DIR__.'/../Fixtures/application_filtered_namespace.txt'), $application, array('namespace' => 'command4'));
|
||||
}
|
||||
|
||||
protected function getDescriptor()
|
||||
{
|
||||
return new TextDescriptor();
|
||||
|
||||
156
lib/composer/vendor/symfony/console/Tests/EventListener/ErrorListenerTest.php
vendored
Normal file
156
lib/composer/vendor/symfony/console/Tests/EventListener/ErrorListenerTest.php
vendored
Normal file
@@ -0,0 +1,156 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Console\Tests\EventListener;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Event\ConsoleErrorEvent;
|
||||
use Symfony\Component\Console\Event\ConsoleTerminateEvent;
|
||||
use Symfony\Component\Console\EventListener\ErrorListener;
|
||||
use Symfony\Component\Console\Input\ArgvInput;
|
||||
use Symfony\Component\Console\Input\ArrayInput;
|
||||
use Symfony\Component\Console\Input\Input;
|
||||
use Symfony\Component\Console\Input\StringInput;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
class ErrorListenerTest extends TestCase
|
||||
{
|
||||
public function testOnConsoleError()
|
||||
{
|
||||
$error = new \TypeError('An error occurred');
|
||||
|
||||
$logger = $this->getLogger();
|
||||
$logger
|
||||
->expects($this->once())
|
||||
->method('error')
|
||||
->with('Error thrown while running command "{command}". Message: "{message}"', array('error' => $error, 'command' => 'test:run --foo=baz buzz', 'message' => 'An error occurred'))
|
||||
;
|
||||
|
||||
$listener = new ErrorListener($logger);
|
||||
$listener->onConsoleError(new ConsoleErrorEvent(new ArgvInput(array('console.php', 'test:run', '--foo=baz', 'buzz')), $this->getOutput(), $error, new Command('test:run')));
|
||||
}
|
||||
|
||||
public function testOnConsoleErrorWithNoCommandAndNoInputString()
|
||||
{
|
||||
$error = new \RuntimeException('An error occurred');
|
||||
|
||||
$logger = $this->getLogger();
|
||||
$logger
|
||||
->expects($this->once())
|
||||
->method('error')
|
||||
->with('An error occurred while using the console. Message: "{message}"', array('error' => $error, 'message' => 'An error occurred'))
|
||||
;
|
||||
|
||||
$listener = new ErrorListener($logger);
|
||||
$listener->onConsoleError(new ConsoleErrorEvent(new NonStringInput(), $this->getOutput(), $error));
|
||||
}
|
||||
|
||||
public function testOnConsoleTerminateForNonZeroExitCodeWritesToLog()
|
||||
{
|
||||
$logger = $this->getLogger();
|
||||
$logger
|
||||
->expects($this->once())
|
||||
->method('debug')
|
||||
->with('Command "{command}" exited with code "{code}"', array('command' => 'test:run', 'code' => 255))
|
||||
;
|
||||
|
||||
$listener = new ErrorListener($logger);
|
||||
$listener->onConsoleTerminate($this->getConsoleTerminateEvent(new ArgvInput(array('console.php', 'test:run')), 255));
|
||||
}
|
||||
|
||||
public function testOnConsoleTerminateForZeroExitCodeDoesNotWriteToLog()
|
||||
{
|
||||
$logger = $this->getLogger();
|
||||
$logger
|
||||
->expects($this->never())
|
||||
->method('debug')
|
||||
;
|
||||
|
||||
$listener = new ErrorListener($logger);
|
||||
$listener->onConsoleTerminate($this->getConsoleTerminateEvent(new ArgvInput(array('console.php', 'test:run')), 0));
|
||||
}
|
||||
|
||||
public function testGetSubscribedEvents()
|
||||
{
|
||||
$this->assertEquals(
|
||||
array(
|
||||
'console.error' => array('onConsoleError', -128),
|
||||
'console.terminate' => array('onConsoleTerminate', -128),
|
||||
),
|
||||
ErrorListener::getSubscribedEvents()
|
||||
);
|
||||
}
|
||||
|
||||
public function testAllKindsOfInputCanBeLogged()
|
||||
{
|
||||
$logger = $this->getLogger();
|
||||
$logger
|
||||
->expects($this->exactly(3))
|
||||
->method('debug')
|
||||
->with('Command "{command}" exited with code "{code}"', array('command' => 'test:run --foo=bar', 'code' => 255))
|
||||
;
|
||||
|
||||
$listener = new ErrorListener($logger);
|
||||
$listener->onConsoleTerminate($this->getConsoleTerminateEvent(new ArgvInput(array('console.php', 'test:run', '--foo=bar')), 255));
|
||||
$listener->onConsoleTerminate($this->getConsoleTerminateEvent(new ArrayInput(array('name' => 'test:run', '--foo' => 'bar')), 255));
|
||||
$listener->onConsoleTerminate($this->getConsoleTerminateEvent(new StringInput('test:run --foo=bar'), 255));
|
||||
}
|
||||
|
||||
public function testCommandNameIsDisplayedForNonStringableInput()
|
||||
{
|
||||
$logger = $this->getLogger();
|
||||
$logger
|
||||
->expects($this->once())
|
||||
->method('debug')
|
||||
->with('Command "{command}" exited with code "{code}"', array('command' => 'test:run', 'code' => 255))
|
||||
;
|
||||
|
||||
$listener = new ErrorListener($logger);
|
||||
$listener->onConsoleTerminate($this->getConsoleTerminateEvent($this->getMockBuilder(InputInterface::class)->getMock(), 255));
|
||||
}
|
||||
|
||||
private function getLogger()
|
||||
{
|
||||
return $this->getMockForAbstractClass(LoggerInterface::class);
|
||||
}
|
||||
|
||||
private function getConsoleTerminateEvent(InputInterface $input, $exitCode)
|
||||
{
|
||||
return new ConsoleTerminateEvent(new Command('test:run'), $input, $this->getOutput(), $exitCode);
|
||||
}
|
||||
|
||||
private function getOutput()
|
||||
{
|
||||
return $this->getMockBuilder(OutputInterface::class)->getMock();
|
||||
}
|
||||
}
|
||||
|
||||
class NonStringInput extends Input
|
||||
{
|
||||
public function getFirstArgument()
|
||||
{
|
||||
}
|
||||
|
||||
public function hasParameterOption($values, $onlyParams = false)
|
||||
{
|
||||
}
|
||||
|
||||
public function getParameterOption($values, $default = false, $onlyParams = false)
|
||||
{
|
||||
}
|
||||
|
||||
public function parse()
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -20,5 +20,7 @@ class DescriptorApplication2 extends Application
|
||||
parent::__construct('My Symfony application', 'v1.0');
|
||||
$this->add(new DescriptorCommand1());
|
||||
$this->add(new DescriptorCommand2());
|
||||
$this->add(new DescriptorCommand3());
|
||||
$this->add(new DescriptorCommand4());
|
||||
}
|
||||
}
|
||||
|
||||
24
lib/composer/vendor/symfony/console/Tests/Fixtures/DescriptorApplicationMbString.php
vendored
Normal file
24
lib/composer/vendor/symfony/console/Tests/Fixtures/DescriptorApplicationMbString.php
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Console\Tests\Fixtures;
|
||||
|
||||
use Symfony\Component\Console\Application;
|
||||
|
||||
class DescriptorApplicationMbString extends Application
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct('MbString åpplicätion');
|
||||
|
||||
$this->add(new DescriptorCommandMbString());
|
||||
}
|
||||
}
|
||||
27
lib/composer/vendor/symfony/console/Tests/Fixtures/DescriptorCommand3.php
vendored
Normal file
27
lib/composer/vendor/symfony/console/Tests/Fixtures/DescriptorCommand3.php
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Console\Tests\Fixtures;
|
||||
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
|
||||
class DescriptorCommand3 extends Command
|
||||
{
|
||||
protected function configure()
|
||||
{
|
||||
$this
|
||||
->setName('descriptor:command3')
|
||||
->setDescription('command 3 description')
|
||||
->setHelp('command 3 help')
|
||||
->setHidden(true)
|
||||
;
|
||||
}
|
||||
}
|
||||
25
lib/composer/vendor/symfony/console/Tests/Fixtures/DescriptorCommand4.php
vendored
Normal file
25
lib/composer/vendor/symfony/console/Tests/Fixtures/DescriptorCommand4.php
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Console\Tests\Fixtures;
|
||||
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
|
||||
class DescriptorCommand4 extends Command
|
||||
{
|
||||
protected function configure()
|
||||
{
|
||||
$this
|
||||
->setName('descriptor:command4')
|
||||
->setAliases(array('descriptor:alias_command4', 'command4:descriptor'))
|
||||
;
|
||||
}
|
||||
}
|
||||
32
lib/composer/vendor/symfony/console/Tests/Fixtures/DescriptorCommandMbString.php
vendored
Normal file
32
lib/composer/vendor/symfony/console/Tests/Fixtures/DescriptorCommandMbString.php
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Console\Tests\Fixtures;
|
||||
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
|
||||
class DescriptorCommandMbString extends Command
|
||||
{
|
||||
protected function configure()
|
||||
{
|
||||
$this
|
||||
->setName('descriptor:åèä')
|
||||
->setDescription('command åèä description')
|
||||
->setHelp('command åèä help')
|
||||
->addUsage('-o|--option_name <argument_name>')
|
||||
->addUsage('<argument_name>')
|
||||
->addArgument('argument_åèä', InputArgument::REQUIRED)
|
||||
->addOption('option_åèä', 'o', InputOption::VALUE_NONE)
|
||||
;
|
||||
}
|
||||
}
|
||||
@@ -26,7 +26,7 @@ class DummyOutput extends BufferedOutput
|
||||
public function getLogs()
|
||||
{
|
||||
$logs = array();
|
||||
foreach (explode("\n", trim($this->fetch())) as $message) {
|
||||
foreach (explode(PHP_EOL, trim($this->fetch())) as $message) {
|
||||
preg_match('/^\[(.*)\] (.*)/', $message, $matches);
|
||||
$logs[] = sprintf('%s %s', $matches[1], $matches[2]);
|
||||
}
|
||||
|
||||
28
lib/composer/vendor/symfony/console/Tests/Fixtures/FooLock2Command.php
vendored
Normal file
28
lib/composer/vendor/symfony/console/Tests/Fixtures/FooLock2Command.php
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Command\LockableTrait;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
class FooLock2Command extends Command
|
||||
{
|
||||
use LockableTrait;
|
||||
|
||||
protected function configure()
|
||||
{
|
||||
$this->setName('foo:lock2');
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
try {
|
||||
$this->lock();
|
||||
$this->lock();
|
||||
} catch (LogicException $e) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
27
lib/composer/vendor/symfony/console/Tests/Fixtures/FooLockCommand.php
vendored
Normal file
27
lib/composer/vendor/symfony/console/Tests/Fixtures/FooLockCommand.php
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Command\LockableTrait;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
class FooLockCommand extends Command
|
||||
{
|
||||
use LockableTrait;
|
||||
|
||||
protected function configure()
|
||||
{
|
||||
$this->setName('foo:lock');
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
if (!$this->lock()) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
$this->release();
|
||||
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
36
lib/composer/vendor/symfony/console/Tests/Fixtures/FooOptCommand.php
vendored
Normal file
36
lib/composer/vendor/symfony/console/Tests/Fixtures/FooOptCommand.php
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
class FooOptCommand extends Command
|
||||
{
|
||||
public $input;
|
||||
public $output;
|
||||
|
||||
protected function configure()
|
||||
{
|
||||
$this
|
||||
->setName('foo:bar')
|
||||
->setDescription('The foo:bar command')
|
||||
->setAliases(array('afoobar'))
|
||||
->addOption('fooopt', 'fo', InputOption::VALUE_OPTIONAL, 'fooopt description')
|
||||
;
|
||||
}
|
||||
|
||||
protected function interact(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$output->writeln('interact called');
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$this->input = $input;
|
||||
$this->output = $output;
|
||||
|
||||
$output->writeln('called');
|
||||
$output->writeln($this->input->getOption('fooopt'));
|
||||
}
|
||||
}
|
||||
11
lib/composer/vendor/symfony/console/Tests/Fixtures/FooSameCaseLowercaseCommand.php
vendored
Normal file
11
lib/composer/vendor/symfony/console/Tests/Fixtures/FooSameCaseLowercaseCommand.php
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
|
||||
class FooSameCaseLowercaseCommand extends Command
|
||||
{
|
||||
protected function configure()
|
||||
{
|
||||
$this->setName('foo:bar')->setDescription('foo:bar command');
|
||||
}
|
||||
}
|
||||
11
lib/composer/vendor/symfony/console/Tests/Fixtures/FooSameCaseUppercaseCommand.php
vendored
Normal file
11
lib/composer/vendor/symfony/console/Tests/Fixtures/FooSameCaseUppercaseCommand.php
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
|
||||
class FooSameCaseUppercaseCommand extends Command
|
||||
{
|
||||
protected function configure()
|
||||
{
|
||||
$this->setName('foo:BAR')->setDescription('foo:BAR command');
|
||||
}
|
||||
}
|
||||
@@ -2,10 +2,10 @@
|
||||
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Console\Tests\Style\SymfonyStyleWithForcedLineLength;
|
||||
use Symfony\Component\Console\Style\SymfonyStyle;
|
||||
|
||||
//Ensure has single blank line at start when using block element
|
||||
return function (InputInterface $input, OutputInterface $output) {
|
||||
$output = new SymfonyStyleWithForcedLineLength($input, $output);
|
||||
$output = new SymfonyStyle($input, $output);
|
||||
$output->caution('Lorem ipsum dolor sit amet');
|
||||
};
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Console\Tests\Style\SymfonyStyleWithForcedLineLength;
|
||||
use Symfony\Component\Console\Style\SymfonyStyle;
|
||||
|
||||
//Ensure has single blank line between titles and blocks
|
||||
return function (InputInterface $input, OutputInterface $output) {
|
||||
$output = new SymfonyStyleWithForcedLineLength($input, $output);
|
||||
$output = new SymfonyStyle($input, $output);
|
||||
$output->title('Title');
|
||||
$output->warning('Lorem ipsum dolor sit amet');
|
||||
$output->title('Title');
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Console\Tests\Style\SymfonyStyleWithForcedLineLength;
|
||||
use Symfony\Component\Console\Style\SymfonyStyle;
|
||||
|
||||
//Ensure that all lines are aligned to the begin of the first line in a very long line block
|
||||
return function (InputInterface $input, OutputInterface $output) {
|
||||
$output = new SymfonyStyleWithForcedLineLength($input, $output);
|
||||
$output = new SymfonyStyle($input, $output);
|
||||
$output->block(
|
||||
'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum',
|
||||
'CUSTOM',
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Console\Tests\Style\SymfonyStyleWithForcedLineLength;
|
||||
use Symfony\Component\Console\Style\SymfonyStyle;
|
||||
|
||||
// ensure long words are properly wrapped in blocks
|
||||
return function (InputInterface $input, OutputInterface $output) {
|
||||
$word = 'Lopadotemachoselachogaleokranioleipsanodrimhypotrimmatosilphioparaomelitokatakechymenokichlepikossyphophattoperisteralektryonoptekephalliokigklopeleiolagoiosiraiobaphetraganopterygon';
|
||||
$sfStyle = new SymfonyStyleWithForcedLineLength($input, $output);
|
||||
$sfStyle = new SymfonyStyle($input, $output);
|
||||
$sfStyle->block($word, 'CUSTOM', 'fg=white;bg=blue', ' § ', false);
|
||||
};
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Console\Tests\Style\SymfonyStyleWithForcedLineLength;
|
||||
use Symfony\Component\Console\Style\SymfonyStyle;
|
||||
|
||||
// ensure that all lines are aligned to the begin of the first one and start with '//' in a very long line comment
|
||||
return function (InputInterface $input, OutputInterface $output) {
|
||||
$output = new SymfonyStyleWithForcedLineLength($input, $output);
|
||||
$output = new SymfonyStyle($input, $output);
|
||||
$output->comment(
|
||||
'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum'
|
||||
);
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Console\Tests\Style\SymfonyStyleWithForcedLineLength;
|
||||
use Symfony\Component\Console\Style\SymfonyStyle;
|
||||
|
||||
// ensure that nested tags have no effect on the color of the '//' prefix
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Console\Tests\Style\SymfonyStyleWithForcedLineLength;
|
||||
use Symfony\Component\Console\Style\SymfonyStyle;
|
||||
|
||||
// ensure that block() behaves properly with a prefix and without type
|
||||
return function (InputInterface $input, OutputInterface $output) {
|
||||
$output = new SymfonyStyleWithForcedLineLength($input, $output);
|
||||
$output = new SymfonyStyle($input, $output);
|
||||
$output->block(
|
||||
'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum',
|
||||
null,
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Console\Tests\Style\SymfonyStyleWithForcedLineLength;
|
||||
use Symfony\Component\Console\Style\SymfonyStyle;
|
||||
|
||||
// ensure that block() behaves properly with a type and without prefix
|
||||
return function (InputInterface $input, OutputInterface $output) {
|
||||
$output = new SymfonyStyleWithForcedLineLength($input, $output);
|
||||
$output = new SymfonyStyle($input, $output);
|
||||
$output->block(
|
||||
'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum',
|
||||
'TEST'
|
||||
|
||||
@@ -2,12 +2,12 @@
|
||||
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Console\Tests\Style\SymfonyStyleWithForcedLineLength;
|
||||
use Symfony\Component\Console\Style\SymfonyStyle;
|
||||
|
||||
// ensure that block() output is properly formatted (even padding lines)
|
||||
return function (InputInterface $input, OutputInterface $output) {
|
||||
$output->setDecorated(true);
|
||||
$output = new SymfonyStyleWithForcedLineLength($input, $output);
|
||||
$output = new SymfonyStyle($input, $output);
|
||||
$output->success(
|
||||
'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum',
|
||||
'TEST'
|
||||
|
||||
13
lib/composer/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_17.php
vendored
Normal file
13
lib/composer/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_17.php
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Console\Style\SymfonyStyle;
|
||||
|
||||
//Ensure symfony style helper methods handle trailing backslashes properly when decorating user texts
|
||||
return function (InputInterface $input, OutputInterface $output) {
|
||||
$output = new SymfonyStyle($input, $output);
|
||||
|
||||
$output->title('Title ending with \\');
|
||||
$output->section('Section ending with \\');
|
||||
};
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user