8000 [Console] Deprecate abbreviating hidden command names using Applicat… · symfony/symfony@38e67fd · GitHub
[go: up one dir, main page]

Skip to content

Commit 38e67fd

Browse files
m-vochalasr
authored andcommitted
[Console] Deprecate abbreviating hidden command names using Application->find()
1 parent ae61ae5 commit 38e67fd

File tree

7 files changed

+135
-6
lines changed

7 files changed

+135
-6
lines changed

UPGRADE-4.4.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@ Cache
66

77
* Added argument `$prefix` to `AdapterInterface::clear()`
88

9+
Console
10+
-------
11+
12+
* Deprecated finding hidden commands using an abbreviation, use the full name instead
13+
914
Debug
1015
-----
1116

UPGRADE-5.0.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ Config
3131
Console
3232
-------
3333

34+
* Removed support for finding hidden commands using an abbreviation, use the full name instead
3435
* Removed the `setCrossingChar()` method in favor of the `setDefaultCrossingChar()` method in `TableStyle`.
3536
* Removed the `setHorizontalBorderChar()` method in favor of the `setDefaultCrossingChars()` method in `TableStyle`.
3637
* Removed the `getHorizontalBorderChar()` method in favor of the `getBorderChars()` method in `TableStyle`.

src/Symfony/Component/Console/Application.php

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -557,6 +557,10 @@ public function getNamespaces()
557557
{
558558
$namespaces = [];
559559
foreach ($this->all() as $command) {
560+
if ($command->isHidden()) {
561+
continue;
562+
}
563+
560564
$namespaces = array_merge($namespaces, $this->extractAllNamespaces($command->getName()));
561565

562566
foreach ($command->getAliases() as $alias) {
@@ -654,6 +658,11 @@ public function find($name)
654658
$message = sprintf('Command "%s" is not defined.', $name);
655659

656660
if ($alternatives = $this->findAlternatives($name, $allCommands)) {
661+
// remove hidden commands
662+
$alternatives = array_filter($alternatives, function ($name) {
663+
return !$this->get($name)->isHidden();
664+
});
665+
657666
if (1 == \count($alternatives)) {
658667
$message .= "\n\nDid you mean this?\n ";
659668
} else {
@@ -662,7 +671,7 @@ public function find($name)
662671
$message .= implode("\n ", $alternatives);
663672
}
664673

665-
throw new CommandNotFoundException($message, $alternatives);
674+
throw new CommandNotFoundException($message, array_values($alternatives));
666675
}
667676

668677
// filter out aliases for commands which are already on the list
@@ -683,20 +692,36 @@ public function find($name)
683692
foreach ($abbrevs as $abbrev) {
684693
$maxLen = max(Helper::strlen($abbrev), $maxLen);
685694
}
686-
$abbrevs = array_map(function ($cmd) use ($commandList, $usableWidth, $maxLen) {
695+
$abbrevs = array_map(function ($cmd) use ($commandList, $usableWidth, $maxLen, &$commands) {
< 67E6 code>687696
if (!$commandList[$cmd] instanceof Command) {
688-
return $cmd;
697+
$commandList[$cmd] = $this->commandLoader->get($cmd);
689698
}
699+
700+
if ($commandList[$cmd]->isHidden()) {
701+
unset($commands[array_search($cmd, $commands)]);
702+
703+
return false;
704+
}
705+
690706
$abbrev = str_pad($cmd, $maxLen, ' ').' '.$commandList[$cmd]->getDescription();
691707

692708
return Helper::strlen($abbrev) > $usableWidth ? Helper::substr($abbrev, 0, $usableWidth - 3).'...' : $abbrev;
693709
}, array_values($commands));
694-
$suggestions = $this->getAbbreviationSuggestions($abbrevs);
695710

696-
A3E2 throw new CommandNotFoundException(sprintf("Command \"%s\" is ambiguous.\nDid you mean one of these?\n%s", $name, $suggestions), array_values($commands));
711+
if (\count($commands) > 1) {
712+
$suggestions = $this->getAbbreviationSuggestions(array_filter($abbrevs));
713+
714+
throw new CommandNotFoundException(sprintf("Command \"%s\" is ambiguous.\nDid you mean one of these?\n%s", $name, $suggestions), array_values($commands));
715+
}
716+
}
717+
718+
$command = $this->get(reset($commands));
719+
720+
if ($command->isHidden()) {
721+
@trigger_error(sprintf('Command "%s" is hidden, finding it using an abbreviation is deprecated since Symfony 4.4, use its full name instead.', $command->getName()), E_USER_DEPRECATED);
697722
}
698723

699-
return $this->get(reset($commands));
724+
return $command;
700725
}
701726

702727
/**

src/Symfony/Component/Console/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ CHANGELOG
44
4.4.0
55
-----
66

7+
* deprecated finding hidden commands using an abbreviation, use the full name instead
78
* added `Question::setTrimmable` default to true to allow the answer to be trimmed
89
* added method `preventRedrawFasterThan()` and `forceRedrawSlowerThan()` on `ProgressBar`
910
* `Application` implements `ResetInterface`

src/Symfony/Component/Console/Tests/ApplicationTest.php

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,8 @@ public static function setUpBeforeClass(): void
7575
require_once self::$fixturesPath.'/FooWithoutAliasCommand.php';
7676
require_once self::$fixturesPath.'/TestAmbiguousCommandRegistering.php';
7777
require_once self::$fixturesPath.'/TestAmbiguousCommandRegistering2.php';
78+
require_once self::$fixturesPath.'/FooHiddenCommand.php';
79+
require_once self::$fixturesPath.'/BarHiddenCommand.php';
7880
}
7981

8082
protected function normalizeLineBreaks($text)
@@ -440,6 +442,16 @@ public function provideAmbiguousAbbreviations()
440442
];
441443
}
442444

445+
public function testFindWithAmbiguousAbbreviationsFindsCommandIfAlternativesAreHidden()
446+
{
447+
$application = new Application();
448+
449+
$application->add(new \FooCommand());
450+
$application->add(new \FooHiddenCommand());
451+
452+
$this->assertInstanceOf('FooCommand', $application->find('foo:'));
453+
}
454+
443455
public function testFindCommandEqualNamespace()
444456
{
445457
$application = new Application();
@@ -706,6 +718,49 @@ public function testFindWithDoubleColonInNameThrowsException()
706718
$application->find('foo::bar');
707719
}
708720

721+
public function testFindHiddenWithExactName()
722+
{
723+
$application = new Application();
724+
$application->add(new \FooHiddenCommand());
725+
726+
$this->assertInstanceOf('FooHiddenCommand', $application->find('foo:hidden'));
727+
$this->assertInstanceOf('FooHiddenCommand', $application->find('afoohidden'));
728+
}
729+
730+
/**
731+
* @group legacy
732+
* @expectedDeprecation Command "%s:hidden" is hidden, finding it using an abbreviation is deprecated since Symfony 4.4, use its full name instead.
733+
* @dataProvider provideAbbreviationsForHiddenCommands
734+
*/
735+
public function testFindHiddenWithAbbreviatedName($name)
736+
{
737+
$application = new Application();
738+
739+
$application->add(new \FooHiddenCommand());
740+
$application->add(new \BarHiddenCommand());
741+
742+
$application->find($name);
743+
}
744+
745+
public function provideAbbreviationsForHiddenCommands()
746+
{
747+
return [
748+
['foo:hidde'],
749+
['afoohidd'],
750+
['bar:hidde'],
751+
];
752+
}
753+
754+
public function testFindAmbiguousCommandsIfAllAlternativesAreHidden()
755+
{
756+
$application = new Application();
757+
758+
$application->add(new \FooCommand());
759+
$application->add(new \FooHiddenCommand());
760+
761+
$this->assertInstanceOf('FooCommand', $application->find('foo:'));
762+
}
763+
709764
public function testSetCatchExceptions()
710765
{
711766
$application = new Application();
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
use Symfony\Component\Console\Command\Command;
4+
use Symfony\Component\Console\Input\InputInterface;
5+
use Symfony\Component\Console\Output\OutputInterface;
6+
7+
class BarHiddenCommand extends Command
8+
{
9+
protected function configure()
10+
{
11+
$this
12+
->setName('bar:hidden')
13+
->setAliases(['abarhidden'])
14+
->setHidden(true)
15+
;
16+
}
17+
18+
protected function execute(InputInterface $input, OutputInterface $output)
19+
{
20+
}
21+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
use Symfony\Component\Console\Command\Command;
4+
use Symfony\Component\Console\Input\InputInterface;
5+
use Symfony\Component\Console\Output\OutputInterface;
6+
7+
class FooHiddenCommand extends Command
8+
{
9+
protected function configure()
10+
{
11+
$this
12+
->setName('foo:hidden')
13+
->setAliases(['afoohidden'])
14+
->setHidden(true)
15+
;
16+
}
17+
18+
protected function execute(InputInterface $input, OutputInterface $output)
19+
{
20+
}
21+
}

0 commit comments

Comments
 (0)
0