[Config][FrameworkBundle] Allow to dump extension config reference sub path

This commit is contained in:
Maxime STEINHAUSSER 2016-11-29 17:47:25 +01:00 committed by Maxime Steinhausser
parent 9e6d6ba3a9
commit 869bb1530b
6 changed files with 146 additions and 4 deletions

View File

@ -37,6 +37,7 @@ class ConfigDumpReferenceCommand extends AbstractConfigCommand
->setName('config:dump-reference')
->setDefinition(array(
new InputArgument('name', InputArgument::OPTIONAL, 'The Bundle name or the extension alias'),
new InputArgument('path', InputArgument::OPTIONAL, 'The configuration option path'),
new InputOption('format', null, InputOption::VALUE_REQUIRED, 'The output format (yaml or xml)', 'yaml'),
))
->setDescription('Dumps the default configuration for an extension')
@ -54,6 +55,10 @@ this is either <comment>yaml</comment> or <comment>xml</comment>.
When the option is not provided, <comment>yaml</comment> is used.
<info>php %command.full_name% FrameworkBundle --format=xml</info>
For dumping a specific option, add its path as second argument (only available for the yaml format):
<info>php %command.full_name% framework profiler.matcher</info>
EOF
)
@ -71,7 +76,10 @@ EOF
if (null === $name = $input->getArgument('name')) {
$this->listBundles($io);
$io->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>)');
$io->comment(array(
'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)',
));
return;
}
@ -82,13 +90,26 @@ EOF
$this->validateConfiguration($extension, $configuration);
$format = $input->getOption('format');
$path = $input->getArgument('path');
if ($path !== null && 'yaml' !== $format) {
$io->error('The "path" option is only available for the "yaml" format.');
return 1;
}
if ($name === $extension->getAlias()) {
$message = sprintf('Default configuration for extension with alias: "%s"', $name);
} else {
$message = sprintf('Default configuration for "%s"', $name);
}
switch ($input->getOption('format')) {
if ($path !== null) {
$message .= sprintf(' at path "%s"', $path);
}
switch ($format) {
case 'yaml':
$io->writeln(sprintf('# %s', $message));
$dumper = new YamlReferenceDumper();
@ -102,6 +123,6 @@ EOF
throw new \InvalidArgumentException('Only the yaml and xml formats are supported.');
}
$io->writeln($dumper->dump($configuration, $extension->getNamespace()));
$io->writeln(null === $path ? $dumper->dump($configuration, $extension->getNamespace()) : $dumper->dumpAtPath($configuration, $path));
}
}

View File

@ -18,6 +18,13 @@ class CustomConfig
$rootNode
->children()
->scalarNode('custom')->end()
->arrayNode('array')
->children()
->scalarNode('child1')->end()
->scalarNode('child2')->end()
->end()
->end()
->end()
->end()
;
}

View File

@ -40,6 +40,39 @@ class ConfigDumpReferenceCommandTest extends WebTestCase
$this->assertContains(' custom:', $tester->getDisplay());
}
public function testDumpAtPath()
{
$tester = $this->createCommandTester();
$ret = $tester->execute(array(
'name' => 'test',
'path' => 'array',
));
$this->assertSame(0, $ret, 'Returns 0 in case of success');
$this->assertSame(<<<'EOL'
# Default configuration for extension with alias: "test" at path "array"
array:
child1: ~
child2: ~
EOL
, $tester->getDisplay(true));
}
public function testDumpAtPathXml()
{
$tester = $this->createCommandTester();
$ret = $tester->execute(array(
'name' => 'test',
'path' => 'array',
'--format' => 'xml',
));
$this->assertSame(1, $ret);
$this->assertContains('[ERROR] The "path" option is only available for the "yaml" format.', $tester->getDisplay());
}
/**
* @return CommandTester
*/

View File

@ -20,7 +20,7 @@
"symfony/cache": "~3.3",
"symfony/class-loader": "~3.2",
"symfony/dependency-injection": "~3.3",
"symfony/config": "~2.8|~3.0",
"symfony/config": "~3.3",
"symfony/event-dispatcher": "~2.8|~3.0",
"symfony/http-foundation": "~3.1",
"symfony/http-kernel": "~3.3",

View File

@ -33,6 +33,32 @@ class YamlReferenceDumper
return $this->dumpNode($configuration->getConfigTreeBuilder()->buildTree());
}
public function dumpAtPath(ConfigurationInterface $configuration, $path)
{
$rootNode = $node = $configuration->getConfigTreeBuilder()->buildTree();
foreach (explode('.', $path) as $step) {
if (!$node instanceof ArrayNode) {
throw new \UnexpectedValueException(sprintf('Unable to find node at path "%s.%s"', $rootNode->getName(), $path));
}
/** @var NodeInterface[] $children */
$children = $node instanceof PrototypedArrayNode ? $this->getPrototypeChildren($node) : $node->getChildren();
foreach ($children as $child) {
if ($child->getName() === $step) {
$node = $child;
continue 2;
}
}
throw new \UnexpectedValueException(sprintf('Unable to find node at path "%s.%s"', $rootNode->getName(), $path));
}
return $this->dumpNode($node);
}
public function dumpNode(NodeInterface $node)
{
$this->reference = '';

View File

@ -25,6 +25,61 @@ class YamlReferenceDumperTest extends \PHPUnit_Framework_TestCase
$this->assertEquals($this->getConfigurationAsString(), $dumper->dump($configuration));
}
public function provideDumpAtPath()
{
return array(
'Regular node' => array('scalar_true', <<<EOL
scalar_true: true
EOL
),
'Array node' => array('array', <<<EOL
# some info
array:
child1: ~
child2: ~
# this is a long
# multi-line info text
# which should be indented
child3: ~ # Example: example setting
EOL
),
'Regular nested' => array('array.child2', <<<EOL
child2: ~
EOL
),
'Prototype' => array('cms_pages.page', <<<EOL
# Prototype
page:
# Prototype
locale:
title: ~ # Required
path: ~ # Required
EOL
),
'Nested prototype' => array('cms_pages.page.locale', <<<EOL
# Prototype
locale:
title: ~ # Required
path: ~ # Required
EOL
),
);
}
/**
* @dataProvider provideDumpAtPath
*/
public function testDumpAtPath($path, $expected)
{
$configuration = new ExampleConfiguration();
$dumper = new YamlReferenceDumper();
$this->assertSame(trim($expected), trim($dumper->dumpAtPath($configuration, $path)));
}
private function getConfigurationAsString()
{
return <<<'EOL'