Skip to content

Commit

Permalink
feature #33775 [Console] Add deprecation message for non-int statusCo…
Browse files Browse the repository at this point in the history
…de (jschaedl)

This PR was merged into the 4.4 branch.

Discussion
----------

[Console] Add deprecation message for non-int statusCode

| Q             | A
| ------------- | ---
| Branch?       | 4.4
| Bug fix?      | no
| New feature?  | no <!-- please update src/**/CHANGELOG.md files -->
| Deprecations? | yes <!-- please update UPGRADE-*.md and src/**/CHANGELOG.md files -->
| Tickets       | Fix #33747 <!-- prefix each issue number with "Fix #", if any -->
| License       | MIT
| Doc PR        | -

### What was done:

- [x] added deprecation message for non-int return value in Command::execute()
- [x] fixed all core commands to return proper int values
- [x] added proper return type-hint to Command::execute() method in all core Commands

Commits
-------

98c4f6a [Console] Command::execute() should always return int - deprecate returning null
  • Loading branch information
nicolas-grekas committed Oct 2, 2019
2 parents 3354bac + 98c4f6a commit c2111be
Show file tree
Hide file tree
Showing 50 changed files with 128 additions and 54 deletions.
1 change: 1 addition & 0 deletions UPGRADE-4.4.md
Expand Up @@ -10,6 +10,7 @@ Console
-------

* Deprecated finding hidden commands using an abbreviation, use the full name instead
* Deprecated returning `null` from `Command::execute()`, return `0` instead

Debug
-----
Expand Down
1 change: 1 addition & 0 deletions UPGRADE-5.0.md
Expand Up @@ -37,6 +37,7 @@ Console
* Removed the `getHorizontalBorderChar()` method in favor of the `getBorderChars()` method in `TableStyle`.
* Removed the `setVerticalBorderChar()` method in favor of the `setVerticalBorderChars()` method in `TableStyle`.
* Removed the `getVerticalBorderChar()` method in favor of the `getBorderChars()` method in `TableStyle`.
* Removed support for returning `null` from `Command::execute()`, return `0` instead
* The `ProcessHelper::run()` method takes the command as an array of arguments.

Before:
Expand Down
8 changes: 6 additions & 2 deletions src/Symfony/Bridge/Twig/Command/DebugCommand.php
Expand Up @@ -111,12 +111,16 @@ protected function execute(InputInterface $input, OutputInterface $output)

switch ($input->getOption('format')) {
case 'text':
return $name ? $this->displayPathsText($io, $name) : $this->displayGeneralText($io, $filter);
$name ? $this->displayPathsText($io, $name) : $this->displayGeneralText($io, $filter);
break;
case 'json':
return $name ? $this->displayPathsJson($io, $name) : $this->displayGeneralJson($io, $filter);
$name ? $this->displayPathsJson($io, $name) : $this->displayGeneralJson($io, $filter);
break;
default:
throw new InvalidArgumentException(sprintf('The format "%s" is not supported.', $input->getOption('format')));
}

return 0;
}

private function displayPathsText(SymfonyStyle $io, string $name)
Expand Down
4 changes: 3 additions & 1 deletion src/Symfony/Bundle/FrameworkBundle/Command/AboutCommand.php
Expand Up @@ -54,7 +54,7 @@ protected function configure()
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
protected function execute(InputInterface $input, OutputInterface $output): int
{
$io = new SymfonyStyle($input, $output);

Expand Down Expand Up @@ -100,6 +100,8 @@ protected function execute(InputInterface $input, OutputInterface $output)
}

$io->table([], $rows);

return 0;
}

private static function formatPath(string $path, string $baseDir): string
Expand Down
Expand Up @@ -72,7 +72,7 @@ protected function configure()
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
protected function execute(InputInterface $input, OutputInterface $output): int
{
$fs = $this->filesystem;
$io = new SymfonyStyle($input, $output);
Expand Down Expand Up @@ -175,6 +175,8 @@ protected function execute(InputInterface $input, OutputInterface $output)
}

$io->success(sprintf('Cache for the "%s" environment (debug=%s) was successfully cleared.', $kernel->getEnvironment(), var_export($kernel->isDebug(), true)));

return 0;
}

private function warmup(string $warmupDir, string $realCacheDir, bool $enableOptionalWarmers = true)
Expand Down
Expand Up @@ -60,7 +60,7 @@ protected function configure()
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
protected function execute(InputInterface $input, OutputInterface $output): int
{
$io = new SymfonyStyle($input, $output);
$kernel = $this->getApplication()->getKernel();
Expand Down Expand Up @@ -99,5 +99,7 @@ protected function execute(InputInterface $input, OutputInterface $output)
}

$io->success('Cache was successfully cleared.');

