[FrameworkBundle] Dump kernel extension configuration

This commit is contained in:
Guillaume Pédelagrabe 2020-03-24 11:12:36 +01:00 committed by Nicolas Grekas
parent 8e47e9f850
commit 2ccafb1eb3
7 changed files with 94 additions and 4 deletions

View File

@ -16,6 +16,7 @@ CHANGELOG
* Added tag `routing.expression_language_function` to define functions available in route conditions
* Added `debug:container --deprecations` option to see compile-time deprecations.
* Made `BrowserKitAssertionsTrait` report the original error message in case of a failure
* Added ability for `config:dump-reference` and `debug:config` to dump and debug kernel container extension configuration.
5.0.0
-----

View File

@ -16,6 +16,7 @@ use Symfony\Component\Console\Exception\LogicException;
use Symfony\Component\Console\Helper\Table;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\StyleInterface;
use Symfony\Component\DependencyInjection\Extension\ConfigurationExtensionInterface;
use Symfony\Component\DependencyInjection\Extension\ExtensionInterface;
/**
@ -64,6 +65,22 @@ abstract class AbstractConfigCommand extends ContainerDebugCommand
$bundles = $this->initializeBundles();
$minScore = INF;
$kernel = $this->getApplication()->getKernel();
if ($kernel instanceof ExtensionInterface && ($kernel instanceof ConfigurationInterface || $kernel instanceof ConfigurationExtensionInterface)) {
if ($name === $kernel->getAlias()) {
return $kernel;
}
if ($kernel->getAlias()) {
$distance = levenshtein($name, $kernel->getAlias());
if ($distance < $minScore) {
$guess = $kernel->getAlias();
$minScore = $distance;
}
}
}
foreach ($bundles as $bundle) {
if ($name === $bundle->getName()) {
if (!$bundle->getContainerExtension()) {

View File

@ -11,6 +11,7 @@
namespace Symfony\Bundle\FrameworkBundle\Command;
use Symfony\Component\Config\Definition\ConfigurationInterface;
use Symfony\Component\Console\Exception\LogicException;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
@ -18,6 +19,8 @@ use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use Symfony\Component\DependencyInjection\Compiler\ValidateEnvPlaceholdersPass;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Extension\ConfigurationExtensionInterface;
use Symfony\Component\DependencyInjection\Extension\ExtensionInterface;
use Symfony\Component\Yaml\Yaml;
/**
@ -70,6 +73,15 @@ EOF
if (null === $name = $input->getArgument('name')) {
$this->listBundles($errorIo);
$kernel = $this->getApplication()->getKernel();
if ($kernel instanceof ExtensionInterface
&& ($kernel instanceof ConfigurationInterface || $kernel instanceof ConfigurationExtensionInterface)
&& $kernel->getAlias()
) {
$errorIo->table(['Kernel Extension'], [[$kernel->getAlias()]]);
}
$errorIo->comment('Provide the name of a bundle as the first argument of this command to dump its configuration. (e.g. <comment>debug:config FrameworkBundle</comment>)');
$errorIo->comment('For dumping a specific option, add its path as the second argument of this command. (e.g. <comment>debug:config FrameworkBundle serializer</comment> to dump the <comment>framework.serializer</comment> configuration)');

View File

@ -11,6 +11,7 @@
namespace Symfony\Bundle\FrameworkBundle\Command;
use Symfony\Component\Config\Definition\ConfigurationInterface;
use Symfony\Component\Config\Definition\Dumper\XmlReferenceDumper;
use Symfony\Component\Config\Definition\Dumper\YamlReferenceDumper;
use Symfony\Component\Console\Exception\InvalidArgumentException;
@ -19,6 +20,8 @@ use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use Symfony\Component\DependencyInjection\Extension\ConfigurationExtensionInterface;
use Symfony\Component\DependencyInjection\Extension\ExtensionInterface;
/**
* A console command for dumping available configuration reference.
@ -81,6 +84,15 @@ EOF
if (null === $name = $input->getArgument('name')) {
$this->listBundles($errorIo);
$kernel = $this->getApplication()->getKernel();
if ($kernel instanceof ExtensionInterface
&& ($kernel instanceof ConfigurationInterface || $kernel instanceof ConfigurationExtensionInterface)
&& $kernel->getAlias()
) {
$errorIo->table(['Kernel Extension'], [[$kernel->getAlias()]]);
}
$errorIo->comment([
'Provide the name of a bundle as the first argument of this command to dump its default configuration. (e.g. <comment>config:dump-reference FrameworkBundle</comment>)',
'For dumping a specific option, add its path as the second argument of this command. (e.g. <comment>config:dump-reference FrameworkBundle profiler.matcher</comment> to dump the <comment>framework.profiler.matcher</comment> configuration)',
@ -91,7 +103,11 @@ EOF
$extension = $this->findExtension($name);
$configuration = $extension->getConfiguration([], $this->getContainerBuilder());
if ($extension instanceof ConfigurationInterface) {
$configuration = $extension;
} else {
$configuration = $extension->getConfiguration([], $this->getContainerBuilder());
}
$this->validateConfiguration($extension, $configuration);

View File

@ -30,6 +30,14 @@ class ConfigDumpReferenceCommandTest extends AbstractWebTestCase
$this->application->doRun(new ArrayInput([]), new NullOutput());
}
public function testDumpKernelExtension()
{
$tester = $this->createCommandTester();
$ret = $tester->execute(['name' => 'foo']);
$this->assertStringContainsString('foo:', $tester->getDisplay());
$this->assertStringContainsString(' bar', $tester->getDisplay());
}
public function testDumpBundleName()
{
$tester = $this->createCommandTester();

View File

@ -12,9 +12,12 @@
namespace Symfony\Bundle\FrameworkBundle\Tests\Functional\app;
use Psr\Log\NullLogger;
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
use Symfony\Component\Config\Definition\ConfigurationInterface;
use Symfony\Component\Config\Loader\LoaderInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Extension\ExtensionInterface;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\HttpKernel\Kernel;
@ -23,7 +26,7 @@ use Symfony\Component\HttpKernel\Kernel;
*
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
*/
class AppKernel extends Kernel
class AppKernel extends Kernel implements ExtensionInterface, ConfigurationInterface
{
private $varDir;
private $testCase;
@ -106,4 +109,32 @@ class AppKernel extends Kernel
return parent::getContainer();
}
public function getConfigTreeBuilder()
{
$treeBuilder = new TreeBuilder('foo');
$rootNode = $treeBuilder->getRootNode();
$rootNode->children()->scalarNode('foo')->defaultValue('bar')->end()->end();
return $treeBuilder;
}
public function load(array $configs, ContainerBuilder $container)
{
}
public function getNamespace()
{
return '';
}
public function getXsdValidationBasePath()
{
return false;
}
public function getAlias()
{
return 'foo';
}
}

View File

@ -12,6 +12,7 @@
namespace Symfony\Component\DependencyInjection\Compiler;
use Symfony\Component\Config\Definition\BaseNode;
use Symfony\Component\Config\Definition\ConfigurationInterface;
use Symfony\Component\Config\Definition\Processor;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Extension\ConfigurationExtensionInterface;
@ -68,14 +69,18 @@ class ValidateEnvPlaceholdersPass implements CompilerPassInterface
$processor = new Processor();
foreach ($extensions as $name => $extension) {
if (!$extension instanceof ConfigurationExtensionInterface || !$config = array_filter($container->getExtensionConfig($name))) {
if (!($extension instanceof ConfigurationExtensionInterface || $extension instanceof ConfigurationInterface)
|| !$config = array_filter($container->getExtensionConfig($name))
) {
// this extension has no semantic configuration or was not called
continue;
}
$config = $resolvingBag->resolveValue($config);
if (null === $configuration = $extension->getConfiguration($config, $container)) {
if ($extension instanceof ConfigurationInterface) {
$configuration = $extension;
} elseif (null === $configuration = $extension->getConfiguration($config, $container)) {
continue;
}