From 01fe89e8ec13f71fc83a0638d0a1c8a410556a85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20TAMARELLE?= Date: Sun, 31 Oct 2021 14:01:31 +0100 Subject: [PATCH] [Framework] Add completion to debug:container --- .../Command/ContainerDebugCommand.php | 42 +++++++++++- .../Functional/ContainerDebugCommandTest.php | 65 +++++++++++++++++++ 2 files changed, 106 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/ContainerDebugCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/ContainerDebugCommand.php index 7f1688bda56f1..8dfebe4ae86f1 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Command/ContainerDebugCommand.php +++ b/src/Symfony/Bundle/FrameworkBundle/Command/ContainerDebugCommand.php @@ -13,6 +13,8 @@ use Symfony\Bundle\FrameworkBundle\Console\Helper\DescriptorHelper; use Symfony\Component\Console\Command\Command; +use Symfony\Component\Console\Completion\CompletionInput; +use Symfony\Component\Console\Completion\CompletionSuggestions; use Symfony\Component\Console\Exception\InvalidArgumentException; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; @@ -190,6 +192,44 @@ protected function execute(InputInterface $input, OutputInterface $output): int return 0; } + public function complete(CompletionInput $input, CompletionSuggestions $suggestions): void + { + if ($input->mustSuggestOptionValuesFor('format')) { + $helper = new DescriptorHelper(); + $suggestions->suggestValues($helper->getFormats()); + + return; + } + + $kernel = $this->getApplication()->getKernel(); + $object = $this->getContainerBuilder($kernel); + + if ($input->mustSuggestArgumentValuesFor('name') + && !$input->getOption('tag') && !$input->getOption('tags') + && !$input->getOption('parameter') && !$input->getOption('parameters') + && !$input->getOption('env-var') && !$input->getOption('env-vars') + && !$input->getOption('types') && !$input->getOption('deprecations') + ) { + $suggestions->suggestValues($this->findServiceIdsContaining( + $object, + $input->getCompletionValue(), + (bool) $input->getOption('show-hidden') + )); + + return; + } + + if ($input->mustSuggestOptionValuesFor('tag')) { + $suggestions->suggestValues($object->findTags()); + + return; + } + + if ($input->mustSuggestOptionValuesFor('parameter')) { + $suggestions->suggestValues(array_keys($object->getParameterBag()->all())); + } + } + /** * Validates input arguments and options. * @@ -245,7 +285,7 @@ private function findServiceIdsContaining(ContainerBuilder $builder, string $nam if (false !== stripos(str_replace('\\', '', $serviceId), $name)) { $foundServiceIdsIgnoringBackslashes[] = $serviceId; } - if (false !== stripos($serviceId, $name)) { + if ('' === $name || false !== stripos($serviceId, $name)) { $foundServiceIds[] = $serviceId; } } diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/ContainerDebugCommandTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/ContainerDebugCommandTest.php index 60576fe9c7955..ff2cc045b7ac1 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/ContainerDebugCommandTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/ContainerDebugCommandTest.php @@ -14,6 +14,7 @@ use Symfony\Bundle\FrameworkBundle\Console\Application; use Symfony\Bundle\FrameworkBundle\Tests\Fixtures\BackslashClass; use Symfony\Component\Console\Tester\ApplicationTester; +use Symfony\Component\Console\Tester\CommandCompletionTester; /** * @group functional @@ -211,4 +212,68 @@ public function provideIgnoreBackslashWhenFindingService() ['\\'.BackslashClass::class], ]; } + + /** + * @dataProvider provideCompletionSuggestions + */ + public function testComplete(array $input, array $expectedSuggestions, array $notExpectedSuggestions = []) + { + static::bootKernel(['test_case' => 'ContainerDebug', 'root_config' => 'config.yml', 'debug' => true]); + + $application = new Application(static::$kernel); + $tester = new CommandCompletionTester($application->find('debug:container')); + $suggestions = $tester->complete($input); + + foreach ($expectedSuggestions as $expectedSuggestion) { + $this->assertContains($expectedSuggestion, $suggestions); + } + foreach ($notExpectedSuggestions as $notExpectedSuggestion) { + $this->assertNotContains($notExpectedSuggestion, $suggestions); + } + } + + public function provideCompletionSuggestions() + { + $serviceId = 'console.command.container_debug'; + $hiddenServiceId = '.console.command.container_debug.lazy'; + $interfaceServiceId = 'Symfony\Component\HttpKernel\HttpKernelInterface'; + + yield 'name' => [ + [''], + [$serviceId, $interfaceServiceId], + [$hiddenServiceId], + ]; + + yield 'name (with hidden)' => [ + ['--show-hidden', ''], + [$serviceId, $interfaceServiceId, $hiddenServiceId], + ]; + + yield 'name (with current value)' => [ + ['--show-hidden', 'console'], + [$serviceId, $hiddenServiceId], + [$interfaceServiceId], + ]; + + yield 'name (no suggestion with --tags)' => [ + ['--tags', ''], + [], + [$serviceId, $interfaceServiceId, $hiddenServiceId], + ]; + + yield 'option --tag' => [ + ['--tag', ''], + ['console.command'], + ]; + + yield 'option --parameter' => [ + ['--parameter', ''], + ['kernel.debug'], + ]; + + yield 'option --format' => [ + ['--format', ''], + ['txt', 'xml', 'json', 'md'], + ]; + } }