return 0;
}
}
Expand Up @@ -59,7 +59,7 @@ protected function configure()
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
protected function execute(InputInterface $input, OutputInterface $output): int
{
$io = new SymfonyStyle($input, $output);
$pool = $input->getArgument('pool');
Expand All @@ -69,13 +69,15 @@ protected function execute(InputInterface $input, OutputInterface $output)
if (!$cachePool->hasItem($key)) {
$io->note(sprintf('Cache item "%s" does not exist in cache pool "%s".', $key, $pool));

return;
return 0;
}

if (!$cachePool->deleteItem($key)) {
throw new \Exception(sprintf('Cache item "%s" could not be deleted.', $key));
}

$io->success(sprintf('Cache item "%s" was successfully deleted.', $key));

return 0;
}
}
Expand Up @@ -51,12 +51,14 @@ protected function configure()
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
protected function execute(InputInterface $input, OutputInterface $output): int
{
$io = new SymfonyStyle($input, $output);

$io->table(['Pool name'], array_map(function ($pool) {
return [$pool];
}, $this->poolNames));

return 0;
}
}
Expand Up @@ -57,7 +57,7 @@ protected function configure()
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
protected function execute(InputInterface $input, OutputInterface $output): int
{
$io = new SymfonyStyle($input, $output);

Expand All @@ -67,5 +67,7 @@ protected function execute(InputInterface $input, OutputInterface $output)
}

$io->success('Successfully pruned cache pool(s).');

return 0;
}
}
Expand Up @@ -66,7 +66,7 @@ protected function configure()
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
protected function execute(InputInterface $input, OutputInterface $output): int
{
$io = new SymfonyStyle($input, $output);

Expand All @@ -80,5 +80,7 @@ protected function execute(InputInterface $input, OutputInterface $output)
$this->cacheWarmer->warmUp($kernel->getContainer()->getParameter('kernel.cache_dir'));

$io->success(sprintf('Cache for the "%s" environment (debug=%s) was successfully warmed.', $kernel->getEnvironment(), var_export($kernel->isDebug(), true)));

return 0;
}
}
Expand Up @@ -63,7 +63,7 @@ protected function configure()
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
protected function execute(InputInterface $input, OutputInterface $output): int
{
$io = new SymfonyStyle($input, $output);
$errorIo = $io->getErrorStyle();
Expand All @@ -73,7 +73,7 @@ protected function execute(InputInterface $input, OutputInterface $output)
$errorIo->comment('Provide the name of a bundle as the first argument of this command to dump its configuration. (e.g. <comment>debug:config FrameworkBundle</comment>)');
$errorIo->comment('For dumping a specific option, add its path as the second argument of this command. (e.g. <comment>debug:config FrameworkBundle serializer</comment> to dump the <comment>framework.serializer</comment> configuration)');

return;
return 0;
}

$extension = $this->findExtension($name);
Expand Down Expand Up @@ -101,7 +101,7 @@ protected function execute(InputInterface $input, OutputInterface $output)

$io->writeln(Yaml::dump([$extensionAlias => $config], 10));

return;
return 0;
}

try {
Expand All @@ -115,6 +115,8 @@ protected function execute(InputInterface $input, OutputInterface $output)
$io->title(sprintf('Current configuration for "%s.%s"', $extensionAlias, $path));

$io->writeln(Yaml::dump($config, 10));

return 0;
}

private function compileContainer(): ContainerBuilder
Expand Down
Expand Up @@ -114,7 +114,7 @@ protected function configure()
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
protected function execute(InputInterface $input, OutputInterface $output): int
{
if ($input->getOption('show-private')) {
@trigger_error('The "--show-private" option no longer has any effect and is deprecated since Symfony 4.1.', E_USER_DEPRECATED);
Expand Down Expand Up @@ -184,6 +184,8 @@ protected function execute(InputInterface $input, OutputInterface $output)
$errorIo->comment('To search for a specific service, re-run this command with a search term. (e.g. <comment>debug:container log</comment>)');
}
}

return 0;
}

/**
Expand Down
Expand Up @@ -69,7 +69,7 @@ protected function configure()
*
* @throws \LogicException
*/
protected function execute(InputInterface $input, OutputInterface $output)
protected function execute(InputInterface $input, OutputInterface $output): int
{
$io = new SymfonyStyle($input, $output);

Expand All @@ -78,7 +78,7 @@ protected function execute(InputInterface $input, OutputInterface $output)
if (!$this->dispatcher->hasListeners($event)) {
$io->getErrorStyle()->warning(sprintf('The event "%s" does not have any registered listeners.', $event));

return;
return 0;
}

$options = ['event' => $event];
Expand All @@ -89,5 +89,7 @@ protected function execute(InputInterface $input, OutputInterface $output)
$options['raw_text'] = $input->getOption('raw');
$options['output'] = $io;
$helper->describe($io, $this->dispatcher, $options);

return 0;
}
}
Expand Up @@ -73,7 +73,7 @@ protected function configure()
*
* @throws InvalidArgumentException When route does not exist
*/
protected function execute(InputInterface $input, OutputInterface $output)
protected function execute(InputInterface $input, OutputInterface $output): int
{
$io = new SymfonyStyle($input, $output);
$name = $input->getArgument('name');
Expand Down Expand Up @@ -105,6 +105,8 @@ protected function execute(InputInterface $input, OutputInterface $output)
'output' => $io,
]);
}

