From f3406338e65182e5c6d096e83593877163efad69 Mon Sep 17 00:00:00 2001 From: "M. Vondano" Date: Sun, 1 Sep 2019 19:33:46 +0200 Subject: [PATCH] [Console] Deprecate abbreviating hidden command names using Application->find() --- UPGRADE-4.4.md | 5 ++ UPGRADE-5.0.md | 1 + src/Symfony/Component/Console/Application.php | 19 +++++-- src/Symfony/Component/Console/CHANGELOG.md | 1 + .../Console/Tests/ApplicationTest.php | 54 +++++++++++++++++++ .../Tests/Fixtures/BarHiddenCommand.php | 21 ++++++++ 6 files changed, 97 insertions(+), 4 deletions(-) create mode 100644 src/Symfony/Component/Console/Tests/Fixtures/BarHiddenCommand.php diff --git a/UPGRADE-4.4.md b/UPGRADE-4.4.md index 584eb693e2..323bf96c18 100644 --- a/UPGRADE-4.4.md +++ b/UPGRADE-4.4.md @@ -6,6 +6,11 @@ Cache * Added argument `$prefix` to `AdapterInterface::clear()` +Console +------- + + * Deprecated finding hidden commands using an abbreviation, use the full name instead + Debug ----- diff --git a/UPGRADE-5.0.md b/UPGRADE-5.0.md index 1039e3a5fe..e0df969c4a 100644 --- a/UPGRADE-5.0.md +++ b/UPGRADE-5.0.md @@ -31,6 +31,7 @@ Config Console ------- + * Removed support for finding hidden commands using an abbreviation, use the full name instead * Removed the `setCrossingChar()` method in favor of the `setDefaultCrossingChar()` method in `TableStyle`. * Removed the `setHorizontalBorderChar()` method in favor of the `setDefaultCrossingChars()` method in `TableStyle`. * Removed the `getHorizontalBorderChar()` method in favor of the `getBorderChars()` method in `TableStyle`. diff --git a/src/Symfony/Component/Console/Application.php b/src/Symfony/Component/Console/Application.php index af1af4b8ec..e66705ab37 100644 --- a/src/Symfony/Component/Console/Application.php +++ b/src/Symfony/Component/Console/Application.php @@ -692,12 +692,14 @@ class Application implements ResetInterface foreach ($abbrevs as $abbrev) { $maxLen = max(Helper::strlen($abbrev), $maxLen); } - $abbrevs = array_map(function ($cmd) use ($commandList, $usableWidth, $maxLen) { + $abbrevs = array_map(function ($cmd) use ($commandList, $usableWidth, $maxLen, &$commands) { if (!$commandList[$cmd] instanceof Command) { $commandList[$cmd] = $this->commandLoader->get($cmd); } if ($commandList[$cmd]->isHidden()) { + unset($commands[array_search($cmd, $commands)]); + return false; } @@ -705,12 +707,21 @@ class Application implements ResetInterface return Helper::strlen($abbrev) > $usableWidth ? Helper::substr($abbrev, 0, $usableWidth - 3).'...' : $abbrev; }, array_values($commands)); - $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)); + if (\count($commands) > 1) { + $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)); + } } - return $this->get(reset($commands)); + $command = $this->get(reset($commands)); + + if ($command->isHidden()) { + @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); + } + + return $command; } /** diff --git a/src/Symfony/Component/Console/CHANGELOG.md b/src/Symfony/Component/Console/CHANGELOG.md index b9e837a8d1..d1b8a324c6 100644 --- a/src/Symfony/Component/Console/CHANGELOG.md +++ b/src/Symfony/Component/Console/CHANGELOG.md @@ -4,6 +4,7 @@ CHANGELOG 4.4.0 ----- + * deprecated finding hidden commands using an abbreviation, use the full name instead * added `Question::setTrimmable` default to true to allow the answer to be trimmed * added method `preventRedrawFasterThan()` and `forceRedrawSlowerThan()` on `ProgressBar` * `Application` implements `ResetInterface` diff --git a/src/Symfony/Component/Console/Tests/ApplicationTest.php b/src/Symfony/Component/Console/Tests/ApplicationTest.php index 9b444419b8..e750975d2d 100644 --- a/src/Symfony/Component/Console/Tests/ApplicationTest.php +++ b/src/Symfony/Component/Console/Tests/ApplicationTest.php @@ -76,6 +76,7 @@ class ApplicationTest extends TestCase require_once self::$fixturesPath.'/TestAmbiguousCommandRegistering.php'; require_once self::$fixturesPath.'/TestAmbiguousCommandRegistering2.php'; require_once self::$fixturesPath.'/FooHiddenCommand.php'; + require_once self::$fixturesPath.'/BarHiddenCommand.php'; } protected function normalizeLineBreaks($text) @@ -441,6 +442,16 @@ class ApplicationTest extends TestCase ]; } + public function testFindWithAmbiguousAbbreviationsFindsCommandIfAlternativesAreHidden() + { + $application = new Application(); + + $application->add(new \FooCommand()); + $application->add(new \FooHiddenCommand()); + + $this->assertInstanceOf('FooCommand', $application->find('foo:')); + } + public function testFindCommandEqualNamespace() { $application = new Application(); @@ -708,6 +719,49 @@ class ApplicationTest extends TestCase $application->find('foo::bar'); } + public function testFindHiddenWithExactName() + { + $application = new Application(); + $application->add(new \FooHiddenCommand()); + + $this->assertInstanceOf('FooHiddenCommand', $application->find('foo:hidden')); + $this->assertInstanceOf('FooHiddenCommand', $application->find('afoohidden')); + } + + /** + * @group legacy + * @expectedDeprecation Command "%s:hidden" is hidden, finding it using an abbreviation is deprecated since Symfony 4.4, use its full name instead. + * @dataProvider provideAbbreviationsForHiddenCommands + */ + public function testFindHiddenWithAbbreviatedName($name) + { + $application = new Application(); + + $application->add(new \FooHiddenCommand()); + $application->add(new \BarHiddenCommand()); + + $application->find($name); + } + + public function provideAbbreviationsForHiddenCommands() + { + return [ + ['foo:hidde'], + ['afoohidd'], + ['bar:hidde'], + ]; + } + + public function testFindAmbiguousCommandsIfAllAlternativesAreHidden() + { + $application = new Application(); + + $application->add(new \FooCommand()); + $application->add(new \FooHiddenCommand()); + + $this->assertInstanceOf('FooCommand', $application->find('foo:')); + } + public function testSetCatchExceptions() { $application = new Application(); diff --git a/src/Symfony/Component/Console/Tests/Fixtures/BarHiddenCommand.php b/src/Symfony/Component/Console/Tests/Fixtures/BarHiddenCommand.php new file mode 100644 index 0000000000..d500f8731f --- /dev/null +++ b/src/Symfony/Component/Console/Tests/Fixtures/BarHiddenCommand.php @@ -0,0 +1,21 @@ +setName('bar:hidden') + ->setAliases(['abarhidden']) + ->setHidden(true) + ; + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + } +}