Skip to content

[FrameworkBundle] Add debug autoconfigure to the container debug command #26745

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
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ protected function configure()
new InputOption('parameter', null, InputOption::VALUE_REQUIRED, 'Displays a specific parameter for an application'),
new InputOption('parameters', null, InputOption::VALUE_NONE, 'Displays parameters for an application'),
new InputOption('types', null, InputOption::VALUE_NONE, 'Displays types (classes/interfaces) available in the container'),
new InputOption('autoconfigure', null, InputOption::VALUE_NONE, 'Displays autoconfiguration interfaces for an application'),
new InputOption('format', null, InputOption::VALUE_REQUIRED, 'The output format (txt, xml, json, or md)', 'txt'),
new InputOption('raw', null, InputOption::VALUE_NONE, 'To output raw description'),
))
Expand All @@ -71,6 +72,10 @@ protected function configure()
To see available types that can be used for autowiring, use the <info>--types</info> flag:

<info>php %command.full_name% --types</info>

To see available autoconfiguration interfaces, use the <info>--autoconfigure</info> flag:

<info>php %command.full_name% --autoconfigure</info>

By default, private services are hidden. You can display all services by
using the <info>--show-private</info> flag:
Expand Down Expand Up @@ -107,6 +112,9 @@ protected function execute(InputInterface $input, OutputInterface $output)
$errorIo = $io->getErrorStyle();

$this->validateInput($input);
if ($input->getOption('autoconfigure')) {
@unlink($this->getApplication()->getKernel()->getContainer()->getParameter('debug.container.dump'));
}
$object = $this->getContainerBuilder();

if ($input->getOption('types')) {
Expand All @@ -121,6 +129,8 @@ protected function execute(InputInterface $input, OutputInterface $output)
$options = array();
} elseif ($parameter = $input->getOption('parameter')) {
$options = array('parameter' => $parameter);
} elseif ($input->getOption('autoconfigure')) {
$options = array('autoconfigure' => true, 'show_private' => $input->getOption('show-private'));
} elseif ($input->getOption('tags')) {
$options = array('group_by' => 'tags', 'show_private' => $input->getOption('show-private'));
} elseif ($tag = $input->getOption('tag')) {
Expand All @@ -139,7 +149,7 @@ protected function execute(InputInterface $input, OutputInterface $output)
$options['output'] = $io;
$helper->describe($io, $object, $options);

if (!$input->getArgument('name') && !$input->getOption('tag') && !$input->getOption('parameter') && $input->isInteractive()) {
if (!$input->getArgument('name') && !$input->getOption('tag') && !$input->getOption('parameter') && !$input->getOption('autoconfigure') && $input->isInteractive()) {
if ($input->getOption('tags')) {
$errorIo->comment('To search for a specific tag, re-run this command with a search term. (e.g. <comment>debug:container --tag=form.type</comment>)');
} elseif ($input->getOption('parameters')) {
Expand All @@ -157,7 +167,7 @@ protected function execute(InputInterface $input, OutputInterface $output)
*/
protected function validateInput(InputInterface $input)
{
$options = array('tags', 'tag', 'parameters', 'parameter');
$options = array('tags', 'tag', 'parameters', 'parameter', 'autoconfigure');

$optionsCount = 0;
foreach ($options as $option) {
Expand All @@ -168,9 +178,9 @@ protected function validateInput(InputInterface $input)

$name = $input->getArgument('name');
if ((null !== $name) && ($optionsCount > 0)) {
throw new \InvalidArgumentException('The options tags, tag, parameters & parameter can not be combined with the service name argument.');
throw new \InvalidArgumentException('The options tags, tag, parameters, parameter & autoconfigure can not be combined with the service name argument.');
} elseif ((null === $name) && $optionsCount > 1) {
throw new \InvalidArgumentException('The options tags, tag, parameters & parameter can not be combined together.');
throw new \InvalidArgumentException('The options tags, tag, parameters, parameter & autoconfigure can not be combined together.');
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ public function describe(OutputInterface $output, $object, array $options = arra
case $object instanceof ParameterBag:
$this->describeContainerParameters($object, $options);
break;
case $object instanceof ContainerBuilder && isset($options['autoconfigure']) && true === $options['autoconfigure']:
$this->describeContainerAutoconfiguringTags($object, $options);
break;
case $object instanceof ContainerBuilder && isset($options['group_by']) && 'tags' === $options['group_by']:
$this->describeContainerTags($object, $options);
break;
Expand Down Expand Up @@ -120,6 +123,11 @@ abstract protected function describeContainerParameters(ParameterBag $parameters
*/
abstract protected function describeContainerTags(ContainerBuilder $builder, array $options = array());

/**
* Describes container autoconfiguring tags.
*/
abstract protected function describeContainerAutoconfiguringTags(ContainerBuilder $builder, array $options = array());

/**
* Describes a container service by its name.
*
Expand Down Expand Up @@ -265,6 +273,28 @@ protected function findDefinitionsByTag(ContainerBuilder $builder, $showPrivate)
return $definitions;
}

/**
* @param ContainerBuilder $builder
*
* @return array
*/
protected function getAutoconfiguredInstanceofByTag(ContainerBuilder $builder)
{
$autoconfiguredInstanceofByTag = array();

foreach ($builder->getAutoconfiguredInstanceof() as $key => $autoconfiguredInstanceof) {
foreach (array_keys($autoconfiguredInstanceof->getTags()) as $tag) {
if (!isset($autoconfiguredInstanceofByTag[$tag])) {
$autoconfiguredInstanceofByTag[$tag] = array($key);
} else {
$autoconfiguredInstanceofByTag[$tag][] = $key;
}
}
}

return $autoconfiguredInstanceofByTag;
}

protected function sortParameters(ParameterBag $parameters)
{
$parameters = $parameters->all();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,22 @@ protected function describeContainerTags(ContainerBuilder $builder, array $optio
$this->writeData($data, $options);
}

/**
* {@inheritdoc}
*/
protected function describeContainerAutoconfiguringTags(ContainerBuilder $builder, array $options = array())
{
$data = array();

$autoconfiguredInstanceofByTag = $this->getAutoconfiguredInstanceofByTag($builder);

foreach ($autoconfiguredInstanceofByTag as $tag => $autoconfiguredInstanceofList) {
$data[$tag] = $autoconfiguredInstanceofByTag[$tag];
}

$this->writeData($data, $options);
}

/**
* {@inheritdoc}
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,24 @@ protected function describeContainerTags(ContainerBuilder $builder, array $optio
}
}

/**
* {@inheritdoc}
*/
protected function describeContainerAutoconfiguringTags(ContainerBuilder $builder, array $options = array())
{
$this->write("Container autoconfiguring Tags\n==============================");

$autoconfiguredInstanceofByTag = $this->getAutoconfiguredInstanceofByTag($builder);

foreach ($autoconfiguredInstanceofByTag as $tag => $autoconfiguredInstanceofList) {
$this->write("\n\n".$tag."\n".str_repeat('-', strlen($tag)));
foreach ($autoconfiguredInstanceofList as $autoconfiguredInstanceof) {
$this->write("\n\n");
$this->write(sprintf('- %s', $autoconfiguredInstanceof));
}
}
}

/**
* {@inheritdoc}
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,21 @@ protected function describeContainerTags(ContainerBuilder $builder, array $optio
}
}

/**
* {@inheritdoc}
*/
protected function describeContainerAutoconfiguringTags(ContainerBuilder $builder, array $options = array())
{
$options['output']->title('Symfony Container Autoconfiguring Tags');

$autoconfiguredInstanceofByTag = $this->getAutoconfiguredInstanceofByTag($builder);

foreach ($autoconfiguredInstanceofByTag as $tag => $autoconfiguredInstanceofList) {
$options['output']->section(sprintf('"%s" tag', $tag));
$options['output']->listing($autoconfiguredInstanceofList);
}
}

/**
* {@inheritdoc}
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,14 @@ protected function describeContainerTags(ContainerBuilder $builder, array $optio
$this->writeDocument($this->getContainerTagsDocument($builder, isset($options['show_private']) && $options['show_private']));
}

/**
* {@inheritdoc}
*/
protected function describeContainerAutoconfiguringTags(ContainerBuilder $builder, array $options = array())
{
$this->writeDocument($this->getContainerAutoconfiguringTagsDocument($builder));
}

/**
* {@inheritdoc}
*/
Expand Down Expand Up @@ -141,7 +149,10 @@ private function writeDocument(\DOMDocument $dom)
$this->write($dom->saveXML());
}

private function getRouteCollectionDocument(RouteCollection $routes): \DOMDocument
/**
* @return \DOMDocument
*/
private function getRouteCollectionDocument(RouteCollection $routes)
{
$dom = new \DOMDocument('1.0', 'UTF-8');
$dom->appendChild($routesXML = $dom->createElement('routes'));
Expand Down Expand Up @@ -249,6 +260,26 @@ private function getContainerTagsDocument(ContainerBuilder $builder, bool $showP
return $dom;
}

private function getContainerAutoconfiguringTagsDocument(ContainerBuilder $builder): \DOMDocument
{
$dom = new \DOMDocument('1.0', 'UTF-8');
$dom->appendChild($containerXML = $dom->createElement('tags'));

$autoconfiguredInstanceofByTag = $this->getAutoconfiguredInstanceofByTag($builder);

foreach ($autoconfiguredInstanceofByTag as $tag => $autoconfiguredInstanceofList) {
$containerXML->appendChild($tagXML = $dom->createElement('tag'));
$tagXML->setAttribute('name', $tag);

foreach ($autoconfiguredInstanceofList as $autoconfiguredInstanceof) {
$tagXML->appendChild($autoconfiguredInstanceofXML = $dom->createElement('autoconfigured-instanceof'));
$autoconfiguredInstanceofXML->appendChild(new \DOMText($autoconfiguredInstanceof));
}
}

return $dom;
}

private function getContainerServiceDocument($service, string $id, ContainerBuilder $builder = null, bool $showArguments = false): \DOMDocument
{
$dom = new \DOMDocument('1.0', 'UTF-8');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,7 @@ private function getContainerBuilderDescriptionTestData(array $objects)
'tag1' => array('show_private' => true, 'tag' => 'tag1'),
'tags' => array('group_by' => 'tags', 'show_private' => true),
'arguments' => array('show_private' => false, 'show_arguments' => true),
'autoconfigure' => array('autoconfigure' => true),
);

$data = array();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ public static function getContainerBuilders()
$builder1 = new ContainerBuilder();
$builder1->setDefinitions(self::getContainerDefinitions());
$builder1->setAliases(self::getContainerAliases());
$builder1->registerForAutoconfiguration(AutoconfiguringInterface::class)->addTag('autoconfiguring_interface_tag');

return array('builder_1' => $builder1);
}
Expand Down Expand Up @@ -196,3 +197,7 @@ public function compile()
return new CompiledRoute('', '#PATH_REGEX#', array(), array(), '#HOST_REGEX#');
}
}

interface AutoconfiguringInterface
{
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"autoconfiguring_interface_tag": [
"Symfony\\Bundle\\FrameworkBundle\\Tests\\Console\\Descriptor\\AutoconfiguringInterface"
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Container autoconfiguring Tags
==============================

autoconfiguring_interface_tag
-----------------------------

- Symfony\Bundle\FrameworkBundle\Tests\Console\Descriptor\AutoconfiguringInterface
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Symfony Container Autoconfiguring Tags
======================================

"autoconfiguring_interface_tag" tag
-----------------------------------

* Symfony\Bundle\FrameworkBundle\Tests\Console\Descriptor\AutoconfiguringInterface
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<tags>
<tag name="autoconfiguring_interface_tag">
<autoconfigured-instanceof>Symfony\Bundle\FrameworkBundle\Tests\Console\Descriptor\AutoconfiguringInterface</autoconfigured-instanceof>
</tag>
</tags>