Skip to content

[FrameworkBundle] Display aliases in debug:container command #54459

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ CHANGELOG
* Add `secrets:reveal` command
* Add `rate_limiter` option to `http_client.default_options` and `http_client.scoped_clients`
* Attach the workflow's configuration to the `workflow` tag
* Display aliases in `debug:container` command

7.0
---
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ protected function configure(): void
->setDefinition([
new InputArgument('name', InputArgument::OPTIONAL, 'A service name (foo)'),
new InputOption('show-arguments', null, InputOption::VALUE_NONE, 'Show arguments in services'),
new InputOption('with-aliases', null, InputOption::VALUE_NONE, 'Display aliases for a single service'),
new InputOption('show-hidden', null, InputOption::VALUE_NONE, 'Show hidden (internal) services'),
new InputOption('tag', null, InputOption::VALUE_REQUIRED, 'Show all services with a specific tag'),
new InputOption('tags', null, InputOption::VALUE_NONE, 'Display tagged services for an application'),
Expand Down Expand Up @@ -106,6 +107,10 @@ protected function configure(): void

<info>php %command.full_name% --show-hidden</info>

To list aliases, use the <info>--with-aliases</info> flag:

<info>php %command.full_name% --with-aliases</info>

EOF
)
;
Expand Down Expand Up @@ -159,6 +164,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
$helper = new DescriptorHelper();
$options['format'] = $input->getOption('format');
$options['show_arguments'] = $input->getOption('show-arguments');
$options['with_aliases'] = $input->getOption('with-aliases');
$options['show_hidden'] = $input->getOption('show-hidden');
$options['raw_text'] = $input->getOption('raw');
$options['output'] = $io;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ protected function describeContainerService(object $service, array $options = []
if ($service instanceof Alias) {
$this->describeContainerAlias($service, $options, $container);
} elseif ($service instanceof Definition) {
$this->writeData($this->getContainerDefinitionData($service, isset($options['omit_tags']) && $options['omit_tags'], isset($options['show_arguments']) && $options['show_arguments'], $container, $options['id']), $options);
$this->writeData($this->getContainerDefinitionData($service, isset($options['omit_tags']) && $options['omit_tags'], isset($options['show_arguments']) && $options['show_arguments'], $container, $options['id'], isset($options['with_aliases']) && $options['with_aliases']), $options);
} else {
$this->writeData($service::class, $options);
}
Expand All @@ -93,6 +93,7 @@ protected function describeContainerServices(ContainerBuilder $container, array
$showHidden = isset($options['show_hidden']) && $options['show_hidden'];
$omitTags = isset($options['omit_tags']) && $options['omit_tags'];
$showArguments = isset($options['show_arguments']) && $options['show_arguments'];
$withAliases = isset($options['with_aliases']) && $options['with_aliases'];
$data = ['definitions' => [], 'aliases' => [], 'services' => []];

if (isset($options['filter'])) {
Expand All @@ -112,7 +113,7 @@ protected function describeContainerServices(ContainerBuilder $container, array
if ($service->hasTag('container.excluded')) {
continue;
}
$data['definitions'][$serviceId] = $this->getContainerDefinitionData($service, $omitTags, $showArguments, $container, $serviceId);
$data['definitions'][$serviceId] = $this->getContainerDefinitionData($service, $omitTags, $showArguments, $container, $serviceId, $withAliases);
} else {
$data['services'][$serviceId] = $service::class;
}
Expand All @@ -123,7 +124,7 @@ protected function describeContainerServices(ContainerBuilder $container, array

protected function describeContainerDefinition(Definition $definition, array $options = [], ?ContainerBuilder $container = null): void
{
$this->writeData($this->getContainerDefinitionData($definition, isset($options['omit_tags']) && $options['omit_tags'], isset($options['show_arguments']) && $options['show_arguments'], $container, $options['id'] ?? null), $options);
$this->writeData($this->getContainerDefinitionData($definition, isset($options['omit_tags']) && $options['omit_tags'], isset($options['show_arguments']) && $options['show_arguments'], $container, $options['id'] ?? null, isset($options['with_aliases']) && $options['with_aliases']), $options);
}

protected function describeContainerAlias(Alias $alias, array $options = [], ?ContainerBuilder $container = null): void
Expand All @@ -135,7 +136,7 @@ protected function describeContainerAlias(Alias $alias, array $options = [], ?Co
}

$this->writeData(
[$this->getContainerAliasData($alias), $this->getContainerDefinitionData($container->getDefinition((string) $alias), isset($options['omit_tags']) && $options['omit_tags'], isset($options['show_arguments']) && $options['show_arguments'], $container, (string) $alias)],
[$this->getContainerAliasData($alias), $this->getContainerDefinitionData($container->getDefinition((string) $alias), isset($options['omit_tags']) && $options['omit_tags'], isset($options['show_arguments']) && $options['show_arguments'], $container, (string) $alias, isset($options['with_aliases']) && $options['with_aliases'])],
array_merge($options, ['id' => (string) $alias])
);
}
Expand Down Expand Up @@ -245,7 +246,7 @@ protected function sortParameters(ParameterBag $parameters): array
return $sortedParameters;
}

private function getContainerDefinitionData(Definition $definition, bool $omitTags = false, bool $showArguments = false, ?ContainerBuilder $container = null, ?string $id = null): array
private function getContainerDefinitionData(Definition $definition, bool $omitTags = false, bool $showArguments = false, ?ContainerBuilder $container = null, ?string $id = null, bool $withAliases = false): array
{
$data = [
'class' => (string) $definition->getClass(),
Expand All @@ -270,7 +271,7 @@ private function getContainerDefinitionData(Definition $definition, bool $omitTa
}

if ($showArguments) {
$data['arguments'] = $this->describeValue($definition->getArguments(), $omitTags, $showArguments, $container, $id);
$data['arguments'] = $this->describeValue($definition->getArguments(), $omitTags, $showArguments, $container, $id, $withAliases);
}

$data['file'] = $definition->getFile();
Expand Down Expand Up @@ -418,12 +419,12 @@ private function getCallableData(mixed $callable): array
throw new \InvalidArgumentException('Callable is not describable.');
}

private function describeValue($value, bool $omitTags, bool $showArguments, ?ContainerBuilder $container = null, ?string $id = null): mixed
private function describeValue($value, bool $omitTags, bool $showArguments, ?ContainerBuilder $container = null, ?string $id = null, bool $withAliases = false): mixed
{
if (\is_array($value)) {
$data = [];
foreach ($value as $k => $v) {
$data[$k] = $this->describeValue($v, $omitTags, $showArguments, $container, $id);
$data[$k] = $this->describeValue($v, $omitTags, $showArguments, $container, $id, $withAliases);
}

return $data;
Expand All @@ -434,10 +435,20 @@ private function describeValue($value, bool $omitTags, bool $showArguments, ?Con
}

if ($value instanceof Reference) {
return [
'type' => 'service',
'id' => (string) $value,
];
$node = $container?->getCompiler()->getServiceReferenceGraph()->getNode((string) $value);

if ($withAliases && $node?->getValue()?->getClass()) {
return [
'type' => 'service',
'id' => (string) $value,
'alias' => $node->getValue()->getClass(),
];
} else {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no need for the "else"

return [
'type' => 'service',
'id' => (string) $value,
];
}
}

if ($value instanceof AbstractArgument) {
Expand All @@ -449,7 +460,7 @@ private function describeValue($value, bool $omitTags, bool $showArguments, ?Con
}

if ($value instanceof Definition) {
return $this->getContainerDefinitionData($value, $omitTags, $showArguments, $container, $id);
return $this->getContainerDefinitionData($value, $omitTags, $showArguments, $container, $id, $withAliases);
}

return $value;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,17 @@ protected function describeContainerDefinition(Definition $definition, array $op
}

if (isset($options['show_arguments']) && $options['show_arguments']) {
$output .= "\n".'- Arguments: '.($definition->getArguments() ? 'yes' : 'no');
if ($definition->getArguments()) {
foreach ($definition->getArguments() as $argument) {
$output .= "\n".'- Argument: `'.$argument.'`';
if (isset($options['with_aliases']) && $options['with_aliases']) {
$node = $container?->getCompiler()?->getServiceReferenceGraph()?->getNode((string) $argument);
$output .= "\n".' - Alias: '.$node?->getValue()?->getClass();
}
}
} else {
$output .= "\n".'- Arguments: no';
}
}

if ($definition->getFile()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -352,14 +352,23 @@ protected function describeContainerDefinition(Definition $definition, array $op
}

$showArguments = isset($options['show_arguments']) && $options['show_arguments'];
$withAliases = isset($options['with_aliases']) && $options['with_aliases'];
$argumentsInformation = [];
if ($showArguments && ($arguments = $definition->getArguments())) {
foreach ($arguments as $argument) {
if ($argument instanceof ServiceClosureArgument) {
$argument = $argument->getValues()[0];
}
if ($argument instanceof Reference) {
$argumentsInformation[] = sprintf('Service(%s)', (string) $argument);
$node = $container?->getCompiler()?->getServiceReferenceGraph()?->getNode((string) $argument);
if ($withAliases && $node?->getValue()?->getClass()) {
$argumentsInformation[] = vsprintf('Alias(%s, Service(%s))', [
$node->getValue()->getClass(),
(string) $argument,
]);
} else {
$argumentsInformation[] = sprintf('Service(%s)', (string) $argument);
}
} elseif ($argument instanceof IteratorArgument) {
if ($argument instanceof TaggedIteratorArgument) {
$argumentsInformation[] = sprintf('Tagged Iterator for "%s"%s', $argument->getTag(), $options['is_debug'] ? '' : sprintf(' (%d element(s))', \count($argument->getValues())));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,17 +59,17 @@ protected function describeContainerService(object $service, array $options = []
throw new \InvalidArgumentException('An "id" option must be provided.');
}

$this->writeDocument($this->getContainerServiceDocument($service, $options['id'], $container, isset($options['show_arguments']) && $options['show_arguments']));
$this->writeDocument($this->getContainerServiceDocument($service, $options['id'], $container, isset($options['show_arguments']) && $options['show_arguments'], isset($options['with_aliases']) && $options['with_aliases']));
}

protected function describeContainerServices(ContainerBuilder $container, array $options = []): void
{
$this->writeDocument($this->getContainerServicesDocument($container, $options['tag'] ?? null, isset($options['show_hidden']) && $options['show_hidden'], isset($options['show_arguments']) && $options['show_arguments'], $options['filter'] ?? null, $options['id'] ?? null));
$this->writeDocument($this->getContainerServicesDocument($container, $options['tag'] ?? null, isset($options['show_hidden']) && $options['show_hidden'], isset($options['show_arguments']) && $options['show_arguments'], $options['filter'] ?? null, $options['id'] ?? null, isset($options['with_aliases']) && $options['with_aliases']));
}

protected function describeContainerDefinition(Definition $definition, array $options = [], ?ContainerBuilder $container = null): void
{
$this->writeDocument($this->getContainerDefinitionDocument($definition, $options['id'] ?? null, isset($options['omit_tags']) && $options['omit_tags'], isset($options['show_arguments']) && $options['show_arguments'], $container));
$this->writeDocument($this->getContainerDefinitionDocument($definition, $options['id'] ?? null, isset($options['omit_tags']) && $options['omit_tags'], isset($options['show_arguments']) && $options['show_arguments'], $container, isset($options['with_aliases']) && $options['with_aliases']));
}

protected function describeContainerAlias(Alias $alias, array $options = [], ?ContainerBuilder $container = null): void
Expand Down Expand Up @@ -268,17 +268,17 @@ private function getContainerTagsDocument(ContainerBuilder $container, bool $sho
return $dom;
}

private function getContainerServiceDocument(object $service, string $id, ?ContainerBuilder $container = null, bool $showArguments = false): \DOMDocument
private function getContainerServiceDocument(object $service, string $id, ?ContainerBuilder $container = null, bool $showArguments = false, bool $withAliases = false): \DOMDocument
{
$dom = new \DOMDocument('1.0', 'UTF-8');

if ($service instanceof Alias) {
$dom->appendChild($dom->importNode($this->getContainerAliasDocument($service, $id)->childNodes->item(0), true));
if ($container) {
$dom->appendChild($dom->importNode($this->getContainerDefinitionDocument($container->getDefinition((string) $service), (string) $service, false, $showArguments, $container)->childNodes->item(0), true));
$dom->appendChild($dom->importNode($this->getContainerDefinitionDocument($container->getDefinition((string) $service), (string) $service, false, $showArguments, $container, $withAliases)->childNodes->item(0), true));
}
} elseif ($service instanceof Definition) {
$dom->appendChild($dom->importNode($this->getContainerDefinitionDocument($service, $id, false, $showArguments, $container)->childNodes->item(0), true));
$dom->appendChild($dom->importNode($this->getContainerDefinitionDocument($service, $id, false, $showArguments, $container, $withAliases)->childNodes->item(0), true));
} else {
$dom->appendChild($serviceXML = $dom->createElement('service'));
$serviceXML->setAttribute('id', $id);
Expand All @@ -288,7 +288,7 @@ private function getContainerServiceDocument(object $service, string $id, ?Conta
return $dom;
}

private function getContainerServicesDocument(ContainerBuilder $container, ?string $tag = null, bool $showHidden = false, bool $showArguments = false, ?callable $filter = null, ?string $id = null): \DOMDocument
private function getContainerServicesDocument(ContainerBuilder $container, ?string $tag = null, bool $showHidden = false, bool $showArguments = false, ?callable $filter = null, ?string $id = null, bool $withAliases = false): \DOMDocument
{
$dom = new \DOMDocument('1.0', 'UTF-8');
$dom->appendChild($containerXML = $dom->createElement('container'));
Expand All @@ -311,14 +311,14 @@ private function getContainerServicesDocument(ContainerBuilder $container, ?stri
continue;
}

$serviceXML = $this->getContainerServiceDocument($service, $serviceId, null, $showArguments);
$serviceXML = $this->getContainerServiceDocument($service, $serviceId, null, $showArguments, $withAliases);
$containerXML->appendChild($containerXML->ownerDocument->importNode($serviceXML->childNodes->item(0), true));
}

return $dom;
}

private function getContainerDefinitionDocument(Definition $definition, ?string $id = null, bool $omitTags = false, bool $showArguments = false, ?ContainerBuilder $container = null): \DOMDocument
private function getContainerDefinitionDocument(Definition $definition, ?string $id = null, bool $omitTags = false, bool $showArguments = false, ?ContainerBuilder $container = null, bool $withAliases = false): \DOMDocument
{
$dom = new \DOMDocument('1.0', 'UTF-8');
$dom->appendChild($serviceXML = $dom->createElement('definition'));
Expand Down Expand Up @@ -379,7 +379,7 @@ private function getContainerDefinitionDocument(Definition $definition, ?string
}

if ($showArguments) {
foreach ($this->getArgumentNodes($definition->getArguments(), $dom, $container) as $node) {
foreach ($this->getArgumentNodes($definition->getArguments(), $dom, $container, $withAliases) as $node) {
$serviceXML->appendChild($node);
}
}
Expand Down Expand Up @@ -418,7 +418,7 @@ private function getContainerDefinitionDocument(Definition $definition, ?string
/**
* @return \DOMNode[]
*/
private function getArgumentNodes(array $arguments, \DOMDocument $dom, ?ContainerBuilder $container = null): array
private function getArgumentNodes(array $arguments, \DOMDocument $dom, ?ContainerBuilder $container = null, bool $withAliases = false): array
{
$nodes = [];

Expand All @@ -434,23 +434,29 @@ private function getArgumentNodes(array $arguments, \DOMDocument $dom, ?Containe
}

if ($argument instanceof Reference) {
$node = $container?->getCompiler()?->getServiceReferenceGraph()?->getNode((string) $argument);

if ($withAliases && $node?->getValue()?->getClass()) {
$argumentXML->setAttribute('alias', $node->getValue()->getClass());
}

$argumentXML->setAttribute('type', 'service');
$argumentXML->setAttribute('id', (string) $argument);
} elseif ($argument instanceof IteratorArgument || $argument instanceof ServiceLocatorArgument) {
$argumentXML->setAttribute('type', $argument instanceof IteratorArgument ? 'iterator' : 'service_locator');

foreach ($this->getArgumentNodes($argument->getValues(), $dom, $container) as $childArgumentXML) {
foreach ($this->getArgumentNodes($argument->getValues(), $dom, $container, $withAliases) as $childArgumentXML) {
$argumentXML->appendChild($childArgumentXML);
}
} elseif ($argument instanceof Definition) {
$argumentXML->appendChild($dom->importNode($this->getContainerDefinitionDocument($argument, null, false, true, $container)->childNodes->item(0), true));
$argumentXML->appendChild($dom->importNode($this->getContainerDefinitionDocument($argument, null, false, true, $container, $withAliases)->childNodes->item(0), true));
} elseif ($argument instanceof AbstractArgument) {
$argumentXML->setAttribute('type', 'abstract');
$argumentXML->appendChild(new \DOMText($argument->getText()));
} elseif (\is_array($argument)) {
$argumentXML->setAttribute('type', 'collection');

foreach ($this->getArgumentNodes($argument, $dom, $container) as $childArgumentXML) {
foreach ($this->getArgumentNodes($argument, $dom, $container, $withAliases) as $childArgumentXML) {
$argumentXML->appendChild($childArgumentXML);
}
} elseif ($argument instanceof \UnitEnum) {
Expand Down