Permalink
Browse files

feature #27476 [Config] deprecate tree builders without root nodes (x…

…abbuh)

This PR was merged into the 4.2-dev branch.

Discussion
----------

[Config] deprecate tree builders without root nodes

| Q             | A
| ------------- | ---
| Branch?       | master
| Bug fix?      | no
| New feature?  | yes
| BC breaks?    | no
| Deprecations? | yes
| Tests pass?   | yes
| Fixed tickets |
| License       | MIT
| Doc PR        |

While reviewing #27472 I wondered if we really need support config trees without a root node. If we did not support it, users wouldn't create pseudo configuration classes when they were actually not needed.

Commits
-------

c2ce153 deprecate tree builders without root nodes
  • Loading branch information...
fabpot committed Jun 25, 2018
2 parents d871473 + c2ce153 commit 21a3439a29914236fdc62a49589df6a6d033a067
Showing with 110 additions and 77 deletions.
  1. +6 −0 UPGRADE-4.2.md
  2. +1 −0 UPGRADE-5.0.md
  3. +2 −3 src/Symfony/Bundle/DebugBundle/DependencyInjection/Configuration.php
  4. +2 −1 src/Symfony/Bundle/DebugBundle/composer.json
  5. +2 −2 src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php
  6. +2 −3 ...y/Bundle/FrameworkBundle/Tests/Functional/Bundle/TestBundle/DependencyInjection/Configuration.php
  7. +1 −1 src/Symfony/Bundle/FrameworkBundle/composer.json
  8. +2 −2 src/Symfony/Bundle/SecurityBundle/DependencyInjection/MainConfiguration.php
  9. +1 −0 src/Symfony/Bundle/SecurityBundle/composer.json
  10. +2 −2 src/Symfony/Bundle/TwigBundle/DependencyInjection/Configuration.php
  11. +1 −1 src/Symfony/Bundle/TwigBundle/composer.json
  12. +2 −3 src/Symfony/Bundle/WebProfilerBundle/DependencyInjection/Configuration.php
  13. +1 −2 src/Symfony/Bundle/WebProfilerBundle/composer.json
  14. +5 −0 src/Symfony/Component/Config/CHANGELOG.md
  15. +18 −0 src/Symfony/Component/Config/Definition/Builder/TreeBuilder.php
  16. +2 −2 src/Symfony/Component/Config/Tests/Definition/Builder/ExprBuilderTest.php
  17. +29 −24 src/Symfony/Component/Config/Tests/Definition/Builder/TreeBuilderTest.php
  18. +2 −2 src/Symfony/Component/Config/Tests/Definition/FinalizationTest.php
  19. +10 −10 src/Symfony/Component/Config/Tests/Definition/MergeTest.php
  20. +8 −8 src/Symfony/Component/Config/Tests/Definition/NormalizationTest.php
  21. +2 −3 src/Symfony/Component/Config/Tests/Fixtures/Configuration/ExampleConfiguration.php
  22. +2 −3 src/Symfony/Component/DependencyInjection/Tests/Compiler/MergeExtensionConfigurationPassTest.php
  23. +5 −3 src/Symfony/Component/DependencyInjection/Tests/Compiler/ValidateEnvPlaceholdersPassTest.php
  24. +2 −2 src/Symfony/Component/DependencyInjection/composer.json
