Skip to content

Commit 3fc23b6

Browse files
committed
feature #47311 [FrameworkBundle] Update ContainerDebugCommand to add parial search for tags (vshevelev, BOB41K1987)
This PR was squashed before being merged into the 6.2 branch. Discussion ---------- [FrameworkBundle] Update ContainerDebugCommand to add parial search for tags | Q | A | ------------- | --- | Branch? | 6.2 | Bug fix? | no | New feature? | yes | Deprecations? | no | Tickets | | License | MIT | Doc PR | symfony/symfony-docs#17201 As of now, the `debug:container` command allows the use of partial search for the service name but doesn't allow the partial search for `tags`. It can be especially useful when using with `#[AutoconfigureTag]` attribute when the class FQN becomes a tag. ``` namespace App\SomeBundle\SomeService\Inerfaces; use Symfony\Component\DependencyInjection\Attribute\AutoconfigureTag; #[AutoconfigureTag] interface SomeInterface{} ``` As of now, to find the services tagged with this interface we need to execute `bin/console debug:container --tag=App\\SomeBundle\\SomeService\\Inerfaces\\SomeInterface` which looks a bit overwhelming. This PR allows to search simply by `bin/console debug:container --tag=SomeInterface` which is much simpler. In case there are multiple tags containing the string, the command will allow choosing the one the user is looking for: ``` bin/console debug:container --tag=kernel Select one of the following tags to display its information: [0] kernel.event_listener [1] kernel.event_subscriber [2] kernel.reset [3] kernel.cache_warmer [4] kernel.locale_aware [5] kernel.fragment_renderer [6] kernel.cache_clearer ``` Commits ------- b301d92686 [FrameworkBundle] Update ContainerDebugCommand to add parial search for tags
2 parents 95c5798 + 57d107c commit 3fc23b6

File tree

2 files changed

+53
-0
lines changed

2 files changed

+53
-0
lines changed

Command/ContainerDebugCommand.php

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
139139
} elseif ($input->getOption('tags')) {
140140
$options = ['group_by' => 'tags'];
141141
} elseif ($tag = $input->getOption('tag')) {
142+
$tag = $this->findProperTagName($input, $errorIo, $object, $tag);
142143
$options = ['tag' => $tag];
143144
} elseif ($name = $input->getArgument('name')) {
144145
$name = $this->findProperServiceName($input, $errorIo, $object, $name, $input->getOption('show-hidden'));
@@ -281,6 +282,24 @@ private function findProperServiceName(InputInterface $input, SymfonyStyle $io,
281282
return $io->choice('Select one of the following services to display its information', $matchingServices);
282283
}
283284

285+
private function findProperTagName(InputInterface $input, SymfonyStyle $io, ContainerBuilder $builder, string $tagName): string
286+
{
287+
if (\in_array($tagName, $builder->findTags(), true) || !$input->isInteractive()) {
288+
return $tagName;
289+
}
290+
291+
$matchingTags = $this->findTagsContaining($builder, $tagName);
292+
if (!$matchingTags) {
293+
throw new InvalidArgumentException(sprintf('No tags found that match "%s".', $tagName));
294+
}
295+
296+
if (1 === \count($matchingTags)) {
297+
return $matchingTags[0];
298+
}
299+
300+
return $io->choice('Select one of the following tags to display its information', $matchingTags);
301+
}
302+
284303
private function findServiceIdsContaining(ContainerBuilder $builder, string $name, bool $showHidden): array
285304
{
286305
$serviceIds = $builder->getServiceIds();
@@ -300,6 +319,19 @@ private function findServiceIdsContaining(ContainerBuilder $builder, string $nam
300319
return $foundServiceIds ?: $foundServiceIdsIgnoringBackslashes;
301320
}
302321

322+
private function findTagsContaining(ContainerBuilder $builder, string $tagName): array
323+
{
324+
$tags = $builder->findTags();
325+
$foundTags = [];
326+
foreach ($tags as $tag) {
327+
if (str_contains($tag, $tagName)) {
328+
$foundTags[] = $tag;
329+
}
330+
}
331+
332+
return $foundTags;
333+
}
334+
303335
/**
304336
* @internal
305337
*/

Tests/Functional/ContainerDebugCommandTest.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,27 @@ public function testIgnoreBackslashWhenFindingService(string $validServiceId)
100100
$this->assertStringNotContainsString('No services found', $tester->getDisplay());
101101
}
102102

103+
public function testTagsPartialSearch()
104+
{
105+
static::bootKernel(['test_case' => 'ContainerDebug', 'root_config' => 'config.yml']);
106+
107+
$application = new Application(static::$kernel);
108+
$application->setAutoExit(false);
109+
110+
$tester = new ApplicationTester($application);
111+
$tester->setInputs(['0']);
112+
$tester->run(['command' => 'debug:container', '--tag' => 'kernel.']);
113+
114+
$this->assertStringContainsString('Select one of the following tags to display its information', $tester->getDisplay());
115+
$this->assertStringContainsString('[0] kernel.event_subscriber', $tester->getDisplay());
116+
$this->assertStringContainsString('[1] kernel.locale_aware', $tester->getDisplay());
117+
$this->assertStringContainsString('[2] kernel.cache_warmer', $tester->getDisplay());
118+
$this->assertStringContainsString('[3] kernel.fragment_renderer', $tester->getDisplay());
119+
$this->assertStringContainsString('[4] kernel.reset', $tester->getDisplay());
120+
$this->assertStringContainsString('[5] kernel.cache_clearer', $tester->getDisplay());
121+
$this->assertStringContainsString('Symfony Container Services Tagged with "kernel.event_subscriber" Tag', $tester->getDisplay());
122+
}
123+
103124
public function testDescribeEnvVars()
104125
{
105126
putenv('REAL=value');

0 commit comments

Comments
 (0)