[Console] enable describing commands in ways that make the list command lazy

This commit is contained in:
Nicolas Grekas 2021-01-15 13:40:32 +01:00
parent 28533aa43c
commit 8a1a1b8171
51 changed files with 463 additions and 90 deletions

View File

@ -34,6 +34,7 @@ class ServerLogCommand extends Command
private $handler; private $handler;
protected static $defaultName = 'server:log'; protected static $defaultName = 'server:log';
protected static $defaultDescription = 'Starts a log server that displays logs in real time';
public function isEnabled() public function isEnabled()
{ {
@ -60,7 +61,7 @@ class ServerLogCommand extends Command
->addOption('format', null, InputOption::VALUE_REQUIRED, 'The line format', ConsoleFormatter::SIMPLE_FORMAT) ->addOption('format', null, InputOption::VALUE_REQUIRED, 'The line format', ConsoleFormatter::SIMPLE_FORMAT)
->addOption('date-format', null, InputOption::VALUE_REQUIRED, 'The date format', ConsoleFormatter::SIMPLE_DATE) ->addOption('date-format', null, InputOption::VALUE_REQUIRED, 'The date format', ConsoleFormatter::SIMPLE_DATE)
->addOption('filter', null, InputOption::VALUE_REQUIRED, 'An expression to filter log. Example: "level > 200 or channel in [\'app\', \'doctrine\']"') ->addOption('filter', null, InputOption::VALUE_REQUIRED, 'An expression to filter log. Example: "level > 200 or channel in [\'app\', \'doctrine\']"')
->setDescription('Starts a log server that displays logs in real time') ->setDescription(self::$defaultDescription)
->setHelp(<<<'EOF' ->setHelp(<<<'EOF'
<info>%command.name%</info> starts a log server to display in real time the log <info>%command.name%</info> starts a log server to display in real time the log
messages generated by your application: messages generated by your application:

View File

@ -33,6 +33,7 @@ use Twig\Loader\FilesystemLoader;
class DebugCommand extends Command class DebugCommand extends Command
{ {
protected static $defaultName = 'debug:twig'; protected static $defaultName = 'debug:twig';
protected static $defaultDescription = 'Shows a list of twig functions, filters, globals and tests';
private $twig; private $twig;
private $projectDir; private $projectDir;
@ -60,7 +61,7 @@ class DebugCommand extends Command
new InputOption('filter', null, InputOption::VALUE_REQUIRED, 'Show details for all entries matching this filter'), new InputOption('filter', null, InputOption::VALUE_REQUIRED, 'Show details for all entries matching this filter'),
new InputOption('format', null, InputOption::VALUE_REQUIRED, 'The output format (text or json)', 'text'), new InputOption('format', null, InputOption::VALUE_REQUIRED, 'The output format (text or json)', 'text'),
]) ])
->setDescription('Shows a list of twig functions, filters, globals and tests') ->setDescription(self::$defaultDescription)
->setHelp(<<<'EOF' ->setHelp(<<<'EOF'
The <info>%command.name%</info> command outputs a list of twig functions, The <info>%command.name%</info> command outputs a list of twig functions,
filters, globals and tests. filters, globals and tests.

View File

@ -35,6 +35,7 @@ use Twig\Source;
class LintCommand extends Command class LintCommand extends Command
{ {
protected static $defaultName = 'lint:twig'; protected static $defaultName = 'lint:twig';
protected static $defaultDescription = 'Lints a template and outputs encountered errors';
private $twig; private $twig;
@ -48,7 +49,7 @@ class LintCommand extends Command
protected function configure() protected function configure()
{ {
$this $this
->setDescription('Lints a template and outputs encountered errors') ->setDescription(self::$defaultDescription)
->addOption('format', null, InputOption::VALUE_REQUIRED, 'The output format', 'txt') ->addOption('format', null, InputOption::VALUE_REQUIRED, 'The output format', 'txt')
->addOption('show-deprecations', null, InputOption::VALUE_NONE, 'Show deprecations as errors') ->addOption('show-deprecations', null, InputOption::VALUE_NONE, 'Show deprecations as errors')
->addArgument('filename', InputArgument::IS_ARRAY, 'A file, a directory or "-" for reading from STDIN') ->addArgument('filename', InputArgument::IS_ARRAY, 'A file, a directory or "-" for reading from STDIN')

View File

@ -11,7 +11,9 @@
namespace Symfony\Component\DependencyInjection\Loader\Configurator; namespace Symfony\Component\DependencyInjection\Loader\Configurator;
use Monolog\Formatter\FormatterInterface;
use Symfony\Bridge\Monolog\Command\ServerLogCommand; use Symfony\Bridge\Monolog\Command\ServerLogCommand;
use Symfony\Bridge\Monolog\Formatter\ConsoleFormatter;
use Symfony\Bridge\Twig\Extension\DumpExtension; use Symfony\Bridge\Twig\Extension\DumpExtension;
use Symfony\Component\HttpKernel\DataCollector\DumpDataCollector; use Symfony\Component\HttpKernel\DataCollector\DumpDataCollector;
use Symfony\Component\HttpKernel\EventListener\DumpListener; use Symfony\Component\HttpKernel\EventListener\DumpListener;
@ -127,9 +129,12 @@ return static function (ContainerConfigurator $container) {
'html' => inline_service(HtmlDescriptor::class)->args([service('var_dumper.html_dumper')]), 'html' => inline_service(HtmlDescriptor::class)->args([service('var_dumper.html_dumper')]),
], ],
]) ])
->tag('console.command', ['command' => 'server:dump']) ->tag('console.command')
->set('monolog.command.server_log', ServerLogCommand::class) ->set('monolog.command.server_log', ServerLogCommand::class)
->tag('console.command', ['command' => 'server:log'])
; ;
if (class_exists(ConsoleFormatter::class) && interface_exists(FormatterInterface::class)) {
$container->services()->get('monolog.command.server_log')->tag('console.command');
}
}; };

View File

@ -30,6 +30,7 @@ use Symfony\Component\HttpKernel\KernelInterface;
class AboutCommand extends Command class AboutCommand extends Command
{ {
protected static $defaultName = 'about'; protected static $defaultName = 'about';
protected static $defaultDescription = 'Displays information about the current project';
/** /**
* {@inheritdoc} * {@inheritdoc}
@ -37,7 +38,7 @@ class AboutCommand extends Command
protected function configure() protected function configure()
{ {
$this $this
->setDescription('Displays information about the current project') ->setDescription(self::$defaultDescription)
->setHelp(<<<'EOT' ->setHelp(<<<'EOT'
The <info>%command.name%</info> command displays information about the current Symfony project. The <info>%command.name%</info> command displays information about the current Symfony project.

View File

@ -40,6 +40,7 @@ class AssetsInstallCommand extends Command
public const METHOD_RELATIVE_SYMLINK = 'relative symlink'; public const METHOD_RELATIVE_SYMLINK = 'relative symlink';
protected static $defaultName = 'assets:install'; protected static $defaultName = 'assets:install';
protected static $defaultDescription = 'Installs bundles web assets under a public directory';
private $filesystem; private $filesystem;
private $projectDir; private $projectDir;
@ -64,7 +65,7 @@ class AssetsInstallCommand extends Command
->addOption('symlink', null, InputOption::VALUE_NONE, 'Symlinks the assets instead of copying it') ->addOption('symlink', null, InputOption::VALUE_NONE, 'Symlinks the assets instead of copying it')
->addOption('relative', null, InputOption::VALUE_NONE, 'Make relative symlinks') ->addOption('relative', null, InputOption::VALUE_NONE, 'Make relative symlinks')
->addOption('no-cleanup', null, InputOption::VALUE_NONE, 'Do not remove the assets of the bundles that no longer exist') ->addOption('no-cleanup', null, InputOption::VALUE_NONE, 'Do not remove the assets of the bundles that no longer exist')
->setDescription('Installs bundles web assets under a public directory') ->setDescription(self::$defaultDescription)
->setHelp(<<<'EOT' ->setHelp(<<<'EOT'
The <info>%command.name%</info> command installs bundle assets into a given The <info>%command.name%</info> command installs bundle assets into a given
directory (e.g. the <comment>public</comment> directory). directory (e.g. the <comment>public</comment> directory).

View File

@ -36,6 +36,7 @@ use Symfony\Component\HttpKernel\RebootableInterface;
class CacheClearCommand extends Command class CacheClearCommand extends Command
{ {
protected static $defaultName = 'cache:clear'; protected static $defaultName = 'cache:clear';
protected static $defaultDescription = 'Clears the cache';
private $cacheClearer; private $cacheClearer;
private $filesystem; private $filesystem;
@ -58,7 +59,7 @@ class CacheClearCommand extends Command
new InputOption('no-warmup', '', InputOption::VALUE_NONE, 'Do not warm up the cache'), new InputOption('no-warmup', '', InputOption::VALUE_NONE, 'Do not warm up the cache'),
new InputOption('no-optional-warmers', '', InputOption::VALUE_NONE, 'Skip optional cache warmers (faster)'), new InputOption('no-optional-warmers', '', InputOption::VALUE_NONE, 'Skip optional cache warmers (faster)'),
]) ])
->setDescription('Clears the cache') ->setDescription(self::$defaultDescription)
->setHelp(<<<'EOF' ->setHelp(<<<'EOF'
The <info>%command.name%</info> command clears the application cache for a given environment The <info>%command.name%</info> command clears the application cache for a given environment
and debug mode: and debug mode:

View File

@ -28,6 +28,7 @@ use Symfony\Component\HttpKernel\CacheClearer\Psr6CacheClearer;
final class CachePoolClearCommand extends Command final class CachePoolClearCommand extends Command
{ {
protected static $defaultName = 'cache:pool:clear'; protected static $defaultName = 'cache:pool:clear';
protected static $defaultDescription = 'Clears cache pools';
private $poolClearer; private $poolClearer;
@ -47,7 +48,7 @@ final class CachePoolClearCommand extends Command
->setDefinition([ ->setDefinition([
new InputArgument('pools', InputArgument::IS_ARRAY | InputArgument::REQUIRED, 'A list of cache pools or cache pool clearers'), new InputArgument('pools', InputArgument::IS_ARRAY | InputArgument::REQUIRED, 'A list of cache pools or cache pool clearers'),
]) ])
->setDescription('Clears cache pools') ->setDescription(self::$defaultDescription)
->setHelp(<<<'EOF' ->setHelp(<<<'EOF'
The <info>%command.name%</info> command clears the given cache pools or cache pool clearers. The <info>%command.name%</info> command clears the given cache pools or cache pool clearers.

View File

@ -26,6 +26,7 @@ use Symfony\Component\HttpKernel\CacheClearer\Psr6CacheClearer;
final class CachePoolDeleteCommand extends Command final class CachePoolDeleteCommand extends Command
{ {
protected static $defaultName = 'cache:pool:delete'; protected static $defaultName = 'cache:pool:delete';
protected static $defaultDescription = 'Deletes an item from a cache pool';
private $poolClearer; private $poolClearer;
@ -46,7 +47,7 @@ final class CachePoolDeleteCommand extends Command
new InputArgument('pool', InputArgument::REQUIRED, 'The cache pool from which to delete an item'), new InputArgument('pool', InputArgument::REQUIRED, 'The cache pool from which to delete an item'),
new InputArgument('key', InputArgument::REQUIRED, 'The cache key to delete from the pool'), new InputArgument('key', InputArgument::REQUIRED, 'The cache key to delete from the pool'),
]) ])
->setDescription('Deletes an item from a cache pool') ->setDescription(self::$defaultDescription)
->setHelp(<<<'EOF' ->setHelp(<<<'EOF'
The <info>%command.name%</info> deletes an item from a given cache pool. The <info>%command.name%</info> deletes an item from a given cache pool.

View File

@ -24,6 +24,7 @@ use Symfony\Component\Console\Style\SymfonyStyle;
final class CachePoolListCommand extends Command final class CachePoolListCommand extends Command
{ {
protected static $defaultName = 'cache:pool:list'; protected static $defaultName = 'cache:pool:list';
protected static $defaultDescription = 'List available cache pools';
private $poolNames; private $poolNames;
@ -40,7 +41,7 @@ final class CachePoolListCommand extends Command
protected function configure() protected function configure()
{ {
$this $this
->setDescription('List available cache pools') ->setDescription(self::$defaultDescription)
->setHelp(<<<'EOF' ->setHelp(<<<'EOF'
The <info>%command.name%</info> command lists all available cache pools. The <info>%command.name%</info> command lists all available cache pools.
EOF EOF

View File

@ -25,6 +25,7 @@ use Symfony\Component\Console\Style\SymfonyStyle;
final class CachePoolPruneCommand extends Command final class CachePoolPruneCommand extends Command
{ {
protected static $defaultName = 'cache:pool:prune'; protected static $defaultName = 'cache:pool:prune';
protected static $defaultDescription = 'Prunes cache pools';
private $pools; private $pools;
@ -44,7 +45,7 @@ final class CachePoolPruneCommand extends Command
protected function configure() protected function configure()
{ {
$this $this
->setDescription('Prunes cache pools') ->setDescription(self::$defaultDescription)
->setHelp(<<<'EOF' ->setHelp(<<<'EOF'
The <info>%command.name%</info> command deletes all expired items from all pruneable pools. The <info>%command.name%</info> command deletes all expired items from all pruneable pools.

View File

@ -29,6 +29,7 @@ use Symfony\Component\HttpKernel\CacheWarmer\CacheWarmerAggregate;
class CacheWarmupCommand extends Command class CacheWarmupCommand extends Command
{ {
protected static $defaultName = 'cache:warmup'; protected static $defaultName = 'cache:warmup';
protected static $defaultDescription = 'Warms up an empty cache';
private $cacheWarmer; private $cacheWarmer;
@ -48,7 +49,7 @@ class CacheWarmupCommand extends Command
->setDefinition([ ->setDefinition([
new InputOption('no-optional-warmers', '', InputOption::VALUE_NONE, 'Skip optional cache warmers (faster)'), new InputOption('no-optional-warmers', '', InputOption::VALUE_NONE, 'Skip optional cache warmers (faster)'),
]) ])
->setDescription('Warms up an empty cache') ->setDescription(self::$defaultDescription)
->setHelp(<<<'EOF' ->setHelp(<<<'EOF'
The <info>%command.name%</info> command warms up the cache. The <info>%command.name%</info> command warms up the cache.

View File

@ -33,6 +33,7 @@ use Symfony\Component\Yaml\Yaml;
class ConfigDebugCommand extends AbstractConfigCommand class ConfigDebugCommand extends AbstractConfigCommand
{ {
protected static $defaultName = 'debug:config'; protected static $defaultName = 'debug:config';
protected static $defaultDescription = 'Dumps the current configuration for an extension';
/** /**
* {@inheritdoc} * {@inheritdoc}
@ -44,7 +45,7 @@ class ConfigDebugCommand extends AbstractConfigCommand
new InputArgument('name', InputArgument::OPTIONAL, 'The bundle name or the extension alias'), new InputArgument('name', InputArgument::OPTIONAL, 'The bundle name or the extension alias'),
new InputArgument('path', InputArgument::OPTIONAL, 'The configuration option path'), new InputArgument('path', InputArgument::OPTIONAL, 'The configuration option path'),
]) ])
->setDescription('Dumps the current configuration for an extension') ->setDescription(self::$defaultDescription)
->setHelp(<<<'EOF' ->setHelp(<<<'EOF'
The <info>%command.name%</info> command dumps the current configuration for an The <info>%command.name%</info> command dumps the current configuration for an
extension/bundle. extension/bundle.

View File

@ -36,6 +36,7 @@ use Symfony\Component\Yaml\Yaml;
class ConfigDumpReferenceCommand extends AbstractConfigCommand class ConfigDumpReferenceCommand extends AbstractConfigCommand
{ {
protected static $defaultName = 'config:dump-reference'; protected static $defaultName = 'config:dump-reference';
protected static $defaultDescription = 'Dumps the default configuration for an extension';
/** /**
* {@inheritdoc} * {@inheritdoc}
@ -48,7 +49,7 @@ class ConfigDumpReferenceCommand extends AbstractConfigCommand
new InputArgument('path', InputArgument::OPTIONAL, 'The configuration option path'), new InputArgument('path', InputArgument::OPTIONAL, 'The configuration option path'),
new InputOption('format', null, InputOption::VALUE_REQUIRED, 'The output format (yaml or xml)', 'yaml'), new InputOption('format', null, InputOption::VALUE_REQUIRED, 'The output format (yaml or xml)', 'yaml'),
]) ])
->setDescription('Dumps the default configuration for an extension') ->setDescription(self::$defaultDescription)
->setHelp(<<<'EOF' ->setHelp(<<<'EOF'
The <info>%command.name%</info> command dumps the default configuration for an The <info>%command.name%</info> command dumps the default configuration for an
extension/bundle. extension/bundle.

View File

@ -35,6 +35,7 @@ class ContainerDebugCommand extends Command
use BuildDebugContainerTrait; use BuildDebugContainerTrait;
protected static $defaultName = 'debug:container'; protected static $defaultName = 'debug:container';
protected static $defaultDescription = 'Displays current services for an application';
/** /**
* {@inheritdoc} * {@inheritdoc}
@ -57,7 +58,7 @@ class ContainerDebugCommand extends Command
new InputOption('raw', null, InputOption::VALUE_NONE, 'To output raw description'), new InputOption('raw', null, InputOption::VALUE_NONE, 'To output raw description'),
new InputOption('deprecations', null, InputOption::VALUE_NONE, 'Displays deprecations generated when compiling and warming up the container'), new InputOption('deprecations', null, InputOption::VALUE_NONE, 'Displays deprecations generated when compiling and warming up the container'),
]) ])
->setDescription('Displays current services for an application') ->setDescription(self::$defaultDescription)
->setHelp(<<<'EOF' ->setHelp(<<<'EOF'
The <info>%command.name%</info> command displays all configured <comment>public</comment> services: The <info>%command.name%</info> command displays all configured <comment>public</comment> services:

View File

@ -30,6 +30,7 @@ use Symfony\Component\HttpKernel\Kernel;
final class ContainerLintCommand extends Command final class ContainerLintCommand extends Command
{ {
protected static $defaultName = 'lint:container'; protected static $defaultName = 'lint:container';
protected static $defaultDescription = 'Ensures that arguments injected into services match type declarations';
/** /**
* @var ContainerBuilder * @var ContainerBuilder
@ -42,7 +43,7 @@ final class ContainerLintCommand extends Command
protected function configure() protected function configure()
{ {
$this $this
->setDescription('Ensures that arguments injected into services match type declarations') ->setDescription(self::$defaultDescription)
->setHelp('This command parses service definitions and ensures that injected values match the type declarations of each services\' class.') ->setHelp('This command parses service definitions and ensures that injected values match the type declarations of each services\' class.')
; ;
} }

View File

@ -30,6 +30,7 @@ use Symfony\Component\HttpKernel\Debug\FileLinkFormatter;
class DebugAutowiringCommand extends ContainerDebugCommand class DebugAutowiringCommand extends ContainerDebugCommand
{ {
protected static $defaultName = 'debug:autowiring'; protected static $defaultName = 'debug:autowiring';
protected static $defaultDescription = 'Lists classes/interfaces you can use for autowiring';
private $supportsHref; private $supportsHref;
private $fileLinkFormatter; private $fileLinkFormatter;
@ -50,7 +51,7 @@ class DebugAutowiringCommand extends ContainerDebugCommand
new InputArgument('search', InputArgument::OPTIONAL, 'A search filter'), new InputArgument('search', InputArgument::OPTIONAL, 'A search filter'),
new InputOption('all', null, InputOption::VALUE_NONE, 'Show also services that are not aliased'), new InputOption('all', null, InputOption::VALUE_NONE, 'Show also services that are not aliased'),
]) ])
->setDescription('Lists classes/interfaces you can use for autowiring') ->setDescription(self::$defaultDescription)
->setHelp(<<<'EOF' ->setHelp(<<<'EOF'
The <info>%command.name%</info> command displays the classes and interfaces that The <info>%command.name%</info> command displays the classes and interfaces that
you can use as type-hints for autowiring: you can use as type-hints for autowiring:

View File

@ -33,6 +33,7 @@ class EventDispatcherDebugCommand extends Command
private const DEFAULT_DISPATCHER = 'event_dispatcher'; private const DEFAULT_DISPATCHER = 'event_dispatcher';
protected static $defaultName = 'debug:event-dispatcher'; protected static $defaultName = 'debug:event-dispatcher';
protected static $defaultDescription = 'Displays configured listeners for an application';
private $dispatchers; private $dispatchers;
public function __construct(ContainerInterface $dispatchers) public function __construct(ContainerInterface $dispatchers)
@ -54,7 +55,7 @@ class EventDispatcherDebugCommand extends Command
new InputOption('format', null, InputOption::VALUE_REQUIRED, 'The output format (txt, xml, json, or md)', 'txt'), new InputOption('format', null, InputOption::VALUE_REQUIRED, 'The output format (txt, xml, json, or md)', 'txt'),
new InputOption('raw', null, InputOption::VALUE_NONE, 'To output raw description'), new InputOption('raw', null, InputOption::VALUE_NONE, 'To output raw description'),
]) ])
->setDescription('Displays configured listeners for an application') ->setDescription(self::$defaultDescription)
->setHelp(<<<'EOF' ->setHelp(<<<'EOF'
The <info>%command.name%</info> command displays all configured listeners: The <info>%command.name%</info> command displays all configured listeners:

View File

@ -36,6 +36,7 @@ class RouterDebugCommand extends Command
use BuildDebugContainerTrait; use BuildDebugContainerTrait;
protected static $defaultName = 'debug:router'; protected static $defaultName = 'debug:router';
protected static $defaultDescription = 'Displays current routes for an application';
private $router; private $router;
private $fileLinkFormatter; private $fileLinkFormatter;
@ -59,7 +60,7 @@ class RouterDebugCommand extends Command
new InputOption('format', null, InputOption::VALUE_REQUIRED, 'The output format (txt, xml, json, or md)', 'txt'), new InputOption('format', null, InputOption::VALUE_REQUIRED, 'The output format (txt, xml, json, or md)', 'txt'),
new InputOption('raw', null, InputOption::VALUE_NONE, 'To output raw route(s)'), new InputOption('raw', null, InputOption::VALUE_NONE, 'To output raw route(s)'),
]) ])
->setDescription('Displays current routes for an application') ->setDescription(self::$defaultDescription)
->setHelp(<<<'EOF' ->setHelp(<<<'EOF'
The <info>%command.name%</info> displays the configured routes: The <info>%command.name%</info> displays the configured routes:

View File

@ -31,6 +31,7 @@ use Symfony\Component\Routing\RouterInterface;
class RouterMatchCommand extends Command class RouterMatchCommand extends Command
{ {
protected static $defaultName = 'router:match'; protected static $defaultName = 'router:match';
protected static $defaultDescription = 'Helps debug routes by simulating a path info match';
private $router; private $router;
private $expressionLanguageProviders; private $expressionLanguageProviders;
@ -55,7 +56,7 @@ class RouterMatchCommand extends Command
new InputOption('scheme', null, InputOption::VALUE_REQUIRED, 'Sets the URI scheme (usually http or https)'), new InputOption('scheme', null, InputOption::VALUE_REQUIRED, 'Sets the URI scheme (usually http or https)'),
new InputOption('host', null, InputOption::VALUE_REQUIRED, 'Sets the URI host'), new InputOption('host', null, InputOption::VALUE_REQUIRED, 'Sets the URI host'),
]) ])
->setDescription('Helps debug routes by simulating a path info match') ->setDescription(self::$defaultDescription)
->setHelp(<<<'EOF' ->setHelp(<<<'EOF'
The <info>%command.name%</info> shows which routes match a given request and which don't and for what reason: The <info>%command.name%</info> shows which routes match a given request and which don't and for what reason:

View File

@ -27,6 +27,7 @@ use Symfony\Component\Console\Style\SymfonyStyle;
final class SecretsDecryptToLocalCommand extends Command final class SecretsDecryptToLocalCommand extends Command
{ {
protected static $defaultName = 'secrets:decrypt-to-local'; protected static $defaultName = 'secrets:decrypt-to-local';
protected static $defaultDescription = 'Decrypts all secrets and stores them in the local vault';
private $vault; private $vault;
private $localVault; private $localVault;
@ -42,7 +43,7 @@ final class SecretsDecryptToLocalCommand extends Command
protected function configure() protected function configure()
{ {
$this $this
->setDescription('Decrypts all secrets and stores them in the local vault') ->setDescription(self::$defaultDescription)
->addOption('force', 'f', InputOption::VALUE_NONE, 'Forces overriding of secrets that already exist in the local vault') ->addOption('force', 'f', InputOption::VALUE_NONE, 'Forces overriding of secrets that already exist in the local vault')
->setHelp(<<<'EOF' ->setHelp(<<<'EOF'
The <info>%command.name%</info> command decrypts all secrets and copies them in the local vault. The <info>%command.name%</info> command decrypts all secrets and copies them in the local vault.

View File

@ -26,6 +26,7 @@ use Symfony\Component\Console\Style\SymfonyStyle;
final class SecretsEncryptFromLocalCommand extends Command final class SecretsEncryptFromLocalCommand extends Command
{ {
protected static $defaultName = 'secrets:encrypt-from-local'; protected static $defaultName = 'secrets:encrypt-from-local';
protected static $defaultDescription = 'Encrypts all local secrets to the vault';
private $vault; private $vault;
private $localVault; private $localVault;
@ -41,7 +42,7 @@ final class SecretsEncryptFromLocalCommand extends Command
protected function configure() protected function configure()
{ {
$this $this
->setDescription('Encrypts all local secrets to the vault') ->setDescription(self::$defaultDescription)
->setHelp(<<<'EOF' ->setHelp(<<<'EOF'
The <info>%command.name%</info> command encrypts all locally overridden secrets to the vault. The <info>%command.name%</info> command encrypts all locally overridden secrets to the vault.

View File

@ -29,6 +29,7 @@ use Symfony\Component\Console\Style\SymfonyStyle;
final class SecretsGenerateKeysCommand extends Command final class SecretsGenerateKeysCommand extends Command
{ {
protected static $defaultName = 'secrets:generate-keys'; protected static $defaultName = 'secrets:generate-keys';
protected static $defaultDescription = 'Generates new encryption keys';
private $vault; private $vault;
private $localVault; private $localVault;
@ -44,7 +45,7 @@ final class SecretsGenerateKeysCommand extends Command
protected function configure() protected function configure()
{ {
$this $this
->setDescription('Generates new encryption keys') ->setDescription(self::$defaultDescription)
->addOption('local', 'l', InputOption::VALUE_NONE, 'Updates the local vault.') ->addOption('local', 'l', InputOption::VALUE_NONE, 'Updates the local vault.')
->addOption('rotate', 'r', InputOption::VALUE_NONE, 'Re-encrypts existing secrets with the newly generated keys.') ->addOption('rotate', 'r', InputOption::VALUE_NONE, 'Re-encrypts existing secrets with the newly generated keys.')
->setHelp(<<<'EOF' ->setHelp(<<<'EOF'

View File

@ -30,6 +30,7 @@ use Symfony\Component\Console\Style\SymfonyStyle;
final class SecretsListCommand extends Command final class SecretsListCommand extends Command
{ {
protected static $defaultName = 'secrets:list'; protected static $defaultName = 'secrets:list';
protected static $defaultDescription = 'Lists all secrets';
private $vault; private $vault;
private $localVault; private $localVault;
@ -45,7 +46,7 @@ final class SecretsListCommand extends Command
protected function configure() protected function configure()
{ {
$this $this
->setDescription('Lists all secrets') ->setDescription(self::$defaultDescription)
->addOption('reveal', 'r', InputOption::VALUE_NONE, 'Display decrypted values alongside names') ->addOption('reveal', 'r', InputOption::VALUE_NONE, 'Display decrypted values alongside names')
->setHelp(<<<'EOF' ->setHelp(<<<'EOF'
The <info>%command.name%</info> command list all stored secrets. The <info>%command.name%</info> command list all stored secrets.

View File

@ -29,6 +29,7 @@ use Symfony\Component\Console\Style\SymfonyStyle;
final class SecretsRemoveCommand extends Command final class SecretsRemoveCommand extends Command
{ {
protected static $defaultName = 'secrets:remove'; protected static $defaultName = 'secrets:remove';
protected static $defaultDescription = 'Removes a secret from the vault';
private $vault; private $vault;
private $localVault; private $localVault;
@ -44,7 +45,7 @@ final class SecretsRemoveCommand extends Command
protected function configure() protected function configure()
{ {
$this $this
->setDescription('Removes a secret from the vault') ->setDescription(self::$defaultDescription)
->addArgument('name', InputArgument::REQUIRED, 'The name of the secret') ->addArgument('name', InputArgument::REQUIRED, 'The name of the secret')
->addOption('local', 'l', InputOption::VALUE_NONE, 'Updates the local vault.') ->addOption('local', 'l', InputOption::VALUE_NONE, 'Updates the local vault.')
->setHelp(<<<'EOF' ->setHelp(<<<'EOF'

View File

@ -30,6 +30,7 @@ use Symfony\Component\Console\Style\SymfonyStyle;
final class SecretsSetCommand extends Command final class SecretsSetCommand extends Command
{ {
protected static $defaultName = 'secrets:set'; protected static $defaultName = 'secrets:set';
protected static $defaultDescription = 'Sets a secret in the vault';
private $vault; private $vault;
private $localVault; private $localVault;
@ -45,7 +46,7 @@ final class SecretsSetCommand extends Command
protected function configure() protected function configure()
{ {
$this $this
->setDescription('Sets a secret in the vault') ->setDescription(self::$defaultDescription)
->addArgument('name', InputArgument::REQUIRED, 'The name of the secret') ->addArgument('name', InputArgument::REQUIRED, 'The name of the secret')
->addArgument('file', InputArgument::OPTIONAL, 'A file where to read the secret from or "-" for reading from STDIN') ->addArgument('file', InputArgument::OPTIONAL, 'A file where to read the secret from or "-" for reading from STDIN')
->addOption('local', 'l', InputOption::VALUE_NONE, 'Updates the local vault.') ->addOption('local', 'l', InputOption::VALUE_NONE, 'Updates the local vault.')

View File

@ -47,6 +47,7 @@ class TranslationDebugCommand extends Command
public const MESSAGE_EQUALS_FALLBACK = 2; public const MESSAGE_EQUALS_FALLBACK = 2;
protected static $defaultName = 'debug:translation'; protected static $defaultName = 'debug:translation';
protected static $defaultDescription = 'Displays translation messages information';
private $translator; private $translator;
private $reader; private $reader;
@ -83,7 +84,7 @@ class TranslationDebugCommand extends Command
new InputOption('only-unused', null, InputOption::VALUE_NONE, 'Displays only unused messages'), new InputOption('only-unused', null, InputOption::VALUE_NONE, 'Displays only unused messages'),
new InputOption('all', null, InputOption::VALUE_NONE, 'Load messages from all registered bundles'), new InputOption('all', null, InputOption::VALUE_NONE, 'Load messages from all registered bundles'),
]) ])
->setDescription('Displays translation messages information') ->setDescription(self::$defaultDescription)
->setHelp(<<<'EOF' ->setHelp(<<<'EOF'
The <info>%command.name%</info> command helps finding unused or missing translation The <info>%command.name%</info> command helps finding unused or missing translation
messages and comparing them with the fallback ones by inspecting the messages and comparing them with the fallback ones by inspecting the

View File

@ -42,6 +42,7 @@ class TranslationUpdateCommand extends Command
private const SORT_ORDERS = [self::ASC, self::DESC]; private const SORT_ORDERS = [self::ASC, self::DESC];
protected static $defaultName = 'translation:update'; protected static $defaultName = 'translation:update';
protected static $defaultDescription = 'Updates the translation file';
private $writer; private $writer;
private $reader; private $reader;
@ -85,7 +86,7 @@ class TranslationUpdateCommand extends Command
new InputOption('sort', null, InputOption::VALUE_OPTIONAL, 'Return list of messages sorted alphabetically', 'asc'), new InputOption('sort', null, InputOption::VALUE_OPTIONAL, 'Return list of messages sorted alphabetically', 'asc'),
new InputOption('as-tree', null, InputOption::VALUE_OPTIONAL, 'Dump the messages as a tree-like structure: The given value defines the level where to switch to inline YAML'), new InputOption('as-tree', null, InputOption::VALUE_OPTIONAL, 'Dump the messages as a tree-like structure: The given value defines the level where to switch to inline YAML'),
]) ])
->setDescription('Updates the translation file') ->setDescription(self::$defaultDescription)
->setHelp(<<<'EOF' ->setHelp(<<<'EOF'
The <info>%command.name%</info> command extracts translation strings from templates The <info>%command.name%</info> command extracts translation strings from templates
of a given bundle or the default translations directory. It can display them or merge of a given bundle or the default translations directory. It can display them or merge

View File

@ -30,6 +30,7 @@ use Symfony\Component\Workflow\Marking;
class WorkflowDumpCommand extends Command class WorkflowDumpCommand extends Command
{ {
protected static $defaultName = 'workflow:dump'; protected static $defaultName = 'workflow:dump';
protected static $defaultDescription = 'Dump a workflow';
/** /**
* {@inheritdoc} * {@inheritdoc}
@ -43,7 +44,7 @@ class WorkflowDumpCommand extends Command
new InputOption('label', 'l', InputOption::VALUE_REQUIRED, 'Labels a graph'), new InputOption('label', 'l', InputOption::VALUE_REQUIRED, 'Labels a graph'),
new InputOption('dump-format', null, InputOption::VALUE_REQUIRED, 'The dump format [dot|puml]', 'dot'), new InputOption('dump-format', null, InputOption::VALUE_REQUIRED, 'The dump format [dot|puml]', 'dot'),
]) ])
->setDescription('Dump a workflow') ->setDescription(self::$defaultDescription)
->setHelp(<<<'EOF' ->setHelp(<<<'EOF'
The <info>%command.name%</info> command dumps the graphical representation of a The <info>%command.name%</info> command dumps the graphical representation of a
workflow in different formats workflow in different formats

View File

@ -62,76 +62,76 @@ return static function (ContainerConfigurator $container) {
->tag('kernel.event_subscriber') ->tag('kernel.event_subscriber')
->set('console.command.about', AboutCommand::class) ->set('console.command.about', AboutCommand::class)
->tag('console.command', ['command' => 'about']) ->tag('console.command')
->set('console.command.assets_install', AssetsInstallCommand::class) ->set('console.command.assets_install', AssetsInstallCommand::class)
->args([ ->args([
service('filesystem'), service('filesystem'),
param('kernel.project_dir'), param('kernel.project_dir'),
]) ])
->tag('console.command', ['command' => 'assets:install']) ->tag('console.command')
->set('console.command.cache_clear', CacheClearCommand::class) ->set('console.command.cache_clear', CacheClearCommand::class)
->args([ ->args([
service('cache_clearer'), service('cache_clearer'),
service('filesystem'), service('filesystem'),
]) ])
->tag('console.command', ['command' => 'cache:clear']) ->tag('console.command')
->set('console.command.cache_pool_clear', CachePoolClearCommand::class) ->set('console.command.cache_pool_clear', CachePoolClearCommand::class)
->args([ ->args([
service('cache.global_clearer'), service('cache.global_clearer'),
]) ])
->tag('console.command', ['command' => 'cache:pool:clear']) ->tag('console.command')
->set('console.command.cache_pool_prune', CachePoolPruneCommand::class) ->set('console.command.cache_pool_prune', CachePoolPruneCommand::class)
->args([ ->args([
[], [],
]) ])
->tag('console.command', ['command' => 'cache:pool:prune']) ->tag('console.command')
->set('console.command.cache_pool_delete', CachePoolDeleteCommand::class) ->set('console.command.cache_pool_delete', CachePoolDeleteCommand::class)
->args([ ->args([
service('cache.global_clearer'), service('cache.global_clearer'),
]) ])
->tag('console.command', ['command' => 'cache:pool:delete']) ->tag('console.command')
->set('console.command.cache_pool_list', CachePoolListCommand::class) ->set('console.command.cache_pool_list', CachePoolListCommand::class)
->args([ ->args([
null, null,
]) ])
->tag('console.command', ['command' => 'cache:pool:list']) ->tag('console.command')
->set('console.command.cache_warmup', CacheWarmupCommand::class) ->set('console.command.cache_warmup', CacheWarmupCommand::class)
->args([ ->args([
service('cache_warmer'), service('cache_warmer'),
]) ])
->tag('console.command', ['command' => 'cache:warmup']) ->tag('console.command')
->set('console.command.config_debug', ConfigDebugCommand::class) ->set('console.command.config_debug', ConfigDebugCommand::class)
->tag('console.command', ['command' => 'debug:config']) ->tag('console.command')
->set('console.command.config_dump_reference', ConfigDumpReferenceCommand::class) ->set('console.command.config_dump_reference', ConfigDumpReferenceCommand::class)
->tag('console.command', ['command' => 'config:dump-reference']) ->tag('console.command')
->set('console.command.container_debug', ContainerDebugCommand::class) ->set('console.command.container_debug', ContainerDebugCommand::class)
->tag('console.command', ['command' => 'debug:container']) ->tag('console.command')
->set('console.command.container_lint', ContainerLintCommand::class) ->set('console.command.container_lint', ContainerLintCommand::class)
->tag('console.command', ['command' => 'lint:container']) ->tag('console.command')
->set('console.command.debug_autowiring', DebugAutowiringCommand::class) ->set('console.command.debug_autowiring', DebugAutowiringCommand::class)
->args([ ->args([
null, null,
service('debug.file_link_formatter')->nullOnInvalid(), service('debug.file_link_formatter')->nullOnInvalid(),
]) ])
->tag('console.command', ['command' => 'debug:autowiring']) ->tag('console.command')
->set('console.command.event_dispatcher_debug', EventDispatcherDebugCommand::class) ->set('console.command.event_dispatcher_debug', EventDispatcherDebugCommand::class)
->args([ ->args([
tagged_locator('event_dispatcher.dispatcher'), tagged_locator('event_dispatcher.dispatcher'),
]) ])
->tag('console.command', ['command' => 'debug:event-dispatcher']) ->tag('console.command')
->set('console.command.messenger_consume_messages', ConsumeMessagesCommand::class) ->set('console.command.messenger_consume_messages', ConsumeMessagesCommand::class)
->args([ ->args([
@ -141,7 +141,7 @@ return static function (ContainerConfigurator $container) {
service('logger')->nullOnInvalid(), service('logger')->nullOnInvalid(),
[], // Receiver names [], // Receiver names
]) ])
->tag('console.command', ['command' => 'messenger:consume']) ->tag('console.command')
->tag('monolog.logger', ['channel' => 'messenger']) ->tag('monolog.logger', ['channel' => 'messenger'])
->set('console.command.messenger_setup_transports', SetupTransportsCommand::class) ->set('console.command.messenger_setup_transports', SetupTransportsCommand::class)
@ -149,19 +149,19 @@ return static function (ContainerConfigurator $container) {
service('messenger.receiver_locator'), service('messenger.receiver_locator'),
[], // Receiver names [], // Receiver names
]) ])
->tag('console.command', ['command' => 'messenger:setup-transports']) ->tag('console.command')
->set('console.command.messenger_debug', DebugCommand::class) ->set('console.command.messenger_debug', DebugCommand::class)
->args([ ->args([
[], // Message to handlers mapping [], // Message to handlers mapping
]) ])
->tag('console.command', ['command' => 'debug:messenger']) ->tag('console.command')
->set('console.command.messenger_stop_workers', StopWorkersCommand::class) ->set('console.command.messenger_stop_workers', StopWorkersCommand::class)
->args([ ->args([
service('cache.messenger.restart_workers_signal'), service('cache.messenger.restart_workers_signal'),
]) ])
->tag('console.command', ['command' => 'messenger:stop-workers']) ->tag('console.command')
->set('console.command.messenger_failed_messages_retry', FailedMessagesRetryCommand::class) ->set('console.command.messenger_failed_messages_retry', FailedMessagesRetryCommand::class)
->args([ ->args([
@ -171,35 +171,35 @@ return static function (ContainerConfigurator $container) {
service('event_dispatcher'), service('event_dispatcher'),
service('logger'), service('logger'),
]) ])
->tag('console.command', ['command' => 'messenger:failed:retry']) ->tag('console.command')
->set('console.command.messenger_failed_messages_show', FailedMessagesShowCommand::class) ->set('console.command.messenger_failed_messages_show', FailedMessagesShowCommand::class)
->args([ ->args([
abstract_arg('Receiver name'), abstract_arg('Receiver name'),
abstract_arg('Receiver'), abstract_arg('Receiver'),
]) ])
->tag('console.command', ['command' => 'messenger:failed:show']) ->tag('console.command')
->set('console.command.messenger_failed_messages_remove', FailedMessagesRemoveCommand::class) ->set('console.command.messenger_failed_messages_remove', FailedMessagesRemoveCommand::class)
->args([ ->args([
abstract_arg('Receiver name'), abstract_arg('Receiver name'),
abstract_arg('Receiver'), abstract_arg('Receiver'),
]) ])
->tag('console.command', ['command' => 'messenger:failed:remove']) ->tag('console.command')
->set('console.command.router_debug', RouterDebugCommand::class) ->set('console.command.router_debug', RouterDebugCommand::class)
->args([ ->args([
service('router'), service('router'),
service('debug.file_link_formatter')->nullOnInvalid(), service('debug.file_link_formatter')->nullOnInvalid(),
]) ])
->tag('console.command', ['command' => 'debug:router']) ->tag('console.command')
->set('console.command.router_match', RouterMatchCommand::class) ->set('console.command.router_match', RouterMatchCommand::class)
->args([ ->args([
service('router'), service('router'),
tagged_iterator('routing.expression_language_provider'), tagged_iterator('routing.expression_language_provider'),
]) ])
->tag('console.command', ['command' => 'router:match']) ->tag('console.command')
->set('console.command.translation_debug', TranslationDebugCommand::class) ->set('console.command.translation_debug', TranslationDebugCommand::class)
->args([ ->args([
@ -211,7 +211,7 @@ return static function (ContainerConfigurator $container) {
[], // Translator paths [], // Translator paths
[], // Twig paths [], // Twig paths
]) ])
->tag('console.command', ['command' => 'debug:translation']) ->tag('console.command')
->set('console.command.translation_update', TranslationUpdateCommand::class) ->set('console.command.translation_update', TranslationUpdateCommand::class)
->args([ ->args([
@ -224,22 +224,22 @@ return static function (ContainerConfigurator $container) {
[], // Translator paths [], // Translator paths
[], // Twig paths [], // Twig paths
]) ])
->tag('console.command', ['command' => 'translation:update']) ->tag('console.command')
->set('console.command.validator_debug', ValidatorDebugCommand::class) ->set('console.command.validator_debug', ValidatorDebugCommand::class)
->args([ ->args([
service('validator'), service('validator'),
]) ])
->tag('console.command', ['command' => 'debug:validator']) ->tag('console.command')
->set('console.command.workflow_dump', WorkflowDumpCommand::class) ->set('console.command.workflow_dump', WorkflowDumpCommand::class)
->tag('console.command', ['command' => 'workflow:dump']) ->tag('console.command')
->set('console.command.xliff_lint', XliffLintCommand::class) ->set('console.command.xliff_lint', XliffLintCommand::class)
->tag('console.command', ['command' => 'lint:xliff']) ->tag('console.command')
->set('console.command.yaml_lint', YamlLintCommand::class) ->set('console.command.yaml_lint', YamlLintCommand::class)
->tag('console.command', ['command' => 'lint:yaml']) ->tag('console.command')
->set('console.command.form_debug', \Symfony\Component\Form\Command\DebugCommand::class) ->set('console.command.form_debug', \Symfony\Component\Form\Command\DebugCommand::class)
->args([ ->args([
@ -250,48 +250,48 @@ return static function (ContainerConfigurator $container) {
[], // All type guessers are stored here by FormPass [], // All type guessers are stored here by FormPass
service('debug.file_link_formatter')->nullOnInvalid(), service('debug.file_link_formatter')->nullOnInvalid(),
]) ])
->tag('console.command', ['command' => 'debug:form']) ->tag('console.command')
->set('console.command.secrets_set', SecretsSetCommand::class) ->set('console.command.secrets_set', SecretsSetCommand::class)
->args([ ->args([
service('secrets.vault'), service('secrets.vault'),
service('secrets.local_vault')->nullOnInvalid(), service('secrets.local_vault')->nullOnInvalid(),
]) ])
->tag('console.command', ['command' => 'secrets:set']) ->tag('console.command')
->set('console.command.secrets_remove', SecretsRemoveCommand::class) ->set('console.command.secrets_remove', SecretsRemoveCommand::class)
->args([ ->args([
service('secrets.vault'), service('secrets.vault'),
service('secrets.local_vault')->nullOnInvalid(), service('secrets.local_vault')->nullOnInvalid(),
]) ])
->tag('console.command', ['command' => 'secrets:remove']) ->tag('console.command')
->set('console.command.secrets_generate_key', SecretsGenerateKeysCommand::class) ->set('console.command.secrets_generate_key', SecretsGenerateKeysCommand::class)
->args([ ->args([
service('secrets.vault'), service('secrets.vault'),
service('secrets.local_vault')->ignoreOnInvalid(), service('secrets.local_vault')->ignoreOnInvalid(),
]) ])
->tag('console.command', ['command' => 'secrets:generate-keys']) ->tag('console.command')
->set('console.command.secrets_list', SecretsListCommand::class) ->set('console.command.secrets_list', SecretsListCommand::class)
->args([ ->args([
service('secrets.vault'), service('secrets.vault'),
service('secrets.local_vault'), service('secrets.local_vault'),
]) ])
->tag('console.command', ['command' => 'secrets:list']) ->tag('console.command')
->set('console.command.secrets_decrypt_to_local', SecretsDecryptToLocalCommand::class) ->set('console.command.secrets_decrypt_to_local', SecretsDecryptToLocalCommand::class)
->args([ ->args([
service('secrets.vault'), service('secrets.vault'),
service('secrets.local_vault')->ignoreOnInvalid(), service('secrets.local_vault')->ignoreOnInvalid(),
]) ])
->tag('console.command', ['command' => 'secrets:decrypt-to-local']) ->tag('console.command')
->set('console.command.secrets_encrypt_from_local', SecretsEncryptFromLocalCommand::class) ->set('console.command.secrets_encrypt_from_local', SecretsEncryptFromLocalCommand::class)
->args([ ->args([
service('secrets.vault'), service('secrets.vault'),
service('secrets.local_vault'), service('secrets.local_vault'),
]) ])
->tag('console.command', ['command' => 'secrets:encrypt-from-local']) ->tag('console.command')
; ;
}; };

View File

@ -34,6 +34,7 @@ use Symfony\Component\Security\Core\Encoder\SelfSaltingEncoderInterface;
class UserPasswordEncoderCommand extends Command class UserPasswordEncoderCommand extends Command
{ {
protected static $defaultName = 'security:encode-password'; protected static $defaultName = 'security:encode-password';
protected static $defaultDescription = 'Encodes a password';
private $encoderFactory; private $encoderFactory;
private $userClasses; private $userClasses;
@ -52,7 +53,7 @@ class UserPasswordEncoderCommand extends Command
protected function configure() protected function configure()
{ {
$this $this
->setDescription('Encodes a password') ->setDescription(self::$defaultDescription)
->addArgument('password', InputArgument::OPTIONAL, 'The plain password to encode.') ->addArgument('password', InputArgument::OPTIONAL, 'The plain password to encode.')
->addArgument('user-class', InputArgument::OPTIONAL, 'The User entity class path associated with the encoder used to encode the password.') ->addArgument('user-class', InputArgument::OPTIONAL, 'The User entity class path associated with the encoder used to encode the password.')
->addOption('empty-salt', null, InputOption::VALUE_NONE, 'Do not generate a salt or let the encoder generate one.') ->addOption('empty-salt', null, InputOption::VALUE_NONE, 'Do not generate a salt or let the encoder generate one.')

View File

@ -20,6 +20,6 @@ return static function (ContainerConfigurator $container) {
service('security.encoder_factory'), service('security.encoder_factory'),
abstract_arg('encoders user classes'), abstract_arg('encoders user classes'),
]) ])
->tag('console.command', ['command' => 'security:encode-password']) ->tag('console.command')
; ;
}; };

View File

@ -24,10 +24,10 @@ return static function (ContainerConfigurator $container) {
param('twig.default_path'), param('twig.default_path'),
service('debug.file_link_formatter')->nullOnInvalid(), service('debug.file_link_formatter')->nullOnInvalid(),
]) ])
->tag('console.command', ['command' => 'debug:twig']) ->tag('console.command')
->set('twig.command.lint', LintCommand::class) ->set('twig.command.lint', LintCommand::class)
->args([service('twig')]) ->args([service('twig')])
->tag('console.command', ['command' => 'lint:twig']) ->tag('console.command')
; ;
}; };

View File

@ -13,6 +13,7 @@ namespace Symfony\Component\Console;
use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Command\HelpCommand; use Symfony\Component\Console\Command\HelpCommand;
use Symfony\Component\Console\Command\LazyCommand;
use Symfony\Component\Console\Command\ListCommand; use Symfony\Component\Console\Command\ListCommand;
use Symfony\Component\Console\Command\SignalableCommandInterface; use Symfony\Component\Console\Command\SignalableCommandInterface;
use Symfony\Component\Console\CommandLoader\CommandLoaderInterface; use Symfony\Component\Console\CommandLoader\CommandLoaderInterface;
@ -489,8 +490,10 @@ class Application implements ResetInterface
return null; return null;
} }
if (!$command instanceof LazyCommand) {
// Will throw if the command is not correctly initialized. // Will throw if the command is not correctly initialized.
$command->getDefinition(); $command->getDefinition();
}
if (!$command->getName()) { if (!$command->getName()) {
throw new LogicException(sprintf('The command defined in "%s" cannot have an empty name.', get_debug_type($command))); throw new LogicException(sprintf('The command defined in "%s" cannot have an empty name.', get_debug_type($command)));

View File

@ -4,8 +4,10 @@ CHANGELOG
5.3 5.3
--- ---
* Added `GithubActionReporter` to render annotations in a Github Action * Add `GithubActionReporter` to render annotations in a Github Action
* Added `InputOption::VALUE_NEGATABLE` flag to handle `--foo`/`--no-foo` options. * Add `InputOption::VALUE_NEGATABLE` flag to handle `--foo`/`--no-foo` options
* Add the `Command::$defaultDescription` static property and the `description` attribute
on the `console.command` tag to allow the `list` command to instantiate commands lazily
5.2.0 5.2.0
----- -----

View File

@ -39,6 +39,11 @@ class Command
*/ */
protected static $defaultName; protected static $defaultName;
/**
* @var string|null The default command description
*/
protected static $defaultDescription;
private $application; private $application;
private $name; private $name;
private $processTitle; private $processTitle;
@ -65,6 +70,17 @@ class Command
return $class === $r->class ? static::$defaultName : null; return $class === $r->class ? static::$defaultName : null;
} }
/**
* @return string|null The default command description or null when no default description is set
*/
public static function getDefaultDescription(): ?string
{
$class = static::class;
$r = new \ReflectionProperty($class, 'defaultDescription');
return $class === $r->class ? static::$defaultDescription : null;
}
/** /**
* @param string|null $name The name of the command; passing null means it must be set in configure() * @param string|null $name The name of the command; passing null means it must be set in configure()
* *
@ -78,6 +94,10 @@ class Command
$this->setName($name); $this->setName($name);
} }
if ('' === $this->description) {
$this->setDescription(static::getDefaultDescription() ?? '');
}
$this->configure(); $this->configure();
} }
@ -298,6 +318,8 @@ class Command
* This method is not part of public API and should not be used directly. * This method is not part of public API and should not be used directly.
* *
* @param bool $mergeArgs Whether to merge or not the Application definition arguments to Command definition arguments * @param bool $mergeArgs Whether to merge or not the Application definition arguments to Command definition arguments
*
* @internal
*/ */
public function mergeApplicationDefinition(bool $mergeArgs = true) public function mergeApplicationDefinition(bool $mergeArgs = true)
{ {
@ -554,11 +576,14 @@ class Command
*/ */
public function setAliases(iterable $aliases) public function setAliases(iterable $aliases)
{ {
$list = [];
foreach ($aliases as $alias) { foreach ($aliases as $alias) {
$this->validateName($alias); $this->validateName($alias);
$list[] = $alias;
} }
$this->aliases = $aliases; $this->aliases = \is_array($aliases) ? $aliases : $list;
return $this; return $this;
} }

View File

@ -0,0 +1,211 @@
<?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\Application;
use Symfony\Component\Console\Helper\HelperSet;
use Symfony\Component\Console\Input\InputDefinition;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
/**
* @author Nicolas Grekas <p@tchwork.com>
*/
final class LazyCommand extends Command
{
private $command;
private $isEnabled;
public function __construct(string $name, array $aliases, string $description, bool $isHidden, \Closure $commandFactory, ?bool $isEnabled = true)
{
$this->setName($name)
->setAliases($aliases)
->setHidden($isHidden)
->setDescription($description);
$this->command = $commandFactory;
$this->isEnabled = $isEnabled;
}
public function ignoreValidationErrors(): void
{
$this->getCommand()->ignoreValidationErrors();
}
public function setApplication(Application $application = null): void
{
if ($this->command instanceof parent) {
$this->command->setApplication($application);
}
parent::setApplication($application);
}
public function setHelperSet(HelperSet $helperSet): void
{
if ($this->command instanceof parent) {
$this->command->setHelperSet($helperSet);
}
parent::setHelperSet($helperSet);
}
public function isEnabled(): bool
{
return $this->isEnabled ?? $this->getCommand()->isEnabled();
}
public function run(InputInterface $input, OutputInterface $output): int
{
return $this->getCommand()->run($input, $output);
}
/**
* @return $this
*/
public function setCode(callable $code): self
{
$this->getCommand()->setCode($code);
return $this;
}
/**
* @internal
*/
public function mergeApplicationDefinition(bool $mergeArgs = true): void
{
$this->getCommand()->mergeApplicationDefinition($mergeArgs);
}
/**
* @return $this
*/
public function setDefinition($definition): self
{
$this->getCommand()->setDefinition($definition);
return $this;
}
public function getDefinition(): InputDefinition
{
return $this->getCommand()->getDefinition();
}
public function getNativeDefinition(): InputDefinition
{
return $this->getCommand()->getNativeDefinition();
}
/**
* @return $this
*/
public function addArgument(string $name, int $mode = null, string $description = '', $default = null): self
{
$this->getCommand()->addArgument($name, $mode, $description, $default);
return $this;
}
/**
* @return $this
*/
public function addOption(string $name, $shortcut = null, int $mode = null, string $description = '', $default = null): self
{
$this->getCommand()->addOption($name, $shortcut, $mode, $description, $default);
return $this;
}
/**
* @return $this
*/
public function setProcessTitle(string $title): self
{
$this->getCommand()->setProcessTitle($title);
return $this;
}
/**
* @return $this
*/
public function setHelp(string $help): self
{
$this->getCommand()->setHelp($help);
return $this;
}
public function getHelp(): string
{
return $this->getCommand()->getHelp();
}
public function getProcessedHelp(): string
{
return $this->getCommand()->getProcessedHelp();
}
public function getSynopsis(bool $short = false): string
{
return $this->getCommand()->getSynopsis($short);
}
/**
* @return $this
*/
public function addUsage(string $usage): self
{
$this->getCommand()->addUsage($usage);
return $this;
}
public function getUsages(): array
{
return $this->getCommand()->getUsages();
}
/**
* @return mixed
*/
public function getHelper(string $name)
{
return $this->getCommand()->getHelper($name);
}
public function getCommand(): parent
{
if (!$this->command instanceof \Closure) {
return $this->command;
}
$command = $this->command = ($this->command)();
$command->setApplication($this->getApplication());
if (null !== $this->getHelperSet()) {
$command->setHelperSet($this->getHelperSet());
}
$command->setName($this->getName())
->setAliases($this->getAliases())
->setHidden($this->isHidden())
->setDescription($this->getDescription());
// Will throw if the command is not correctly initialized.
$command->getDefinition();
return $command;
}
}

View File

@ -12,11 +12,14 @@
namespace Symfony\Component\Console\DependencyInjection; namespace Symfony\Component\Console\DependencyInjection;
use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Command\LazyCommand;
use Symfony\Component\Console\CommandLoader\ContainerCommandLoader; use Symfony\Component\Console\CommandLoader\ContainerCommandLoader;
use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\Compiler\ServiceLocatorTagPass; use Symfony\Component\DependencyInjection\Compiler\ServiceLocatorTagPass;
use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\TypedReference; use Symfony\Component\DependencyInjection\TypedReference;
/** /**
@ -52,7 +55,7 @@ class AddConsoleCommandPass implements CompilerPassInterface
$class = $container->getParameterBag()->resolveValue($definition->getClass()); $class = $container->getParameterBag()->resolveValue($definition->getClass());
if (isset($tags[0]['command'])) { if (isset($tags[0]['command'])) {
$commandName = $tags[0]['command']; $aliases = $tags[0]['command'];
} else { } else {
if (!$r = $container->getReflectionClass($class)) { if (!$r = $container->getReflectionClass($class)) {
throw new InvalidArgumentException(sprintf('Class "%s" used for service "%s" cannot be found.', $class, $id)); throw new InvalidArgumentException(sprintf('Class "%s" used for service "%s" cannot be found.', $class, $id));
@ -60,7 +63,14 @@ class AddConsoleCommandPass implements CompilerPassInterface
if (!$r->isSubclassOf(Command::class)) { 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)); throw new InvalidArgumentException(sprintf('The service "%s" tagged "%s" must be a subclass of "%s".', $id, $this->commandTag, Command::class));
} }
$commandName = $class::getDefaultName(); $aliases = $class::getDefaultName();
}
$aliases = explode('|', $aliases ?? '');
$commandName = array_shift($aliases);
if ($isHidden = '' === $commandName) {
$commandName = array_shift($aliases);
} }
if (null === $commandName) { if (null === $commandName) {
@ -74,16 +84,19 @@ class AddConsoleCommandPass implements CompilerPassInterface
continue; continue;
} }
$description = $tags[0]['description'] ?? null;
unset($tags[0]); unset($tags[0]);
$lazyCommandMap[$commandName] = $id; $lazyCommandMap[$commandName] = $id;
$lazyCommandRefs[$id] = new TypedReference($id, $class); $lazyCommandRefs[$id] = new TypedReference($id, $class);
$aliases = [];
foreach ($tags as $tag) { foreach ($tags as $tag) {
if (isset($tag['command'])) { if (isset($tag['command'])) {
$aliases[] = $tag['command']; $aliases[] = $tag['command'];
$lazyCommandMap[$tag['command']] = $id; $lazyCommandMap[$tag['command']] = $id;
} }
$description = $description ?? $tag['description'] ?? null;
} }
$definition->addMethodCall('setName', [$commandName]); $definition->addMethodCall('setName', [$commandName]);
@ -91,6 +104,29 @@ class AddConsoleCommandPass implements CompilerPassInterface
if ($aliases) { if ($aliases) {
$definition->addMethodCall('setAliases', [$aliases]); $definition->addMethodCall('setAliases', [$aliases]);
} }
if ($isHidden) {
$definition->addMethodCall('setHidden', [true]);
}
if (!$description) {
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));
}
$description = $class::getDefaultDescription();
}
if ($description) {
$definition->addMethodCall('setDescription', [$description]);
$container->register('.'.$id.'.lazy', LazyCommand::class)
->setArguments([$commandName, $aliases, $description, $isHidden, new ServiceClosureArgument($lazyCommandRefs[$id])]);
$lazyCommandRefs[$id] = new Reference('.'.$id.'.lazy');
}
} }
$container $container

View File

@ -13,6 +13,7 @@ namespace Symfony\Component\Console\Tests\DependencyInjection;
use PHPUnit\Framework\TestCase; use PHPUnit\Framework\TestCase;
use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Command\LazyCommand;
use Symfony\Component\Console\CommandLoader\ContainerCommandLoader; use Symfony\Component\Console\CommandLoader\ContainerCommandLoader;
use Symfony\Component\Console\DependencyInjection\AddConsoleCommandPass; use Symfony\Component\Console\DependencyInjection\AddConsoleCommandPass;
use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument; use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument;
@ -20,6 +21,7 @@ use Symfony\Component\DependencyInjection\ChildDefinition;
use Symfony\Component\DependencyInjection\Compiler\PassConfig; use Symfony\Component\DependencyInjection\Compiler\PassConfig;
use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition; use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\TypedReference; use Symfony\Component\DependencyInjection\TypedReference;
class AddConsoleCommandPassTest extends TestCase class AddConsoleCommandPassTest extends TestCase
@ -118,6 +120,39 @@ class AddConsoleCommandPassTest extends TestCase
]; ];
} }
public function testProcessFallsBackToDefaultDescription()
{
$container = new ContainerBuilder();
$container
->register('with-defaults', DescribedCommand::class)
->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(['cmdname' => 'with-defaults'], $commandLoader->getArgument(1));
$this->assertEquals([['with-defaults' => new ServiceClosureArgument(new Reference('.with-defaults.lazy'))]], $commandLocator->getArguments());
$this->assertSame([], $container->getParameter('console.command.ids'));
$initCounter = DescribedCommand::$initCounter;
$command = $container->get('console.command_loader')->get('cmdname');
$this->assertInstanceOf(LazyCommand::class, $command);
$this->assertSame(['cmdalias'], $command->getAliases());
$this->assertSame('Just testing', $command->getDescription());
$this->assertTrue($command->isHidden());
$this->assertTrue($command->isEnabled());
$this->assertSame($initCounter, DescribedCommand::$initCounter);
$this->assertSame('', $command->getHelp());
$this->assertSame(1 + $initCounter, DescribedCommand::$initCounter);
}
public function testProcessThrowAnExceptionIfTheServiceIsAbstract() public function testProcessThrowAnExceptionIfTheServiceIsAbstract()
{ {
$this->expectException(\InvalidArgumentException::class); $this->expectException(\InvalidArgumentException::class);
@ -250,3 +285,18 @@ class NamedCommand extends Command
{ {
protected static $defaultName = 'default'; protected static $defaultName = 'default';
} }
class DescribedCommand extends Command
{
public static $initCounter = 0;
protected static $defaultName = '|cmdname|cmdalias';
protected static $defaultDescription = 'Just testing';
public function __construct()
{
++self::$initCounter;
parent::__construct();
}
}

View File

@ -32,6 +32,7 @@ use Symfony\Component\HttpKernel\Debug\FileLinkFormatter;
class DebugCommand extends Command class DebugCommand extends Command
{ {
protected static $defaultName = 'debug:form'; protected static $defaultName = 'debug:form';
protected static $defaultDescription = 'Displays form type information';
private $formRegistry; private $formRegistry;
private $namespaces; private $namespaces;
@ -64,7 +65,7 @@ class DebugCommand extends Command
new InputOption('show-deprecated', null, InputOption::VALUE_NONE, 'Display deprecated options in form types'), new InputOption('show-deprecated', null, InputOption::VALUE_NONE, 'Display deprecated options in form types'),
new InputOption('format', null, InputOption::VALUE_REQUIRED, 'The output format (txt or json)', 'txt'), new InputOption('format', null, InputOption::VALUE_REQUIRED, 'The output format (txt or json)', 'txt'),
]) ])
->setDescription('Displays form type information') ->setDescription(self::$defaultDescription)
->setHelp(<<<'EOF' ->setHelp(<<<'EOF'
The <info>%command.name%</info> command displays information about form types. The <info>%command.name%</info> command displays information about form types.

View File

@ -36,6 +36,7 @@ use Symfony\Component\Messenger\Worker;
class ConsumeMessagesCommand extends Command class ConsumeMessagesCommand extends Command
{ {
protected static $defaultName = 'messenger:consume'; protected static $defaultName = 'messenger:consume';
protected static $defaultDescription = 'Consumes messages';
private $routableBus; private $routableBus;
private $receiverLocator; private $receiverLocator;
@ -71,7 +72,7 @@ class ConsumeMessagesCommand extends Command
new InputOption('sleep', null, InputOption::VALUE_REQUIRED, 'Seconds to sleep before asking for new messages after no messages were found', 1), new InputOption('sleep', null, InputOption::VALUE_REQUIRED, 'Seconds to sleep before asking for new messages after no messages were found', 1),
new InputOption('bus', 'b', InputOption::VALUE_REQUIRED, 'Name of the bus to which received messages should be dispatched (if not passed, bus is determined automatically)'), new InputOption('bus', 'b', InputOption::VALUE_REQUIRED, 'Name of the bus to which received messages should be dispatched (if not passed, bus is determined automatically)'),
]) ])
->setDescription('Consumes messages') ->setDescription(self::$defaultDescription)
->setHelp(<<<'EOF' ->setHelp(<<<'EOF'
The <info>%command.name%</info> command consumes messages and dispatches them to the message bus. The <info>%command.name%</info> command consumes messages and dispatches them to the message bus.

View File

@ -26,6 +26,7 @@ use Symfony\Component\Console\Style\SymfonyStyle;
class DebugCommand extends Command class DebugCommand extends Command
{ {
protected static $defaultName = 'debug:messenger'; protected static $defaultName = 'debug:messenger';
protected static $defaultDescription = 'Lists messages you can dispatch using the message buses';
private $mapping; private $mapping;
@ -43,7 +44,7 @@ class DebugCommand extends Command
{ {
$this $this
->addArgument('bus', InputArgument::OPTIONAL, sprintf('The bus id (one of "%s")', implode('", "', array_keys($this->mapping)))) ->addArgument('bus', InputArgument::OPTIONAL, sprintf('The bus id (one of "%s")', implode('", "', array_keys($this->mapping))))
->setDescription('Lists messages you can dispatch using the message buses') ->setDescription(self::$defaultDescription)
->setHelp(<<<'EOF' ->setHelp(<<<'EOF'
The <info>%command.name%</info> command displays all messages that can be The <info>%command.name%</info> command displays all messages that can be
dispatched using the message buses: dispatched using the message buses:

View File

@ -27,6 +27,7 @@ use Symfony\Component\Messenger\Transport\Receiver\ReceiverInterface;
class FailedMessagesRemoveCommand extends AbstractFailedMessagesCommand class FailedMessagesRemoveCommand extends AbstractFailedMessagesCommand
{ {
protected static $defaultName = 'messenger:failed:remove'; protected static $defaultName = 'messenger:failed:remove';
protected static $defaultDescription = 'Remove given messages from the failure transport';
/** /**
* {@inheritdoc} * {@inheritdoc}
@ -39,7 +40,7 @@ class FailedMessagesRemoveCommand extends AbstractFailedMessagesCommand
new InputOption('force', null, InputOption::VALUE_NONE, 'Force the operation without confirmation'), new InputOption('force', null, InputOption::VALUE_NONE, 'Force the operation without confirmation'),
new InputOption('show-messages', null, InputOption::VALUE_NONE, 'Display messages before removing it (if multiple ids are given)'), new InputOption('show-messages', null, InputOption::VALUE_NONE, 'Display messages before removing it (if multiple ids are given)'),
]) ])
->setDescription('Remove given messages from the failure transport') ->setDescription(self::$defaultDescription)
->setHelp(<<<'EOF' ->setHelp(<<<'EOF'
The <info>%command.name%</info> removes given messages that are pending in the failure transport. The <info>%command.name%</info> removes given messages that are pending in the failure transport.

View File

@ -35,6 +35,7 @@ use Symfony\Component\Messenger\Worker;
class FailedMessagesRetryCommand extends AbstractFailedMessagesCommand class FailedMessagesRetryCommand extends AbstractFailedMessagesCommand
{ {
protected static $defaultName = 'messenger:failed:retry'; protected static $defaultName = 'messenger:failed:retry';
protected static $defaultDescription = 'Retries one or more messages from the failure transport';
private $eventDispatcher; private $eventDispatcher;
private $messageBus; private $messageBus;
@ -59,7 +60,7 @@ class FailedMessagesRetryCommand extends AbstractFailedMessagesCommand
new InputArgument('id', InputArgument::IS_ARRAY, 'Specific message id(s) to retry'), new InputArgument('id', InputArgument::IS_ARRAY, 'Specific message id(s) to retry'),
new InputOption('force', null, InputOption::VALUE_NONE, 'Force action without confirmation'), new InputOption('force', null, InputOption::VALUE_NONE, 'Force action without confirmation'),
]) ])
->setDescription('Retries one or more messages from the failure transport') ->setDescription(self::$defaultDescription)
->setHelp(<<<'EOF' ->setHelp(<<<'EOF'
The <info>%command.name%</info> retries message in the failure transport. The <info>%command.name%</info> retries message in the failure transport.

View File

@ -28,6 +28,7 @@ use Symfony\Component\Messenger\Transport\Receiver\ListableReceiverInterface;
class FailedMessagesShowCommand extends AbstractFailedMessagesCommand class FailedMessagesShowCommand extends AbstractFailedMessagesCommand
{ {
protected static $defaultName = 'messenger:failed:show'; protected static $defaultName = 'messenger:failed:show';
protected static $defaultDescription = 'Shows one or more messages from the failure transport';
/** /**
* {@inheritdoc} * {@inheritdoc}
@ -39,7 +40,7 @@ class FailedMessagesShowCommand extends AbstractFailedMessagesCommand
new InputArgument('id', InputArgument::OPTIONAL, 'Specific message id to show'), new InputArgument('id', InputArgument::OPTIONAL, 'Specific message id to show'),
new InputOption('max', null, InputOption::VALUE_REQUIRED, 'Maximum number of messages to list', 50), new InputOption('max', null, InputOption::VALUE_REQUIRED, 'Maximum number of messages to list', 50),
]) ])
->setDescription('Shows one or more messages from the failure transport') ->setDescription(self::$defaultDescription)
->setHelp(<<<'EOF' ->setHelp(<<<'EOF'
The <info>%command.name%</info> shows message that are pending in the failure transport. The <info>%command.name%</info> shows message that are pending in the failure transport.

View File

@ -25,6 +25,7 @@ use Symfony\Component\Messenger\Transport\SetupableTransportInterface;
class SetupTransportsCommand extends Command class SetupTransportsCommand extends Command
{ {
protected static $defaultName = 'messenger:setup-transports'; protected static $defaultName = 'messenger:setup-transports';
protected static $defaultDescription = 'Prepares the required infrastructure for the transport';
private $transportLocator; private $transportLocator;
private $transportNames; private $transportNames;
@ -41,7 +42,7 @@ class SetupTransportsCommand extends Command
{ {
$this $this
->addArgument('transport', InputArgument::OPTIONAL, 'Name of the transport to setup', null) ->addArgument('transport', InputArgument::OPTIONAL, 'Name of the transport to setup', null)
->setDescription('Prepares the required infrastructure for the transport') ->setDescription(self::$defaultDescription)
->setHelp(<<<EOF ->setHelp(<<<EOF
The <info>%command.name%</info> command setups the transports: The <info>%command.name%</info> command setups the transports:

View File

@ -25,6 +25,7 @@ use Symfony\Component\Messenger\EventListener\StopWorkerOnRestartSignalListener;
class StopWorkersCommand extends Command class StopWorkersCommand extends Command
{ {
protected static $defaultName = 'messenger:stop-workers'; protected static $defaultName = 'messenger:stop-workers';
protected static $defaultDescription = 'Stops workers after their current message';
private $restartSignalCachePool; private $restartSignalCachePool;
@ -42,7 +43,7 @@ class StopWorkersCommand extends Command
{ {
$this $this
->setDefinition([]) ->setDefinition([])
->setDescription('Stops workers after their current message') ->setDescription(self::$defaultDescription)
->setHelp(<<<'EOF' ->setHelp(<<<'EOF'
The <info>%command.name%</info> command sends a signal to stop any <info>messenger:consume</info> processes that are running. The <info>%command.name%</info> command sends a signal to stop any <info>messenger:consume</info> processes that are running.

View File

@ -31,6 +31,7 @@ use Symfony\Component\Translation\Util\XliffUtils;
class XliffLintCommand extends Command class XliffLintCommand extends Command
{ {
protected static $defaultName = 'lint:xliff'; protected static $defaultName = 'lint:xliff';
protected static $defaultDescription = 'Lints a XLIFF file and outputs encountered errors';
private $format; private $format;
private $displayCorrectFiles; private $displayCorrectFiles;
@ -53,7 +54,7 @@ class XliffLintCommand extends Command
protected function configure() protected function configure()
{ {
$this $this
->setDescription('Lints a XLIFF file and outputs encountered errors') ->setDescription(self::$defaultDescription)
->addArgument('filename', InputArgument::IS_ARRAY, 'A file, a directory or "-" for reading from STDIN') ->addArgument('filename', InputArgument::IS_ARRAY, 'A file, a directory or "-" for reading from STDIN')
->addOption('format', null, InputOption::VALUE_REQUIRED, 'The output format', 'txt') ->addOption('format', null, InputOption::VALUE_REQUIRED, 'The output format', 'txt')
->setHelp(<<<EOF ->setHelp(<<<EOF

View File

@ -33,6 +33,7 @@ use Symfony\Component\Validator\Mapping\Factory\MetadataFactoryInterface;
class DebugCommand extends Command class DebugCommand extends Command
{ {
protected static $defaultName = 'debug:validator'; protected static $defaultName = 'debug:validator';
protected static $defaultDescription = 'Displays validation constraints for classes';
private $validator; private $validator;
@ -48,7 +49,7 @@ class DebugCommand extends Command
$this $this
->addArgument('class', InputArgument::REQUIRED, 'A fully qualified class name or a path') ->addArgument('class', InputArgument::REQUIRED, 'A fully qualified class name or a path')
->addOption('show-all', null, InputOption::VALUE_NONE, 'Show all classes even if they have no validation constraints') ->addOption('show-all', null, InputOption::VALUE_NONE, 'Show all classes even if they have no validation constraints')
->setDescription('Displays validation constraints for classes') ->setDescription(self::$defaultDescription)
->setHelp(<<<'EOF' ->setHelp(<<<'EOF'
The <info>%command.name% 'App\Entity\Dummy'</info> command dumps the validators for the dummy class. The <info>%command.name% 'App\Entity\Dummy'</info> command dumps the validators for the dummy class.

View File

@ -35,6 +35,7 @@ use Symfony\Component\VarDumper\Server\DumpServer;
class ServerDumpCommand extends Command class ServerDumpCommand extends Command
{ {
protected static $defaultName = 'server:dump'; protected static $defaultName = 'server:dump';
protected static $defaultDescription = 'Starts a dump server that collects and displays dumps in a single place';
private $server; private $server;
@ -58,7 +59,7 @@ class ServerDumpCommand extends Command
$this $this
->addOption('format', null, InputOption::VALUE_REQUIRED, sprintf('The output format (%s)', $availableFormats), 'cli') ->addOption('format', null, InputOption::VALUE_REQUIRED, sprintf('The output format (%s)', $availableFormats), 'cli')
->setDescription('Starts a dump server that collects and displays dumps in a single place') ->setDescription(self::$defaultDescription)
->setHelp(<<<'EOF' ->setHelp(<<<'EOF'
<info>%command.name%</info> starts a dump server that collects and displays <info>%command.name%</info> starts a dump server that collects and displays
dumps in a single place for debugging you application: dumps in a single place for debugging you application:

View File

@ -33,6 +33,7 @@ use Symfony\Component\Yaml\Yaml;
class LintCommand extends Command class LintCommand extends Command
{ {
protected static $defaultName = 'lint:yaml'; protected static $defaultName = 'lint:yaml';
protected static $defaultDescription = 'Lints a file and outputs encountered errors';
private $parser; private $parser;
private $format; private $format;
@ -54,7 +55,7 @@ class LintCommand extends Command
protected function configure() protected function configure()
{ {
$this $this
->setDescription('Lints a file and outputs encountered errors') ->setDescription(self::$defaultDescription)
->addArgument('filename', InputArgument::IS_ARRAY, 'A file, a directory or "-" for reading from STDIN') ->addArgument('filename', InputArgument::IS_ARRAY, 'A file, a directory or "-" for reading from STDIN')
->addOption('format', null, InputOption::VALUE_REQUIRED, 'The output format') ->addOption('format', null, InputOption::VALUE_REQUIRED, 'The output format')
->addOption('parse-tags', null, InputOption::VALUE_NONE, 'Parse custom tags') ->addOption('parse-tags', null, InputOption::VALUE_NONE, 'Parse custom tags')