@@ -25,6 +25,12 @@ Form
{{ form_widget(field) }}
{% endfor %}
```
Config
------
* Deprecated constructing a `TreeBuilder` without passing root node information.
Security
--------
@@ -9,6 +9,7 @@ Cache
Config
------
* Dropped support for constructing a `TreeBuilder` without passing root node information.
* Added the `getChildNodeDefinitions()` method to `ParentNodeDefinitionInterface`.
* The `Processor` class has been made final
@@ -26,10 +26,9 @@ class Configuration implements ConfigurationInterface
*/
public function getConfigTreeBuilder()
{
$treeBuilder = new TreeBuilder();
$rootNode = $treeBuilder->root('debug');
$treeBuilder = new TreeBuilder('debug');
$rootNode
$treeBuilder->getRootNode()
->children()
->integerNode('max_items')
->info('Max number of displayed items past the first level, -1 means no limit')
@@ -23,11 +23,12 @@
"symfony/var-dumper": "^4.1.1"
},
"require-dev": {
"symfony/config": "~3.4|~4.0",
"symfony/config": "~4.2",
"symfony/dependency-injection": "~3.4|~4.0",
"symfony/web-profiler-bundle": "~3.4|~4.0"
},
"conflict": {
"symfony/config": "<4.2",
"symfony/dependency-injection": "<3.4"
},
"suggest": {
@@ -54,8 +54,8 @@ public function __construct(bool $debug)
*/
public function getConfigTreeBuilder()
{
$treeBuilder = new TreeBuilder();
$rootNode = $treeBuilder->root('framework');
$treeBuilder = new TreeBuilder('framework');
$rootNode = $treeBuilder->getRootNode();
$rootNode
->beforeNormalization()
@@ -25,11 +25,10 @@ public function __construct($customConfig = null)
public function getConfigTreeBuilder()
{
$treeBuilder = new TreeBuilder();
$rootNode = $treeBuilder->root('test');
$treeBuilder = new TreeBuilder('test');
if ($this->customConfig) {
$this->customConfig->addConfiguration($rootNode);
$this->customConfig->addConfiguration($treeBuilder->getRootNode());
}
return $treeBuilder;
@@ -20,7 +20,7 @@
"ext-xml": "*",
"symfony/cache": "~3.4|~4.0",
"symfony/dependency-injection": "^4.1.1",
"symfony/config": "~3.4|~4.0",
"symfony/config": "~4.2",
"symfony/event-dispatcher": "^4.1",
"symfony/http-foundation": "^4.1",
"symfony/http-kernel": "^4.1",
@@ -41,8 +41,8 @@ public function __construct(array $factories, array $userProviderFactories)
*/
public function getConfigTreeBuilder()
{
$tb = new TreeBuilder();
$rootNode = $tb->root('security');
$tb = new TreeBuilder('security');
$rootNode = $tb->getRootNode();
$rootNode
->beforeNormalization()
@@ -18,6 +18,7 @@
"require": {
"php": "^7.1.3",
"ext-xml": "*",
"symfony/config": "^4.2",
"symfony/security": "~4.2",
"symfony/dependency-injection": "^3.4.3|^4.0.3",
"symfony/http-kernel": "^4.1"
@@ -29,8 +29,8 @@ class Configuration implements ConfigurationInterface
*/
public function getConfigTreeBuilder()
{
$treeBuilder = new TreeBuilder();
$rootNode = $treeBuilder->root('twig');
$treeBuilder = new TreeBuilder('twig');
$rootNode = $treeBuilder->getRootNode();
$rootNode
->children()
@@ -17,7 +17,7 @@
],
"require": {
"php": "^7.1.3",
"symfony/config": "~3.4|~4.0",
"symfony/config": "~4.2",
"symfony/twig-bridge": "^3.4.3|^4.0.3",
"symfony/http-foundation": "~4.1",
"symfony/http-kernel": "~4.1",
@@ -31,10 +31,9 @@ class Configuration implements ConfigurationInterface
*/
public function getConfigTreeBuilder()
{
$treeBuilder = new TreeBuilder();
$rootNode = $treeBuilder->root('web_profiler');
$treeBuilder = new TreeBuilder('web_profiler');
$rootNode
$treeBuilder->getRootNode()
->children()
->booleanNode('toolbar')->defaultFalse()->end()
->booleanNode('intercept_redirects')->defaultFalse()->end()
@@ -17,20 +17,19 @@
],
"require": {
"php": "^7.1.3",
"symfony/config": "^4.2",
"symfony/http-kernel": "~4.1",
"symfony/routing": "~3.4|~4.0",
"symfony/twig-bundle": "^3.4.3|^4.0.3",
"symfony/var-dumper": "~3.4|~4.0",
"twig/twig": "~1.34|~2.4"
},
"require-dev": {
"symfony/config": "~3.4|~4.0",
"symfony/console": "~3.4|~4.0",
"symfony/dependency-injection": "~3.4|~4.0",
"symfony/stopwatch": "~3.4|~4.0"
},
"conflict": {
"symfony/config": "<3.4",
"symfony/dependency-injection": "<3.4",
"symfony/event-dispatcher": "<3.4",
"symfony/var-dumper": "<3.4"
@@ -1,6 +1,11 @@
CHANGELOG
=========
4.2.0
-----
* deprecated constructing a `TreeBuilder` without passing root node information
4.1.0
-----
@@ -24,6 +24,15 @@ class TreeBuilder implements NodeParentInterface
protected $tree;
protected $root;
public function __construct(string $name = null, string $type = 'array', NodeBuilder $builder = null)
{
if (null === $name) {
@trigger_error('A tree builder without a root node is deprecated since Symfony 4.2 and will not be supported anymore in 5.0.', E_USER_DEPRECATED);
} else {
$this->root($name, $type, $builder);
}
}
/**
* Creates the root node.
*
@@ -42,6 +51,15 @@ public function root($name, $type = 'array', NodeBuilder $builder = null)
return $this->root = $builder->node($name, $type)->setParent($this);
}
public function getRootNode(): NodeDefinition
{
if (null === $this->root) {
throw new \RuntimeException(sprintf('Calling %s() before creating the root node is not supported, migrate to the new constructor signature instead.', __METHOD__));
}
return $this->root;
}
/**
* Builds the tree.
*
@@ -212,10 +212,10 @@ public function testEndThenPartNotSpecified()
*/
protected function getTestBuilder()
{
$builder = new TreeBuilder();
$builder = new TreeBuilder('test');
return $builder
->root('test')
->getRootNode()
->children()
->variableNode('key')
->validate()
@@ -19,10 +19,9 @@ class TreeBuilderTest extends TestCase
{
public function testUsingACustomNodeBuilder()
{
$builder = new TreeBuilder();
$root = $builder->root('custom', 'array', new CustomNodeBuilder());
$builder = new TreeBuilder('custom', 'array', new CustomNodeBuilder());
$nodeBuilder = $root->children();
$nodeBuilder = $builder->getRootNode()->children();
$this->assertInstanceOf('Symfony\Component\Config\Tests\Fixtures\Builder\NodeBuilder', $nodeBuilder);
@@ -33,49 +32,46 @@ public function testUsingACustomNodeBuilder()
public function testOverrideABuiltInNodeType()
{
$builder = new TreeBuilder();
$root = $builder->root('override', 'array', new CustomNodeBuilder());
$builder = new TreeBuilder('override', 'array', new CustomNodeBuilder());
$definition = $root->children()->variableNode('variable');
$definition = $builder->getRootNode()->children()->variableNode('variable');
$this->assertInstanceOf('Symfony\Component\Config\Tests\Fixtures\Builder\VariableNodeDefinition', $definition);
}
public function testAddANodeType()
{
$builder = new TreeBuilder();
$root = $builder->root('override', 'array', new CustomNodeBuilder());
$builder = new TreeBuilder('override', 'array', new CustomNodeBuilder());
$definition = $root->children()->barNode('variable');
$definition = $builder->getRootNode()->children()->barNode('variable');
$this->assertInstanceOf('Symfony\Component\Config\Tests\Fixtures\Builder\BarNodeDefinition', $definition);
}
public function testCreateABuiltInNodeTypeWithACustomNodeBuilder()
{
$builder = new TreeBuilder();
$root = $builder->root('builtin', 'array', new CustomNodeBuilder());
$builder = new TreeBuilder('builtin', 'array', new CustomNodeBuilder());
$definition = $root->children()->booleanNode('boolean');
$definition = $builder->getRootNode()->children()->booleanNode('boolean');
$this->assertInstanceOf('Symfony\Component\Config\Definition\Builder\BooleanNodeDefinition', $definition);
}
public function testPrototypedArrayNodeUseTheCustomNodeBuilder()
{
$builder = new TreeBuilder();
$root = $builder->root('override', 'array', new CustomNodeBuilder());
$builder = new TreeBuilder('override', 'array', new CustomNodeBuilder());
$root = $builder->getRootNode();
$root->prototype('bar')->end();
$this->assertInstanceOf('Symfony\Component\Config\Tests\Fixtures\BarNode', $root->getNode(true)->getPrototype());
}
public function testAnExtendedNodeBuilderGetsPropagatedToTheChildren()
{
$builder = new TreeBuilder();
$builder = new TreeBuilder('propagation');
$builder->root('propagation')
$builder->getRootNode()
->children()
->setNodeClass('extended', 'Symfony\Component\Config\Definition\Builder\BooleanNodeDefinition')
->node('foo', 'extended')->end()
@@ -99,9 +95,9 @@ public function testAnExtendedNodeBuilderGetsPropagatedToTheChildren()
public function testDefinitionInfoGetsTransferredToNode()
{
$builder = new TreeBuilder();
$builder = new TreeBuilder('test');
$builder->root('test')->info('root info')
$builder->getRootNode()->info('root info')
->children()
->node('child', 'variable')->info('child info')->defaultValue('default')
->end()
@@ -116,9 +112,9 @@ public function testDefinitionInfoGetsTransferredToNode()
public function testDefinitionExampleGetsTransferredToNode()
{
$builder = new TreeBuilder();
$builder = new TreeBuilder('test');
$builder->root('test')
$builder->getRootNode()
->example(array('key' => 'value'))
->children()
->node('child', 'variable')->info('child info')->defaultValue('default')->example('example')
@@ -134,9 +130,9 @@ public function testDefinitionExampleGetsTransferredToNode()
public function testDefaultPathSeparatorIsDot()
{
$builder = new TreeBuilder();
$builder = new TreeBuilder('propagation');
$builder->root('propagation')
$builder->getRootNode()
->children()
->node('foo', 'variable')->end()
->arrayNode('child')
@@ -164,9 +160,9 @@ public function testDefaultPathSeparatorIsDot()
public function testPathSeparatorIsPropagatedToChildren()
{
$builder = new TreeBuilder();
$builder = new TreeBuilder('propagation');
$builder->root('propagation')
$builder->getRootNode()
->children()
->node('foo', 'variable')->end()
->arrayNode('child')
@@ -192,4 +188,13 @@ public function testPathSeparatorIsPropagatedToChildren()
$this->assertInstanceOf('Symfony\Component\Config\Definition\BaseNode', $childChildren['foo']);
$this->assertSame('propagation/child/foo', $childChildren['foo']->getPath());
}
/**
* @group legacy
* @expectedDeprecation A tree builder without a root node is deprecated since Symfony 4.2 and will not be supported anymore in 5.0.
*/
public function testInitializingTreeBuildersWithoutRootNode()
{
new TreeBuilder();
}
}
@@ -20,9 +20,9 @@ class FinalizationTest extends TestCase
{
public function testUnsetKeyWithDeepHierarchy()
{
$tb = new TreeBuilder();
$tb = new TreeBuilder('config', 'array');
$tree = $tb
->root('config', 'array')
->getRootNode()
->children()
->node('level1', 'array')
->canBeUnset()
Oops, something went wrong.

0 comments on commit 21a3439

Please sign in to comment.