bug #33748 [Console] Do not include hidden commands in suggested alternatives (m-vo)
This PR was merged into the 3.4 branch.
Discussion
----------
[Console] Do not include hidden commands in suggested alternatives
| Q | A
| ------------- | ---
| Branch? | 3.4
| Bug fix? | yes
| New feature? | no
| Deprecations? | no
| Tickets | Fix #33398
| License | MIT
| Doc PR | n/a
Partially backports #33412 on 3.4, avoids leaking the names of hidden commands in suggested alternatives on command not found.
Commits
-------
8a9d173c36
Do not include hidden commands in suggested alternatives
This commit is contained in:
commit
944cda7969
@ -529,6 +529,10 @@ class Application
|
||||
{
|
||||
$namespaces = [];
|
||||
foreach ($this->all() as $command) {
|
||||
if ($command->isHidden()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$namespaces = array_merge($namespaces, $this->extractAllNamespaces($command->getName()));
|
||||
|
||||
foreach ($command->getAliases() as $alias) {
|
||||
@ -622,6 +626,11 @@ class Application
|
||||
$message = sprintf('Command "%s" is not defined.', $name);
|
||||
|
||||
if ($alternatives = $this->findAlternatives($name, $allCommands)) {
|
||||
// remove hidden commands
|
||||
$alternatives = array_filter($alternatives, function ($name) {
|
||||
return !$this->get($name)->isHidden();
|
||||
});
|
||||
|
||||
if (1 == \count($alternatives)) {
|
||||
$message .= "\n\nDid you mean this?\n ";
|
||||
} else {
|
||||
@ -630,7 +639,7 @@ class Application
|
||||
$message .= implode("\n ", $alternatives);
|
||||
}
|
||||
|
||||
throw new CommandNotFoundException($message, $alternatives);
|
||||
throw new CommandNotFoundException($message, array_values($alternatives));
|
||||
}
|
||||
|
||||
// filter out aliases for commands which are already on the list
|
||||
@ -654,13 +663,18 @@ class Application
|
||||
}
|
||||
$abbrevs = array_map(function ($cmd) use ($commandList, $usableWidth, $maxLen) {
|
||||
if (!$commandList[$cmd] instanceof Command) {
|
||||
return $cmd;
|
||||
$commandList[$cmd] = $this->commandLoader->get($cmd);
|
||||
}
|
||||
|
||||
if ($commandList[$cmd]->isHidden()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$abbrev = str_pad($cmd, $maxLen, ' ').' '.$commandList[$cmd]->getDescription();
|
||||
|
||||
return Helper::strlen($abbrev) > $usableWidth ? Helper::substr($abbrev, 0, $usableWidth - 3).'...' : $abbrev;
|
||||
}, array_values($commands));
|
||||
$suggestions = $this->getAbbreviationSuggestions($abbrevs);
|
||||
$suggestions = $this->getAbbreviationSuggestions(array_filter($abbrevs));
|
||||
|
||||
throw new CommandNotFoundException(sprintf("Command \"%s\" is ambiguous.\nDid you mean one of these?\n%s", $name, $suggestions), array_values($commands));
|
||||
}
|
||||
|
@ -74,6 +74,7 @@ class ApplicationTest extends TestCase
|
||||
require_once self::$fixturesPath.'/FooSubnamespaced2Command.php';
|
||||
require_once self::$fixturesPath.'/TestAmbiguousCommandRegistering.php';
|
||||
require_once self::$fixturesPath.'/TestAmbiguousCommandRegistering2.php';
|
||||
require_once self::$fixturesPath.'/FooHiddenCommand.php';
|
||||
}
|
||||
|
||||
protected function normalizeLineBreaks($text)
|
||||
@ -616,6 +617,7 @@ class ApplicationTest extends TestCase
|
||||
$application->add(new \Foo1Command());
|
||||
$application->add(new \Foo2Command());
|
||||
$application->add(new \Foo3Command());
|
||||
$application->add(new \FooHiddenCommand());
|
||||
|
||||
$expectedAlternatives = [
|
||||
'afoobar',
|
||||
|
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
class FooHiddenCommand extends Command
|
||||
{
|
||||
protected function configure()
|
||||
{
|
||||
$this
|
||||
->setName('foo:hidden')
|
||||
->setAliases(['afoohidden'])
|
||||
->setHidden(true)
|
||||
;
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user