Aggiornato Composer

This commit is contained in:
Paolo A
2024-05-17 12:24:19 +00:00
parent 4ac62108b5
commit ec201d75b2
2238 changed files with 38684 additions and 59785 deletions

View File

@@ -134,7 +134,7 @@ class Application implements ResetInterface
*
* @throws \Exception When running fails. Bypass this when {@link setCatchExceptions()}.
*/
public function run(InputInterface $input = null, OutputInterface $output = null)
public function run(?InputInterface $input = null, ?OutputInterface $output = null)
{
if (\function_exists('putenv')) {
@putenv('LINES='.$this->terminal->getHeight());
@@ -276,7 +276,9 @@ class Application implements ResetInterface
$alternative = $alternatives[0];
$style = new SymfonyStyle($input, $output);
$style->block(sprintf("\nCommand \"%s\" is not defined.\n", $name), null, 'error');
$output->writeln('');
$formattedBlock = (new FormatterHelper())->formatBlock(sprintf('Command "%s" is not defined.', $name), 'error', true);
$output->writeln($formattedBlock);
if (!$style->confirm(sprintf('Do you want to run "%s" instead? ', $alternative), false)) {
if (null !== $this->dispatcher) {
$event = new ConsoleErrorEvent($input, $output, $e);
@@ -363,9 +365,18 @@ class Application implements ResetInterface
CompletionInput::TYPE_ARGUMENT_VALUE === $input->getCompletionType()
&& 'command' === $input->getCompletionName()
) {
$suggestions->suggestValues(array_filter(array_map(function (Command $command) {
return $command->isHidden() ? null : $command->getName();
}, $this->all())));
$commandNames = [];
foreach ($this->all() as $name => $command) {
// skip hidden commands and aliased commands as they already get added below
if ($command->isHidden() || $command->getName() !== $name) {
continue;
}
$commandNames[] = $command->getName();
foreach ($command->getAliases() as $name) {
$commandNames[] = $name;
}
}
$suggestions->suggestValues(array_filter($commandNames));
return;
}
@@ -767,7 +778,7 @@ class Application implements ResetInterface
*
* @return Command[]
*/
public function all(string $namespace = null)
public function all(?string $namespace = null)
{
$this->init();
@@ -924,11 +935,21 @@ class Application implements ResetInterface
}
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;
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(['--quiet', '-q'], true)) {
@@ -974,22 +995,26 @@ class Application implements ResetInterface
}
}
if ($command instanceof SignalableCommandInterface && ($this->signalsToDispatchEvent || $command->getSubscribedSignals())) {
if (!$this->signalRegistry) {
throw new RuntimeException('Unable to subscribe to signal events. Make sure that the `pcntl` extension is installed and that "pcntl_*" functions are not disabled by your php.ini\'s "disable_functions" directive.');
}
if ($this->signalsToDispatchEvent) {
$commandSignals = $command instanceof SignalableCommandInterface ? $command->getSubscribedSignals() : [];
if (Terminal::hasSttyAvailable()) {
$sttyMode = shell_exec('stty -g');
if ($commandSignals || null !== $this->dispatcher) {
if (!$this->signalRegistry) {
throw new RuntimeException('Unable to subscribe to signal events. Make sure that the `pcntl` extension is installed and that "pcntl_*" functions are not disabled by your php.ini\'s "disable_functions" directive.');
}
foreach ([\SIGINT, \SIGTERM] as $signal) {
$this->signalRegistry->register($signal, static function () use ($sttyMode) {
shell_exec('stty '.$sttyMode);
});
if (Terminal::hasSttyAvailable()) {
$sttyMode = shell_exec('stty -g');
foreach ([\SIGINT, \SIGTERM] as $signal) {
$this->signalRegistry->register($signal, static function () use ($sttyMode) {
shell_exec('stty '.$sttyMode);
});
}
}
}
if ($this->dispatcher) {
if (null !== $this->dispatcher) {
foreach ($this->signalsToDispatchEvent as $signal) {
$event = new ConsoleSignalEvent($command, $input, $output, $signal);
@@ -1006,7 +1031,7 @@ class Application implements ResetInterface
}
}
foreach ($command->getSubscribedSignals() as $signal) {
foreach ($commandSignals as $signal) {
$this->signalRegistry->register($signal, [$command, 'handleSignal']);
}
}
@@ -1122,7 +1147,7 @@ class Application implements ResetInterface
*
* @return string
*/
public function extractNamespace(string $name, int $limit = null)
public function extractNamespace(string $name, ?int $limit = null)
{
$parts = explode(':', $name, -1);

View File

@@ -57,7 +57,7 @@ class GithubActionReporter
*
* @see https://docs.github.com/en/free-pro-team@latest/actions/reference/workflow-commands-for-github-actions#setting-an-error-message
*/
public function error(string $message, string $file = null, int $line = null, int $col = null): void
public function error(string $message, ?string $file = null, ?int $line = null, ?int $col = null): void
{
$this->log('error', $message, $file, $line, $col);
}
@@ -67,7 +67,7 @@ class GithubActionReporter
*
* @see https://docs.github.com/en/free-pro-team@latest/actions/reference/workflow-commands-for-github-actions#setting-a-warning-message
*/
public function warning(string $message, string $file = null, int $line = null, int $col = null): void
public function warning(string $message, ?string $file = null, ?int $line = null, ?int $col = null): void
{
$this->log('warning', $message, $file, $line, $col);
}
@@ -77,12 +77,12 @@ class GithubActionReporter
*
* @see https://docs.github.com/en/free-pro-team@latest/actions/reference/workflow-commands-for-github-actions#setting-a-debug-message
*/
public function debug(string $message, string $file = null, int $line = null, int $col = null): void
public function debug(string $message, ?string $file = null, ?int $line = null, ?int $col = null): void
{
$this->log('debug', $message, $file, $line, $col);
}
private function log(string $type, string $message, string $file = null, int $line = null, int $col = null): void
private function log(string $type, string $message, ?string $file = null, ?int $line = null, ?int $col = null): void
{
// Some values must be encoded.
$message = strtr($message, self::ESCAPED_DATA);

View File

@@ -96,7 +96,7 @@ class Command
*
* @throws LogicException When the command name is empty
*/
public function __construct(string $name = null)
public function __construct(?string $name = null)
{
$this->definition = new InputDefinition();
@@ -132,7 +132,7 @@ class Command
$this->ignoreValidationErrors = true;
}
public function setApplication(Application $application = null)
public function setApplication(?Application $application = null)
{
$this->application = $application;
if ($application) {
@@ -242,7 +242,7 @@ class Command
*
* @return int The command exit code
*
* @throws \Exception When binding input fails. Bypass this by calling {@link ignoreValidationErrors()}.
* @throws ExceptionInterface When input binding fails. Bypass this by calling {@link ignoreValidationErrors()}.
*
* @see setCode()
* @see execute()
@@ -429,11 +429,11 @@ class Command
* @param int|null $mode The argument mode: InputArgument::REQUIRED or InputArgument::OPTIONAL
* @param mixed $default The default value (for InputArgument::OPTIONAL mode only)
*
* @throws InvalidArgumentException When argument mode is not valid
*
* @return $this
*
* @throws InvalidArgumentException When argument mode is not valid
*/
public function addArgument(string $name, int $mode = null, string $description = '', $default = null)
public function addArgument(string $name, ?int $mode = null, string $description = '', $default = null)
{
$this->definition->addArgument(new InputArgument($name, $mode, $description, $default));
if (null !== $this->fullDefinition) {
@@ -450,11 +450,11 @@ class Command
* @param int|null $mode The option mode: One of the InputOption::VALUE_* constants
* @param mixed $default The default value (must be null for InputOption::VALUE_NONE)
*
* @throws InvalidArgumentException If option mode is invalid or incompatible
*
* @return $this
*
* @throws InvalidArgumentException If option mode is invalid or incompatible
*/
public function addOption(string $name, $shortcut = null, int $mode = null, string $description = '', $default = null)
public function addOption(string $name, $shortcut = null, ?int $mode = null, string $description = '', $default = null)
{
$this->definition->addOption(new InputOption($name, $shortcut, $mode, $description, $default));
if (null !== $this->fullDefinition) {
@@ -518,7 +518,7 @@ class Command
*
* @final since Symfony 5.1
*/
public function setHidden(bool $hidden /*= true*/)
public function setHidden(bool $hidden /* = true */)
{
$this->hidden = $hidden;

View File

@@ -65,15 +65,15 @@ final class CompleteCommand extends Command
{
try {
// uncomment when a bugfix or BC break has been introduced in the shell completion scripts
//$version = $input->getOption('symfony');
//if ($version && version_compare($version, 'x.y', '>=')) {
// $version = $input->getOption('symfony');
// if ($version && version_compare($version, 'x.y', '>=')) {
// $message = sprintf('Completion script version is not supported ("%s" given, ">=x.y" required).', $version);
// $this->log($message);
// $output->writeln($message.' Install the Symfony completion script again by using the "completion" command.');
// return 126;
//}
// }
$shell = $input->getOption('shell');
if (!$shell) {
@@ -105,11 +105,12 @@ final class CompleteCommand extends Command
} elseif (
$completionInput->mustSuggestArgumentValuesFor('command')
&& $command->getName() !== $completionInput->getCompletionValue()
&& !\in_array($completionInput->getCompletionValue(), $command->getAliases(), true)
) {
$this->log(' No command found, completing using the Application class.');
// expand shortcut names ("cache:cl<TAB>") into their full name ("cache:clear")
$suggestions->suggestValue($command->getName());
$suggestions->suggestValues(array_filter(array_merge([$command->getName()], $command->getAliases())));
} else {
$command->mergeApplicationDefinition();
$completionInput->bind($command->getDefinition());
@@ -154,10 +155,10 @@ final class CompleteCommand extends Command
throw $e;
}
return self::FAILURE;
return 2;
}
return self::SUCCESS;
return 0;
}
private function createCompletionInput(InputInterface $input): CompletionInput

View File

@@ -41,7 +41,7 @@ final class DumpCompletionCommand extends Command
{
$fullCommand = $_SERVER['PHP_SELF'];
$commandName = basename($fullCommand);
$fullCommand = realpath($fullCommand) ?: $fullCommand;
$fullCommand = @realpath($fullCommand) ?: $fullCommand;
$this
->setHelp(<<<EOH
@@ -53,7 +53,7 @@ to use shell autocompletion (currently only bash completion is supported).
Dump the script to a global completion file and restart your shell:
<info>%command.full_name% bash | sudo tee /etc/bash_completion.d/${commandName}</>
<info>%command.full_name% bash | sudo tee /etc/bash_completion.d/{$commandName}</>
Or dump the script to a local file and source it:
@@ -70,7 +70,7 @@ Or dump the script to a local file and source it:
Add this to the end of your shell configuration file (e.g. <info>"~/.bashrc"</>):
<info>eval "$(${fullCommand} completion bash)"</>
<info>eval "$({$fullCommand} completion bash)"</>
EOH
)
->addArgument('shell', InputArgument::OPTIONAL, 'The shell type (e.g. "bash"), the value of the "$SHELL" env var will be used if this is not given')
@@ -85,7 +85,7 @@ EOH
if ($input->getOption('debug')) {
$this->tailDebugLog($commandName, $output);
return self::SUCCESS;
return 0;
}
$shell = $input->getArgument('shell') ?? self::guessShell();
@@ -93,15 +93,21 @@ EOH
if (!file_exists($completionFile)) {
$supportedShells = $this->getSupportedShells();
($output instanceof ConsoleOutputInterface ? $output->getErrorOutput() : $output)
->writeln(sprintf('<error>Detected shell "%s", which is not supported by Symfony shell completion (supported shells: "%s").</>', $shell, implode('", "', $supportedShells)));
if ($output instanceof ConsoleOutputInterface) {
$output = $output->getErrorOutput();
}
if ($shell) {
$output->writeln(sprintf('<error>Detected shell "%s", which is not supported by Symfony shell completion (supported shells: "%s").</>', $shell, implode('", "', $supportedShells)));
} else {
$output->writeln(sprintf('<error>Shell not detected, Symfony shell completion only supports "%s").</>', implode('", "', $supportedShells)));
}
return self::INVALID;
return 2;
}
$output->write(str_replace(['{{ COMMAND_NAME }}', '{{ VERSION }}'], [$commandName, $this->getApplication()->getVersion()], file_get_contents($completionFile)));
return self::SUCCESS;
return 0;
}
private static function guessShell(): string
@@ -126,8 +132,14 @@ EOH
*/
private function getSupportedShells(): array
{
return array_map(function ($f) {
return pathinfo($f, \PATHINFO_EXTENSION);
}, glob(__DIR__.'/../Resources/completion.*'));
$shells = [];
foreach (new \DirectoryIterator(__DIR__.'/../Resources/') as $file) {
if (str_starts_with($file->getBasename(), 'completion.') && $file->isFile()) {
$shells[] = $file->getExtension();
}
}
return $shells;
}
}

View File

@@ -43,7 +43,7 @@ final class LazyCommand extends Command
$this->getCommand()->ignoreValidationErrors();
}
public function setApplication(Application $application = null): void
public function setApplication(?Application $application = null): void
{
if ($this->command instanceof parent) {
$this->command->setApplication($application);
@@ -117,7 +117,7 @@ final class LazyCommand extends Command
/**
* @return $this
*/
public function addArgument(string $name, int $mode = null, string $description = '', $default = null): self
public function addArgument(string $name, ?int $mode = null, string $description = '', $default = null): self
{
$this->getCommand()->addArgument($name, $mode, $description, $default);
@@ -127,7 +127,7 @@ final class LazyCommand extends Command
/**
* @return $this
*/
public function addOption(string $name, $shortcut = null, int $mode = null, string $description = '', $default = null): self
public function addOption(string $name, $shortcut = null, ?int $mode = null, string $description = '', $default = null): self
{
$this->getCommand()->addOption($name, $shortcut, $mode, $description, $default);

View File

@@ -30,7 +30,7 @@ trait LockableTrait
/**
* Locks a command.
*/
private function lock(string $name = null, bool $blocking = false): bool
private function lock(?string $name = null, bool $blocking = false): bool
{
if (!class_exists(SemaphoreStore::class)) {
throw new LogicException('To enable the locking feature you must install the symfony/lock component.');

View File

@@ -24,6 +24,9 @@ class BashCompletionOutput implements CompletionOutputInterface
$values = $suggestions->getValueSuggestions();
foreach ($suggestions->getOptionSuggestions() as $option) {
$values[] = '--'.$option->getName();
if ($option->isNegatable()) {
$values[] = '--no-'.$option->getName();
}
}
$output->writeln(implode("\n", $values));
}

View File

@@ -67,7 +67,7 @@ class AddConsoleCommandPass implements CompilerPassInterface
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));
}
$aliases = $class::getDefaultName();
$aliases = str_replace('%', '%%', $class::getDefaultName() ?? '');
}
$aliases = explode('|', $aliases ?? '');
@@ -124,7 +124,7 @@ class AddConsoleCommandPass implements CompilerPassInterface
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));
}
$description = $class::getDefaultDescription();
$description = str_replace('%', '%%', $class::getDefaultDescription() ?? '');
}
if ($description) {

View File

@@ -43,7 +43,7 @@ class ApplicationDescription
*/
private $aliases;
public function __construct(Application $application, string $namespace = null, bool $showHidden = false)
public function __construct(Application $application, ?string $namespace = null, bool $showHidden = false)
{
$this->application = $application;
$this->namespace = $namespace;
@@ -131,7 +131,7 @@ class ApplicationDescription
}
if ($namespacedCommands) {
ksort($namespacedCommands);
ksort($namespacedCommands, \SORT_STRING);
foreach ($namespacedCommands as $key => $commandsSet) {
ksort($commandsSet);
$sortedCommands[$key] = $commandsSet;

View File

@@ -79,7 +79,7 @@ class XmlDescriptor extends Descriptor
return $dom;
}
public function getApplicationDocument(Application $application, string $namespace = null, bool $short = false): \DOMDocument
public function getApplicationDocument(Application $application, ?string $namespace = null, bool $short = false): \DOMDocument
{
$dom = new \DOMDocument('1.0', 'UTF-8');
$dom->appendChild($rootXml = $dom->createElement('symfony'));

View File

@@ -12,7 +12,10 @@
namespace Symfony\Component\Console\Event;
/**
* Allows to do things before the command is executed, like skipping the command or changing the input.
* Allows to do things before the command is executed, like skipping the command or executing code before the command is
* going to be executed.
*
* Changing the input arguments will have no effect.
*
* @author Fabien Potencier <fabien@symfony.com>
*/

View File

@@ -25,7 +25,7 @@ final class ConsoleErrorEvent extends ConsoleEvent
private $error;
private $exitCode;
public function __construct(InputInterface $input, OutputInterface $output, \Throwable $error, Command $command = null)
public function __construct(InputInterface $input, OutputInterface $output, \Throwable $error, ?Command $command = null)
{
parent::__construct($command, $input, $output);

View File

@@ -26,7 +26,7 @@ class ErrorListener implements EventSubscriberInterface
{
private $logger;
public function __construct(LoggerInterface $logger = null)
public function __construct(?LoggerInterface $logger = null)
{
$this->logger = $logger;
}

View File

@@ -26,7 +26,7 @@ class CommandNotFoundException extends \InvalidArgumentException implements Exce
* @param int $code Exception code
* @param \Throwable|null $previous Previous exception used for the exception chaining
*/
public function __construct(string $message, array $alternatives = [], int $code = 0, \Throwable $previous = null)
public function __construct(string $message, array $alternatives = [], int $code = 0, ?\Throwable $previous = null)
{
parent::__construct($message, $code, $previous);

View File

@@ -12,7 +12,7 @@
namespace Symfony\Component\Console\Exception;
/**
* Represents an incorrect option name typed in the console.
* Represents an incorrect option name or value typed in the console.
*
* @author Jérôme Tamarelle <jerome@tamarelle.net>
*/

View File

@@ -27,7 +27,7 @@ final class NullOutputFormatterStyle implements OutputFormatterStyleInterface
/**
* {@inheritdoc}
*/
public function setBackground(string $color = null): void
public function setBackground(?string $color = null): void
{
// do nothing
}
@@ -35,7 +35,7 @@ final class NullOutputFormatterStyle implements OutputFormatterStyleInterface
/**
* {@inheritdoc}
*/
public function setForeground(string $color = null): void
public function setForeground(?string $color = null): void
{
// do nothing
}

View File

@@ -13,6 +13,8 @@ namespace Symfony\Component\Console\Formatter;
use Symfony\Component\Console\Exception\InvalidArgumentException;
use function Symfony\Component\String\b;
/**
* Formatter class for console output.
*
@@ -258,7 +260,7 @@ class OutputFormatter implements WrappableOutputFormatterInterface
}
preg_match('~(\\n)$~', $text, $matches);
$text = $prefix.preg_replace('~([^\\n]{'.$width.'})\\ *~', "\$1\n", $text);
$text = $prefix.$this->addLineBreaks($text, $width);
$text = rtrim($text, "\n").($matches[1] ?? '');
if (!$currentLineLength && '' !== $current && "\n" !== substr($current, -1)) {
@@ -282,4 +284,11 @@ class OutputFormatter implements WrappableOutputFormatterInterface
return implode("\n", $lines);
}
private function addLineBreaks(string $text, int $width): string
{
$encoding = mb_detect_encoding($text, null, true) ?: 'UTF-8';
return b($text)->toCodePointString($encoding)->wordwrap($width, "\n", true)->toByteString($encoding);
}
}

View File

@@ -33,7 +33,7 @@ class OutputFormatterStyle implements OutputFormatterStyleInterface
* @param string|null $foreground The style foreground color name
* @param string|null $background The style background color name
*/
public function __construct(string $foreground = null, string $background = null, array $options = [])
public function __construct(?string $foreground = null, ?string $background = null, array $options = [])
{
$this->color = new Color($this->foreground = $foreground ?: '', $this->background = $background ?: '', $this->options = $options);
}
@@ -41,7 +41,7 @@ class OutputFormatterStyle implements OutputFormatterStyleInterface
/**
* {@inheritdoc}
*/
public function setForeground(string $color = null)
public function setForeground(?string $color = null)
{
$this->color = new Color($this->foreground = $color ?: '', $this->background, $this->options);
}
@@ -49,7 +49,7 @@ class OutputFormatterStyle implements OutputFormatterStyleInterface
/**
* {@inheritdoc}
*/
public function setBackground(string $color = null)
public function setBackground(?string $color = null)
{
$this->color = new Color($this->foreground, $this->background = $color ?: '', $this->options);
}
@@ -96,7 +96,8 @@ class OutputFormatterStyle implements OutputFormatterStyleInterface
{
if (null === $this->handlesHrefGracefully) {
$this->handlesHrefGracefully = 'JetBrains-JediTerm' !== getenv('TERMINAL_EMULATOR')
&& (!getenv('KONSOLE_VERSION') || (int) getenv('KONSOLE_VERSION') > 201100);
&& (!getenv('KONSOLE_VERSION') || (int) getenv('KONSOLE_VERSION') > 201100)
&& !isset($_SERVER['IDEA_INITIAL_DIRECTORY']);
}
if (null !== $this->href && $this->handlesHrefGracefully) {

View File

@@ -21,12 +21,12 @@ interface OutputFormatterStyleInterface
/**
* Sets style foreground color.
*/
public function setForeground(string $color = null);
public function setForeground(?string $color = null);
/**
* Sets style background color.
*/
public function setBackground(string $color = null);
public function setBackground(?string $color = null);
/**
* Sets some specific style option.

View File

@@ -26,7 +26,7 @@ class OutputFormatterStyleStack implements ResetInterface
private $emptyStyle;
public function __construct(OutputFormatterStyleInterface $emptyStyle = null)
public function __construct(?OutputFormatterStyleInterface $emptyStyle = null)
{
$this->emptyStyle = $emptyStyle ?? new OutputFormatterStyle();
$this->reset();
@@ -55,7 +55,7 @@ class OutputFormatterStyleStack implements ResetInterface
*
* @throws InvalidArgumentException When style tags incorrectly nested
*/
public function pop(OutputFormatterStyleInterface $style = null)
public function pop(?OutputFormatterStyleInterface $style = null)
{
if (empty($this->styles)) {
return $this->emptyStyle;

View File

@@ -26,7 +26,7 @@ final class Dumper
private $cloner;
private $handler;
public function __construct(OutputInterface $output, CliDumper $dumper = null, ClonerInterface $cloner = null)
public function __construct(OutputInterface $output, ?CliDumper $dumper = null, ?ClonerInterface $cloner = null)
{
$this->output = $output;
$this->dumper = $dumper;

View File

@@ -26,7 +26,7 @@ abstract class Helper implements HelperInterface
/**
* {@inheritdoc}
*/
public function setHelperSet(HelperSet $helperSet = null)
public function setHelperSet(?HelperSet $helperSet = null)
{
$this->helperSet = $helperSet;
}
@@ -96,7 +96,7 @@ abstract class Helper implements HelperInterface
*
* @return string
*/
public static function substr(?string $string, int $from, int $length = null)
public static function substr(?string $string, int $from, ?int $length = null)
{
$string ?? $string = '';
@@ -171,6 +171,8 @@ abstract class Helper implements HelperInterface
$string = $formatter->format($string ?? '');
// remove already formatted characters
$string = preg_replace("/\033\[[^m]*m/", '', $string ?? '');
// remove terminal hyperlinks
$string = preg_replace('/\\033]8;[^;]*;[^\\033]*\\033\\\\/', '', $string ?? '');
$formatter->setDecorated($isDecorated);
return $string;

View File

@@ -21,7 +21,7 @@ interface HelperInterface
/**
* Sets the helper set associated with this helper.
*/
public function setHelperSet(HelperSet $helperSet = null);
public function setHelperSet(?HelperSet $helperSet = null);
/**
* Gets the helper set associated with this helper.

View File

@@ -37,7 +37,7 @@ class HelperSet implements \IteratorAggregate
}
}
public function set(HelperInterface $helper, string $alias = null)
public function set(HelperInterface $helper, ?string $alias = null)
{
$this->helpers[$helper->getName()] = $helper;
if (null !== $alias) {
@@ -76,7 +76,7 @@ class HelperSet implements \IteratorAggregate
/**
* @deprecated since Symfony 5.4
*/
public function setCommand(Command $command = null)
public function setCommand(?Command $command = null)
{
trigger_deprecation('symfony/console', '5.4', 'Method "%s()" is deprecated.', __METHOD__);

View File

@@ -32,7 +32,7 @@ class ProcessHelper extends Helper
* @param callable|null $callback A PHP callback to run whenever there is some
* output available on STDOUT or STDERR
*/
public function run(OutputInterface $output, $cmd, string $error = null, callable $callback = null, int $verbosity = OutputInterface::VERBOSITY_VERY_VERBOSE): Process
public function run(OutputInterface $output, $cmd, ?string $error = null, ?callable $callback = null, int $verbosity = OutputInterface::VERBOSITY_VERY_VERBOSE): Process
{
if (!class_exists(Process::class)) {
throw new \LogicException('The ProcessHelper cannot be run as the Process component is not installed. Try running "compose require symfony/process".');
@@ -98,7 +98,7 @@ class ProcessHelper extends Helper
*
* @see run()
*/
public function mustRun(OutputInterface $output, $cmd, string $error = null, callable $callback = null): Process
public function mustRun(OutputInterface $output, $cmd, ?string $error = null, ?callable $callback = null): Process
{
$process = $this->run($output, $cmd, $error, $callback);
@@ -112,7 +112,7 @@ class ProcessHelper extends Helper
/**
* Wraps a Process callback to add debugging output.
*/
public function wrapCallback(OutputInterface $output, Process $process, callable $callback = null): callable
public function wrapCallback(OutputInterface $output, Process $process, ?callable $callback = null): callable
{
if ($output instanceof ConsoleOutputInterface) {
$output = $output->getErrorOutput();

View File

@@ -53,7 +53,6 @@ final class ProgressBar
private $startTime;
private $stepWidth;
private $percent = 0.0;
private $formatLineCount;
private $messages = [];
private $overwrite = true;
private $terminal;
@@ -170,9 +169,12 @@ final class ProgressBar
$this->messages[$name] = $message;
}
/**
* @return string|null
*/
public function getMessage(string $name = 'message')
{
return $this->messages[$name];
return $this->messages[$name] ?? null;
}
public function getStartTime(): int
@@ -294,7 +296,7 @@ final class ProgressBar
*
* @param int|null $max Number of steps to complete the bar (0 if indeterminate), if null it will be inferred from $iterable
*/
public function iterate(iterable $iterable, int $max = null): iterable
public function iterate(iterable $iterable, ?int $max = null): iterable
{
$this->start($max ?? (is_countable($iterable) ? \count($iterable) : 0));
@@ -312,7 +314,7 @@ final class ProgressBar
*
* @param int|null $max Number of steps to complete the bar (0 if indeterminate), null to leave unchanged
*/
public function start(int $max = null)
public function start(?int $max = null)
{
$this->startTime = time();
$this->step = 0;
@@ -446,8 +448,6 @@ final class ProgressBar
} else {
$this->format = $format;
}
$this->formatLineCount = substr_count($this->format, "\n");
}
/**
@@ -464,7 +464,7 @@ final class ProgressBar
if ($this->overwrite) {
if (null !== $this->previousMessage) {
if ($this->output instanceof ConsoleSectionOutput) {
$messageLines = explode("\n", $message);
$messageLines = explode("\n", $this->previousMessage);
$lineCount = \count($messageLines);
foreach ($messageLines as $messageLine) {
$messageLineLength = Helper::width(Helper::removeDecoration($this->output->getFormatter(), $messageLine));
@@ -474,7 +474,8 @@ final class ProgressBar
}
$this->output->clear($lineCount);
} else {
for ($i = 0; $i < $this->formatLineCount; ++$i) {
$lineCount = substr_count($this->previousMessage, "\n");
for ($i = 0; $i < $lineCount; ++$i) {
$this->cursor->moveToColumn(1);
$this->cursor->clearLine();
$this->cursor->moveUp();

View File

@@ -50,7 +50,7 @@ class ProgressIndicator
* @param int $indicatorChangeInterval Change interval in milliseconds
* @param array|null $indicatorValues Animated indicator characters
*/
public function __construct(OutputInterface $output, string $format = null, int $indicatorChangeInterval = 100, array $indicatorValues = null)
public function __construct(OutputInterface $output, ?string $format = null, int $indicatorChangeInterval = 100, ?array $indicatorValues = null)
{
$this->output = $output;
@@ -129,8 +129,6 @@ class ProgressIndicator
/**
* Finish the indicator with message.
*
* @param $message
*/
public function finish(string $message)
{

View File

@@ -24,6 +24,7 @@ use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Question\ChoiceQuestion;
use Symfony\Component\Console\Question\Question;
use Symfony\Component\Console\Terminal;
use function Symfony\Component\String\s;
/**
@@ -127,7 +128,18 @@ class QuestionHelper extends Helper
}
if (false === $ret) {
$isBlocked = stream_get_meta_data($inputStream)['blocked'] ?? true;
if (!$isBlocked) {
stream_set_blocking($inputStream, true);
}
$ret = $this->readInput($inputStream, $question);
if (!$isBlocked) {
stream_set_blocking($inputStream, false);
}
if (false === $ret) {
throw new MissingInputException('Aborted.');
}
@@ -491,21 +503,7 @@ class QuestionHelper extends Helper
return self::$stdinIsInteractive;
}
if (\function_exists('stream_isatty')) {
return self::$stdinIsInteractive = @stream_isatty(fopen('php://stdin', 'r'));
}
if (\function_exists('posix_isatty')) {
return self::$stdinIsInteractive = @posix_isatty(fopen('php://stdin', 'r'));
}
if (!\function_exists('exec')) {
return self::$stdinIsInteractive = true;
}
exec('stty 2> /dev/null', $output, $status);
return self::$stdinIsInteractive = 1 !== $status;
return self::$stdinIsInteractive = @stream_isatty(fopen('php://stdin', 'r'));
}
/**

View File

@@ -451,7 +451,7 @@ class Table
*
* +-----+-----------+-------+
*/
private function renderRowSeparator(int $type = self::SEPARATOR_MID, string $title = null, string $titleFormat = null)
private function renderRowSeparator(int $type = self::SEPARATOR_MID, ?string $title = null, ?string $titleFormat = null)
{
if (0 === $count = $this->numberOfColumns) {
return;
@@ -516,7 +516,7 @@ class Table
*
* | 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens |
*/
private function renderRow(array $row, string $cellFormat, string $firstCellFormat = null)
private function renderRow(array $row, string $cellFormat, ?string $firstCellFormat = null)
{
$rowContent = $this->renderColumnSeparator(self::BORDER_OUTSIDE);
$columns = $this->getRowColumns($row);
@@ -621,9 +621,10 @@ class Table
if (!strstr($cell ?? '', "\n")) {
continue;
}
$escaped = implode("\n", array_map([OutputFormatter::class, 'escapeTrailingBackslash'], explode("\n", $cell)));
$eol = str_contains($cell ?? '', "\r\n") ? "\r\n" : "\n";
$escaped = implode($eol, array_map([OutputFormatter::class, 'escapeTrailingBackslash'], explode($eol, $cell)));
$cell = $cell instanceof TableCell ? new TableCell($escaped, ['colspan' => $cell->getColspan()]) : $escaped;
$lines = explode("\n", str_replace("\n", "<fg=default;bg=default>\n</>", $cell));
$lines = explode($eol, str_replace($eol, '<fg=default;bg=default></>'.$eol, $cell));
foreach ($lines as $lineKey => $line) {
if ($colspan > 1) {
$line = new TableCell($line, ['colspan' => $colspan]);
@@ -678,15 +679,16 @@ class Table
{
$unmergedRows = [];
foreach ($rows[$line] as $column => $cell) {
if (null !== $cell && !$cell instanceof TableCell && !is_scalar($cell) && !(\is_object($cell) && method_exists($cell, '__toString'))) {
if (null !== $cell && !$cell instanceof TableCell && !\is_scalar($cell) && !(\is_object($cell) && method_exists($cell, '__toString'))) {
throw new InvalidArgumentException(sprintf('A cell must be a TableCell, a scalar or an object implementing "__toString()", "%s" given.', get_debug_type($cell)));
}
if ($cell instanceof TableCell && $cell->getRowspan() > 1) {
$nbLines = $cell->getRowspan() - 1;
$lines = [$cell];
if (strstr($cell, "\n")) {
$lines = explode("\n", str_replace("\n", "<fg=default;bg=default>\n</>", $cell));
$nbLines = \count($lines) > $nbLines ? substr_count($cell, "\n") : $nbLines;
$eol = str_contains($cell, "\r\n") ? "\r\n" : "\n";
$lines = explode($eol, str_replace($eol, '<fg=default;bg=default>'.$eol.'</>', $cell));
$nbLines = \count($lines) > $nbLines ? substr_count($cell, $eol) : $nbLines;
$rows[$line][$column] = new TableCell($lines[0], ['colspan' => $cell->getColspan(), 'style' => $cell->getStyle()]);
unset($lines[0]);
@@ -800,18 +802,18 @@ class Table
continue;
}
foreach ($row as $i => $cell) {
if ($cell instanceof TableCell) {
$textContent = Helper::removeDecoration($this->output->getFormatter(), $cell);
$textLength = Helper::width($textContent);
if ($textLength > 0) {
$contentColumns = str_split($textContent, ceil($textLength / $cell->getColspan()));
foreach ($contentColumns as $position => $content) {
$row[$i + $position] = $content;
foreach ($row as $i => $cell) {
if ($cell instanceof TableCell) {
$textContent = Helper::removeDecoration($this->output->getFormatter(), $cell);
$textLength = Helper::width($textContent);
if ($textLength > 0) {
$contentColumns = mb_str_split($textContent, ceil($textLength / $cell->getColspan()));
foreach ($contentColumns as $position => $content) {
$row[$i + $position] = $content;
}
}
}
}
}
$lengths[] = $this->getCellWidth($row, $column);
}

View File

@@ -90,7 +90,7 @@ class TableStyle
*
* @return $this
*/
public function setHorizontalBorderChars(string $outside, string $inside = null): self
public function setHorizontalBorderChars(string $outside, ?string $inside = null): self
{
$this->horizontalOutsideBorderChar = $outside;
$this->horizontalInsideBorderChar = $inside ?? $outside;
@@ -115,7 +115,7 @@ class TableStyle
*
* @return $this
*/
public function setVerticalBorderChars(string $outside, string $inside = null): self
public function setVerticalBorderChars(string $outside, ?string $inside = null): self
{
$this->verticalOutsideBorderChar = $outside;
$this->verticalInsideBorderChar = $inside ?? $outside;
@@ -169,7 +169,7 @@ class TableStyle
*
* @return $this
*/
public function setCrossingChars(string $cross, string $topLeft, string $topMid, string $topRight, string $midRight, string $bottomRight, string $bottomMid, string $bottomLeft, string $midLeft, string $topLeftBottom = null, string $topMidBottom = null, string $topRightBottom = null): self
public function setCrossingChars(string $cross, string $topLeft, string $topMid, string $topRight, string $midRight, string $bottomRight, string $bottomMid, string $bottomLeft, string $midLeft, ?string $topLeftBottom = null, ?string $topMidBottom = null, ?string $topRightBottom = null): self
{
$this->crossingChar = $cross;
$this->crossingTopLeftChar = $topLeft;

View File

@@ -43,7 +43,7 @@ class ArgvInput extends Input
private $tokens;
private $parsed;
public function __construct(array $argv = null, InputDefinition $definition = null)
public function __construct(?array $argv = null, ?InputDefinition $definition = null)
{
$argv = $argv ?? $_SERVER['argv'] ?? [];

View File

@@ -27,7 +27,7 @@ class ArrayInput extends Input
{
private $parameters;
public function __construct(array $parameters, InputDefinition $definition = null)
public function __construct(array $parameters, ?InputDefinition $definition = null)
{
$this->parameters = $parameters;

View File

@@ -33,7 +33,7 @@ abstract class Input implements InputInterface, StreamableInputInterface
protected $arguments = [];
protected $interactive = true;
public function __construct(InputDefinition $definition = null)
public function __construct(?InputDefinition $definition = null)
{
if (null === $definition) {
$this->definition = new InputDefinition();

View File

@@ -32,13 +32,13 @@ class InputArgument
/**
* @param string $name The argument name
* @param int|null $mode The argument mode: self::REQUIRED or self::OPTIONAL
* @param int|null $mode The argument mode: a bit mask of self::REQUIRED, self::OPTIONAL and self::IS_ARRAY
* @param string $description A description text
* @param string|bool|int|float|array|null $default The default value (for self::OPTIONAL mode only)
*
* @throws InvalidArgumentException When argument mode is not valid
*/
public function __construct(string $name, int $mode = null, string $description = '', $default = null)
public function __construct(string $name, ?int $mode = null, string $description = '', $default = null)
{
if (null === $mode) {
$mode = self::OPTIONAL;
@@ -92,7 +92,7 @@ class InputArgument
*/
public function setDefault($default = null)
{
if (self::REQUIRED === $this->mode && null !== $default) {
if ($this->isRequired() && null !== $default) {
throw new LogicException('Cannot set a default value except for InputArgument::OPTIONAL mode.');
}

View File

@@ -59,7 +59,7 @@ class InputOption
*
* @throws InvalidArgumentException If option mode is invalid or incompatible
*/
public function __construct(string $name, $shortcut = null, int $mode = null, string $description = '', $default = null)
public function __construct(string $name, $shortcut = null, ?int $mode = null, string $description = '', $default = null)
{
if (str_starts_with($name, '--')) {
$name = substr($name, 2);
@@ -69,7 +69,7 @@ class InputOption
throw new InvalidArgumentException('An option name cannot be empty.');
}
if (empty($shortcut)) {
if ('' === $shortcut || [] === $shortcut || false === $shortcut) {
$shortcut = null;
}
@@ -78,10 +78,10 @@ class InputOption
$shortcut = implode('|', $shortcut);
}
$shortcuts = preg_split('{(\|)-?}', ltrim($shortcut, '-'));
$shortcuts = array_filter($shortcuts);
$shortcuts = array_filter($shortcuts, 'strlen');
$shortcut = implode('|', $shortcuts);
if (empty($shortcut)) {
if ('' === $shortcut) {
throw new InvalidArgumentException('An option shortcut cannot be empty.');
}
}

View File

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

View File

@@ -110,7 +110,7 @@ class ConsoleLogger extends AbstractLogger
$replacements = [];
foreach ($context as $key => $val) {
if (null === $val || is_scalar($val) || (\is_object($val) && method_exists($val, '__toString'))) {
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);

View File

@@ -37,7 +37,7 @@ class ConsoleOutput extends StreamOutput implements ConsoleOutputInterface
* @param bool|null $decorated Whether to decorate messages (null for auto-guessing)
* @param OutputFormatterInterface|null $formatter Output formatter instance (null to use default OutputFormatter)
*/
public function __construct(int $verbosity = self::VERBOSITY_NORMAL, bool $decorated = null, OutputFormatterInterface $formatter = null)
public function __construct(int $verbosity = self::VERBOSITY_NORMAL, ?bool $decorated = null, ?OutputFormatterInterface $formatter = null)
{
parent::__construct($this->openOutputStream(), $verbosity, $decorated, $formatter);

View File

@@ -43,7 +43,7 @@ class ConsoleSectionOutput extends StreamOutput
*
* @param int $lines Number of lines to clear. If null, then the entire output of this section is cleared
*/
public function clear(int $lines = null)
public function clear(?int $lines = null)
{
if (empty($this->content) || !$this->isDecorated()) {
return;

View File

@@ -37,7 +37,7 @@ abstract class Output implements OutputInterface
* @param bool $decorated Whether to decorate messages
* @param OutputFormatterInterface|null $formatter Output formatter instance (null to use default OutputFormatter)
*/
public function __construct(?int $verbosity = self::VERBOSITY_NORMAL, bool $decorated = false, OutputFormatterInterface $formatter = null)
public function __construct(?int $verbosity = self::VERBOSITY_NORMAL, bool $decorated = false, ?OutputFormatterInterface $formatter = null)
{
$this->verbosity = $verbosity ?? self::VERBOSITY_NORMAL;
$this->formatter = $formatter ?? new OutputFormatter();

View File

@@ -39,7 +39,7 @@ class StreamOutput extends Output
*
* @throws InvalidArgumentException When first argument is not a real stream
*/
public function __construct($stream, int $verbosity = self::VERBOSITY_NORMAL, bool $decorated = null, OutputFormatterInterface $formatter = null)
public function __construct($stream, int $verbosity = self::VERBOSITY_NORMAL, ?bool $decorated = null, ?OutputFormatterInterface $formatter = null)
{
if (!\is_resource($stream) || 'stream' !== get_resource_type($stream)) {
throw new InvalidArgumentException('The StreamOutput class needs a stream as its first argument.');
@@ -64,9 +64,6 @@ class StreamOutput extends Output
return $this->stream;
}
/**
* {@inheritdoc}
*/
protected function doWrite(string $message, bool $newline)
{
if ($newline) {
@@ -98,18 +95,29 @@ class StreamOutput extends Output
return false;
}
if ('Hyper' === getenv('TERM_PROGRAM')) {
// Detect msysgit/mingw and assume this is a tty because detection
// does not work correctly, see https://github.com/composer/composer/issues/9690
if (!@stream_isatty($this->stream) && !\in_array(strtoupper((string) getenv('MSYSTEM')), ['MINGW32', 'MINGW64'], true)) {
return false;
}
if ('\\' === \DIRECTORY_SEPARATOR && @sapi_windows_vt100_support($this->stream)) {
return true;
}
if (\DIRECTORY_SEPARATOR === '\\') {
return (\function_exists('sapi_windows_vt100_support')
&& @sapi_windows_vt100_support($this->stream))
|| false !== getenv('ANSICON')
|| 'ON' === getenv('ConEmuANSI')
|| 'xterm' === getenv('TERM');
if ('Hyper' === getenv('TERM_PROGRAM')
|| false !== getenv('COLORTERM')
|| false !== getenv('ANSICON')
|| 'ON' === getenv('ConEmuANSI')
) {
return true;
}
return stream_isatty($this->stream);
if ('dumb' === $term = (string) getenv('TERM')) {
return false;
}
// See https://github.com/chalk/supports-color/blob/d4f413efaf8da045c5ab440ed418ef02dbb28bf1/index.js#L157
return preg_match('/^((screen|xterm|vt100|vt220|putty|rxvt|ansi|cygwin|linux).*)|(.*-256(color)?(-bce)?)$/', $term);
}
}

View File

@@ -24,7 +24,7 @@ class TrimmedBufferOutput extends Output
private $maxLength;
private $buffer = '';
public function __construct(int $maxLength, ?int $verbosity = self::VERBOSITY_NORMAL, bool $decorated = false, OutputFormatterInterface $formatter = null)
public function __construct(int $maxLength, ?int $verbosity = self::VERBOSITY_NORMAL, bool $decorated = false, ?OutputFormatterInterface $formatter = null)
{
if ($maxLength <= 0) {
throw new InvalidArgumentException(sprintf('"%s()" expects a strictly positive maxLength. Got %d.', __METHOD__, $maxLength));

View File

@@ -186,7 +186,7 @@ class Question
*
* @return $this
*/
public function setAutocompleterCallback(callable $callback = null): self
public function setAutocompleterCallback(?callable $callback = null): self
{
if ($this->hidden && null !== $callback) {
throw new LogicException('A hidden question cannot use the autocompleter.');
@@ -202,7 +202,7 @@ class Question
*
* @return $this
*/
public function setValidator(callable $validator = null)
public function setValidator(?callable $validator = null)
{
$this->validator = $validator;

View File

@@ -11,18 +11,21 @@ _sf_{{ COMMAND_NAME }}() {
local sf_cmd="${COMP_WORDS[0]}"
# for an alias, get the real script behind it
if [[ $(type -t $sf_cmd) == "alias" ]]; then
sf_cmd_type=$(type -t $sf_cmd)
if [[ $sf_cmd_type == "alias" ]]; then
sf_cmd=$(alias $sf_cmd | sed -E "s/alias $sf_cmd='(.*)'/\1/")
elif [[ $sf_cmd_type == "file" ]]; then
sf_cmd=$(type -p $sf_cmd)
fi
if [ ! -f "$sf_cmd" ]; then
if [[ $sf_cmd_type != "function" && ! -x $sf_cmd ]]; then
return 1
fi
local cur prev words cword
_get_comp_words_by_ref -n := cur prev words cword
local completecmd=("$sf_cmd" "_complete" "-sbash" "-c$cword" "-S{{ VERSION }}")
local completecmd=("$sf_cmd" "_complete" "--no-interaction" "-sbash" "-c$cword" "-S{{ VERSION }}")
for w in ${words[@]}; do
w=$(printf -- '%b' "$w")
# remove quotes from typed values

View File

@@ -43,7 +43,7 @@ final class SignalRegistry
return false;
}
if (\in_array('pcntl_signal', explode(',', ini_get('disable_functions')))) {
if (\in_array('pcntl_signal', explode(',', \ini_get('disable_functions')))) {
return false;
}

View File

@@ -46,7 +46,7 @@ class SingleCommandApplication extends Command
return $this;
}
public function run(InputInterface $input = null, OutputInterface $output = null): int
public function run(?InputInterface $input = null, ?OutputInterface $output = null): int
{
if ($this->running) {
return parent::run($input, $output);

View File

@@ -85,14 +85,14 @@ interface StyleInterface
*
* @return mixed
*/
public function ask(string $question, string $default = null, callable $validator = null);
public function ask(string $question, ?string $default = null, ?callable $validator = null);
/**
* Asks a question with the user input hidden.
*
* @return mixed
*/
public function askHidden(string $question, callable $validator = null);
public function askHidden(string $question, ?callable $validator = null);
/**
* Asks for confirmation.

View File

@@ -61,7 +61,7 @@ class SymfonyStyle extends OutputStyle
*
* @param string|array $messages The message to write in the block
*/
public function block($messages, string $type = null, string $style = null, string $prefix = ' ', bool $padding = false, bool $escape = true)
public function block($messages, ?string $type = null, ?string $style = null, string $prefix = ' ', bool $padding = false, bool $escape = true)
{
$messages = \is_array($messages) ? array_values($messages) : [$messages];
@@ -250,7 +250,7 @@ class SymfonyStyle extends OutputStyle
/**
* {@inheritdoc}
*/
public function ask(string $question, string $default = null, callable $validator = null)
public function ask(string $question, ?string $default = null, ?callable $validator = null)
{
$question = new Question($question, $default);
$question->setValidator($validator);
@@ -261,7 +261,7 @@ class SymfonyStyle extends OutputStyle
/**
* {@inheritdoc}
*/
public function askHidden(string $question, callable $validator = null)
public function askHidden(string $question, ?callable $validator = null)
{
$question = new Question($question);
@@ -338,7 +338,7 @@ class SymfonyStyle extends OutputStyle
/**
* @see ProgressBar::iterate()
*/
public function progressIterate(iterable $iterable, int $max = null): iterable
public function progressIterate(iterable $iterable, ?int $max = null): iterable
{
yield from $this->createProgressBar()->iterate($iterable, $max);
@@ -440,18 +440,18 @@ class SymfonyStyle extends OutputStyle
$chars = substr(str_replace(\PHP_EOL, "\n", $this->bufferedOutput->fetch()), -2);
if (!isset($chars[0])) {
$this->newLine(); //empty history, so we should start with a new line.
$this->newLine(); // empty history, so we should start with a new line.
return;
}
//Prepend new line for each non LF chars (This means no blank line was output before)
// Prepend new line for each non LF chars (This means no blank line was output before)
$this->newLine(2 - substr_count($chars, "\n"));
}
private function autoPrependText(): void
{
$fetched = $this->bufferedOutput->fetch();
//Prepend new line if last char isn't EOL:
// Prepend new line if last char isn't EOL:
if (!str_ends_with($fetched, "\n")) {
$this->newLine();
}
@@ -463,7 +463,7 @@ class SymfonyStyle extends OutputStyle
$this->bufferedOutput->write($message, $newLine, $type);
}
private function createBlock(iterable $messages, string $type = null, string $style = null, string $prefix = ' ', bool $padding = false, bool $escape = false): array
private function createBlock(iterable $messages, ?string $type = null, ?string $style = null, string $prefix = ' ', bool $padding = false, bool $escape = false): array
{
$indentLength = 0;
$prefixLength = Helper::width(Helper::removeDecoration($this->getFormatter(), $prefix));

View File

@@ -64,20 +64,19 @@ class Terminal
return self::$stty;
}
// skip check if exec function is disabled
if (!\function_exists('exec')) {
// skip check if shell_exec function is disabled
if (!\function_exists('shell_exec')) {
return false;
}
exec('stty 2>&1', $output, $exitcode);
return self::$stty = 0 === $exitcode;
return self::$stty = (bool) shell_exec('stty 2> '.('\\' === \DIRECTORY_SEPARATOR ? 'NUL' : '/dev/null'));
}
private static function initDimensions()
{
if ('\\' === \DIRECTORY_SEPARATOR) {
if (preg_match('/^(\d+)x(\d+)(?: \((\d+)x(\d+)\))?$/', trim(getenv('ANSICON')), $matches)) {
$ansicon = getenv('ANSICON');
if (false !== $ansicon && preg_match('/^(\d+)x(\d+)(?: \((\d+)x(\d+)\))?$/', trim($ansicon), $matches)) {
// extract [w, H] from "wxh (WxH)"
// or [w, h] from "wxh"
self::$width = (int) $matches[1];
@@ -157,6 +156,8 @@ class Terminal
2 => ['pipe', 'w'],
];
$cp = \function_exists('sapi_windows_cp_set') ? sapi_windows_cp_get() : 0;
$process = proc_open($command, $descriptorspec, $pipes, null, null, ['suppress_errors' => true]);
if (!\is_resource($process)) {
return null;
@@ -167,6 +168,10 @@ class Terminal
fclose($pipes[2]);
proc_close($process);
if ($cp) {
sapi_windows_cp_set($cp);
}
return $info;
}
}

View File

@@ -49,17 +49,37 @@ class ApplicationTester
*/
public function run(array $input, array $options = [])
{
$this->input = new ArrayInput($input);
if (isset($options['interactive'])) {
$this->input->setInteractive($options['interactive']);
$prevShellVerbosity = getenv('SHELL_VERBOSITY');
try {
$this->input = new ArrayInput($input);
if (isset($options['interactive'])) {
$this->input->setInteractive($options['interactive']);
}
if ($this->inputs) {
$this->input->setStream(self::createStream($this->inputs));
}
$this->initOutput($options);
return $this->statusCode = $this->application->run($this->input, $this->output);
} finally {
// SHELL_VERBOSITY is set by Application::configureIO so we need to unset/reset it
// to its previous value to avoid one test's verbosity to spread to the following tests
if (false === $prevShellVerbosity) {
if (\function_exists('putenv')) {
@putenv('SHELL_VERBOSITY');
}
unset($_ENV['SHELL_VERBOSITY']);
unset($_SERVER['SHELL_VERBOSITY']);
} else {
if (\function_exists('putenv')) {
@putenv('SHELL_VERBOSITY='.$prevShellVerbosity);
}
$_ENV['SHELL_VERBOSITY'] = $prevShellVerbosity;
$_SERVER['SHELL_VERBOSITY'] = $prevShellVerbosity;
}
}
if ($this->inputs) {
$this->input->setStream(self::createStream($this->inputs));
}
$this->initOutput($options);
return $this->statusCode = $this->application->run($this->input, $this->output);
}
}

View File

@@ -35,9 +35,9 @@ trait TesterTrait
/**
* Gets the display returned by the last execution of the command or application.
*
* @throws \RuntimeException If it's called before the execute method
*
* @return string
*
* @throws \RuntimeException If it's called before the execute method
*/
public function getDisplay(bool $normalize = false)
{
@@ -103,9 +103,9 @@ trait TesterTrait
/**
* Gets the status code returned by the last execution of the command or application.
*
* @throws \RuntimeException If it's called before the execute method
*
* @return int
*
* @throws \RuntimeException If it's called before the execute method
*/
public function getStatusCode()
{

View File

@@ -2,7 +2,7 @@
"name": "symfony/console",
"type": "library",
"description": "Eases the creation of beautiful and testable command line interfaces",
"keywords": ["console", "cli", "command line", "terminal"],
"keywords": ["console", "cli", "command-line", "terminal"],
"homepage": "https://symfony.com",
"license": "MIT",
"authors": [