return 0;
}

private function findRouteNameContaining(string $name, RouteCollection $routes): array
Expand Down
Expand Up @@ -124,7 +124,7 @@ protected function configure()
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
protected function execute(InputInterface $input, OutputInterface $output): int
{
$io = new SymfonyStyle($input, $output);

Expand Down Expand Up @@ -246,7 +246,7 @@ protected function execute(InputInterface $input, OutputInterface $output)

$io->getErrorStyle()->warning($outputMessage);

return;
return 0;
}

// Load the fallback catalogues
Expand Down Expand Up @@ -295,6 +295,8 @@ protected function execute(InputInterface $input, OutputInterface $output)
}

$io->table($headers, $rows);

return 0;
}

private function formatState(int $state): string
Expand Down
Expand Up @@ -59,7 +59,7 @@ protected function configure()
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
protected function execute(InputInterface $input, OutputInterface $output): int
{
$container = $this->getApplication()->getKernel()->getContainer();
$serviceId = $input->getArgument('name');
Expand Down Expand Up @@ -97,5 +97,7 @@ protected function execute(InputInterface $input, OutputInterface $output)
],
];
$output->writeln($dumper->dump($workflow->getDefinition(), $marking, $options));

return 0;
}
}
Expand Up @@ -123,6 +123,8 @@ protected function execute(InputInterface $input, OutputInterface $output)

$this->displayLog($input, $output, $clientId, $record);
}

return 0;
}

private function getLogs($socket)
Expand Down
Expand Up @@ -164,6 +164,6 @@ protected function execute(InputInterface $input, OutputInterface $output)
return 1;
}

return null;
return 0;
}
}
Expand Up @@ -103,6 +103,6 @@ protected function execute(InputInterface $input, OutputInterface $output)
}
}

return null;
return 0;
}
}
Expand Up @@ -77,6 +77,6 @@ protected function execute(InputInterface $input, OutputInterface $output)
return 1;
}

return null;
return 0;
}
}
1 change: 1 addition & 0 deletions src/Symfony/Component/Console/CHANGELOG.md
Expand Up @@ -10,6 +10,7 @@ CHANGELOG
* `Application` implements `ResetInterface`
* marked all dispatched event classes as `@final`
* added support for displaying table horizontally
* deprecated returning `null` from `Command::execute()`, return `0` instead

4.3.0
-----
Expand Down
6 changes: 5 additions & 1 deletion src/Symfony/Component/Console/Command/Command.php
Expand Up @@ -150,7 +150,7 @@ protected function configure()
* execute() method, you set the code to execute by passing
* a Closure to the setCode() method.
*
* @return int|void void or 0 if everything went fine, or an exit code
* @return int 0 if everything went fine, or an exit code
*
* @throws LogicException When this abstract method is not implemented
*
Expand Down Expand Up @@ -253,6 +253,10 @@ public function run(InputInterface $input, OutputInterface $output)
$statusCode = ($this->code)($input, $output);
} else {
$statusCode = $this->execute($input, $output);

if (!\is_int($statusCode)) {
@trigger_error(sprintf('A non numeric or nullable $statusCode returned by Command::execute() is deprecated since Symfony 4.4, return an integer value instead.'), E_USER_DEPRECATED);
}
}

return is_numeric($statusCode) ? (int) $statusCode : 0;
Expand Down
2 changes: 2 additions & 0 deletions src/Symfony/Component/Console/Command/HelpCommand.php
Expand Up @@ -77,5 +77,7 @@ protected function execute(InputInterface $input, OutputInterface $output)
]);

$this->command = null;

return 0;
}
}
2 changes: 2 additions & 0 deletions src/Symfony/Component/Console/Command/ListCommand.php
Expand Up @@ -74,6 +74,8 @@ protected function execute(InputInterface $input, OutputInterface $output)
'raw_text' => $input->getOption('raw'),
'namespace' => $input->getArgument('namespace'),
]);

return 0;
}

private function createDefinition(): InputDefinition
Expand Down
4 changes: 3 additions & 1 deletion src/Symfony/Component/Console/Tests/ApplicationTest.php
Expand Up @@ -1837,9 +1837,11 @@ public function __construct()

class LazyCommand extends Command
{
public function execute(InputInterface $input, OutputInterface $output)
public function execute(InputInterface $input, OutputInterface $output): int
{
$output->writeln('lazy-command called');

return 0;
}
}

Expand Down

0 comments on commit c2111be

Please sign in to comment.