8000 [Config] Improve the deprecation features by handling package and ver… · symfony/symfony@bb1e5bc · GitHub
[go: up one dir, main page]

Skip to content

Commit bb1e5bc

Browse files
committed
[Config] Improve the deprecation features by handling package and version
1 parent d0e5593 commit bb1e5bc

17 files changed

+179
-29
lines changed

UPGRADE-6.0.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
UPGRADE FROM 5.x to 6.0
22
=======================
33

4+
Config
5+
------
6+
* The signature of method `NodeDefinition::setDeprecated()` has been updated to `NodeDefinition::setDeprecation(string $package, string $version, string $message)`.
7+
* The signature of method `BaseNode::setDeprecated()` has been updated to `BaseNode::setDeprecation(string $package, string $version, string $message)`.
8+
49
Console
510
-------
611

src/Symfony/Component/Config/CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
CHANGELOG
22
=========
33

4+
5.1.0
5+
-----
6+
* deprecated signature `NodeDefinition::setDeprecated(string $message)`, use `Definition::setDeprecation(string $package, string $version, string $message)` instead
7+
* deprecated signature `BaseNode::setDeprecated(?string $message)`, use `Alias::setDeprecation(string $package, string $version, string $message)` instead
8+
* deprecated passing a null message to `BaseNode::setDeprecated()` to un-deprecate a node
9+
410
5.0.0
511
-----
612

src/Symfony/Component/Config/Definition/ArrayNode.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,8 @@ protected function finalizeValue($value)
227227
}
228228

229229
if ($child->isDeprecated()) {
230-
trigger_deprecation('', '', $child->getDeprecationMessage($name, $this->getPath()));
230+
$deprecation = $child->getDeprecation($name, $this->getPath());
231+
trigger_deprecation($deprecation['package'], $deprecation['version'], $deprecation['message']);
231232
}
232233

233234
try {

src/Symfony/Component/Config/Definition/BaseNode.php

Lines changed: 51 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ abstract class BaseNode implements NodeInterface
3535
protected $finalValidationClosures = [];
3636
protected $allowOverwrite = true;
3737
protected $required = false;
38-
protected $deprecationMessage = null;
38+
protected $deprecation = [];
3939
protected $equivalentValues = [];
4040
protected $attributes = [];
4141
protected $pathSeparator;
@@ -198,12 +198,41 @@ public function setRequired(bool $boolean)
198198
/**
199199
* Sets this node as deprecated.
200200
*
201+
* @param string $package The name of the composer package that is triggering the deprecation
202+
* @param string $version The version of the package that introduced the deprecation
203+
* @param string $message the deprecation message to use
204+
*
201205
* You can use %node% and %path% placeholders in your message to display,
202206
* respectively, the node name and its complete path.
203207
*/
204-
public function setDeprecated(?string $message)
208+
public function setDeprecated(/* string $package, string $version, string $message = 'The child node "%node%" at path "%path%" is deprecated.' */)
205209
{
206-
$this->deprecationMessage = $message;
210+
$args = \func_get_args();
211+
212+
if (\func_num_args() < 3) {
213+
trigger_deprecation('symfony/config', '5.1', 'The signature of method "%s()" requires 3 arguments: "string $package, string $version, string $message", not defining them is deprecated.', __METHOD__);
214+
215+
if (!isset($args[0])) {
216+
trigger_deprecation('symfony/config', '5.1', 'Passing a null message to un-deprecate a node is deprecated.');
217+
218+
$this->deprecation = [];
219+
220+
return;
221+
}
222+
223+
$message = (string) $args[0];
224+
$package = $version = '';
225+
} else {
226+
$package = (string) $args[0];
227+
$version = (string) $args[1];
228+
$message = (string) $args[2];
229+
}
230+
231+
$this->deprecation = [
232+
'package' => $package,
233+
'version' => $version,
234+
'message' => $message,
235+
];
207236
}
208237

209238
/**
@@ -249,20 +278,37 @@ public function isRequired()
249278
*/
250279
public function isDeprecated()
251280
{
252-
return null !== $this->deprecationMessage;
281+
return (bool) $this->deprecation;
253282
}
254283

255284
/**
256285
* Returns the deprecated message.
257286
*
287+
* @deprecated since Symfony 5.1, use "getDeprecation()" instead.
288+
*
258289
* @param string $node the configuration node name
259290
* @param string $path the path of the node
260291
*
261292
* @return string
262293
*/
263294
public function getDeprecationMessage(string $node, string $path)
264295
{
265-
return strtr($this->deprecationMessage, ['%node%' => $node, '%path%' => $path]);
296+
trigger_deprecation('symfony/config', '5.1', 'The "%s()" method is deprecated, use "getDeprecation()" instead.', __METHOD__);
297+
298+
return $this->getDeprecation($node, $path)['message'];
299+
}
300+
301+
/**
302+
* @param string $node the configuration node name
303+
* @param string $path the path of the node
304+
*/
305+
public function getDeprecation(string $node, string $path): array
306+
{
307+
return [
308+
'package' => $this->deprecation['package'] ?? '',
309+
'version' => $this->deprecation['version'] ?? '',
310+
'message' => strtr($this->deprecation['message'] ?? '', ['%node%' => $node, '%path%' => $path]),
311+
];
266312
}
267313

268314
/**

src/Symfony/Component/Config/Definition/Builder/ArrayNodeDefinition.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -435,7 +435,9 @@ protected function createNode()
435435
$node->addEquivalentValue(false, $this->falseEquivalent);
436436
$node->setPerformDeepMerging($this->performDeepMerging);
437437
$node->setRequired($this->required);
438-
$node->setDeprecated($this->deprecationMessage);
438+
if ([] !== $this->deprecation) {
439+
$node->setDeprecated($this->deprecation['package'], $this->deprecation['version'], $this->deprecation['message']);
440+
}
439441
$node->setIgnoreExtraKeys($this->ignoreExtraKeys, $this->removeExtraKeys);
440442
$node->setNormalizeKeys($this->normalizeKeys);
441443

src/Symfony/Component/Config/Definition/Builder/NodeDefinition.php

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ abstract class NodeDefinition implements NodeParentInterface
2828
protected $defaultValue;
2929
protected $default = false;
3030
protected $required = false;
31-
protected $deprecationMessage = null;
31+
protected $deprecation = [];
3232
protected $merge;
3333
protected $allowEmptyValue = true;
3434
protected $nullEquivalent;
@@ -159,14 +159,35 @@ public function isRequired()
159159
/**
160160
* Sets the node as deprecated.
161161
*
162+
* @param string $package The name of the composer package that is triggering the deprecation
163+
* @param string $version The version of the package that introduced the deprecation
164+
* @param string $message the deprecation message to use
165+
*
162166
* You can use %node% and %path% placeholders in your message to display,
163167
* respectively, the node name and its complete path.
164168
*
165169
* @return $this
166170
*/
167-
public function setDeprecated(string $message = 'The child node "%node%" at path "%path%" is deprecated.')
171+
public function setDeprecated(/* string $package, string $version, string $message = 'The child node "%node%" at path "%path%" is deprecated.' */)
168172
{
169-
$this->deprecationMessage = $message;
173+
$args = \func_get_args();
174+
175+
if (\func_num_args() <= 1) {
176+
trigger_deprecation('symfony/config', '5.1', 'The signature of method "%s()" requires 3 arguments: "string $package, string $version, string $message", not defining them is deprecated.', __METHOD__);
177+
178+
$message = $args[0] ?? 'The child node "%node%" at path "%path%" is deprecated.';
179+
$package = $version = '';
180+
} else {
181+
$package = (string) $args[0];
182+
$version = (string) $args[1];
183+
$message = (string) ($args[2] ?? 'The child node "%node%" at path "%path%" is deprecated.');
184+
}
185+
186+
$this->deprecation = [
187+
'package' => $package,
188+
'version' => $version,
189+
'message' => $message,
190+
];
170191

171192
return $this;
172193
}

src/Symfony/Component/Config/Definition/Builder/VariableNodeDefinition.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,9 @@ protected function createNode()
5454
$node->addEquivalentValue(true, $this->trueEquivalent);
5555
$node->addEquivalentValue(false, $this->falseEquivalent);
5656
$node->setRequired($this->required);
57-
$node->setDeprecated($this->deprecationMessage);
57+
if ([] !== $this->deprecation) {
58+
$node->setDeprecated($this->deprecation['package'], $this->deprecation['version'], $this->deprecation['message']);
59+
}
5860

5961
if (null !== $this->validation) {
6062
$node->setFinalValidationClosures($this->validation->rules);

src/Symfony/Component/Config/Definition/Dumper/XmlReferenceDumper.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,8 @@ private function writeNode(NodeInterface $node, int $depth = 0, bool $root = fal
148148
}
149149

150150
if ($child->isDeprecated()) {
151-
$comments[] = sprintf('Deprecated (%s)', $child->getDeprecationMessage($child->getName(), $node->getPath()));
151+
$deprecation = $child->getDeprecation($child->getName(), $node->getPath());
152+
$comments[] = sprintf('Deprecated (%s)', ($deprecation['package'] || $deprecation['version'] ? "Since {$deprecation['package']} {$deprecation['version']}: " : '').$deprecation['message']);
152153
}
153154

154155
if ($child instanceof EnumNode) {

src/Symfony/Component/Config/Definition/Dumper/YamlReferenceDumper.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,8 @@ private function writeNode(NodeInterface $node, NodeInterface $parentNode = null
120120

121121
// deprecated?
122122
if ($node->isDeprecated()) {
123-
$comments[] = sprintf('Deprecated (%s)', $node->getDeprecationMessage($node->getName(), $parentNode ? $parentNode->getPath() : $node->getPath()));
123+
$deprecation = $node->getDeprecation($node->getName(), $parentNode ? $parentNode->getPath() : $node->getPath());
124+
$comments[] = sprintf('Deprecated (%s)', ($deprecation['package'] || $deprecation['version'] ? "Since {$deprecation['package']} {$deprecation['version']}: " : '').$deprecation['message']);
124125
}
125126

126127
// example

src/Symfony/Component/Config/Tests/Definition/ArrayNodeTest.php

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -227,10 +227,13 @@ public function testGetDefaultValueWithoutDefaultValue()
227227
public function testSetDeprecated()
228228
{
229229
$childNode = new ArrayNode('foo');
230-
$childNode->setDeprecated('"%node%" is deprecated');
230+
$childNode->setDeprecated('vendor/package', '1.1', '"%node%" is deprecated');
231231

232232
$this->assertTrue($childNode->isDeprecated());
233-
$this->assertSame('"foo" is deprecated', $childNode->getDeprecationMessage($childNode->getName(), $childNode->getPath()));
233+
$deprecation = $childNode->getDeprecation($childNode->getName(), $childNode->getPath());
234+
$this->assertSame('"foo" is deprecated', $deprecation['message']);
235+
$this->assertSame('vendor/package', $deprecation['package']);
236+
$this->assertSame('1.1', $deprecation['version']);
234237

235238
$node = new ArrayNode('root');
236239
$node->addChild($childNode);
@@ -256,6 +259,35 @@ public function testSetDeprecated()
256259
$this->assertTrue($deprecationTriggered, '->finalize() should trigger if the deprecated node is set');
257260
}
258261

262+
/**
263+
* @group legacy
264+
* @expectedDeprecation Since symfony/config 5.1: The signature of method "Symfony\Component\Config\Definition\BaseNode::setDeprecated()" requires 3 arguments: "string $package, string $version, string $message", not defining them is deprecated.
265+
* @expectedDeprecation Since symfony/config 5.1: Passing a null message to un-deprecate a node is deprecated.
266+
*/
267+
public function testUnDeprecateANode()
268+
{
269+
$node = new ArrayNode('foo');
270+
$node->setDeprecated('"%node%" is deprecated');
271+
$node->setDeprecated(null);
272+
273+
$this->assertFalse($node->isDeprecated());
274+
}
275+
276+
/**
277+
* @group legacy
278+
* @expectedDeprecation Since symfony/config 5.1: The signature of method "Symfony\Component\Config\Definition\BaseNode::setDeprecated()" requires 3 arguments: "string $package, string $version, string $message", not defining them is deprecated.
279+
*/
280+
public function testSetDeprecatedWithoutPackageAndVersion()
281+
{
282+
$node = new ArrayNode('foo');
283+
$node->setDeprecated('"%node%" is deprecated');
284+
285+
$deprecation = $node->getDeprecation($node->getName(), $node->getPath());
286+
$this->assertSame('"foo" is deprecated', $deprecation['message']);
287+
$this->assertSame('', $deprecation['package']);
288+
$this->assertSame('', $deprecation['version']);
289+
}
290+
259291
/**
260292
* @dataProvider getDataWithIncludedExtraKeys
261293
*/

src/Symfony/Component/Config/Tests/Definition/Builder/ArrayNodeDefinitionTest.php

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -332,13 +332,37 @@ public function testSetDeprecated()
332332
$node = new ArrayNodeDefinition('root');
333333
$node
334334
->children()
335-
->arrayNode('foo')->setDeprecated('The "%path%" node is deprecated.')->end()
335+
->arrayNode('foo')->setDeprecated('vendor/package', '1.1', 'The "%path%" node is deprecated.')->end()
336336
->end()
337337
;
338338
$deprecatedNode = $node->getNode()->getChildren()['foo'];
339339

340340
$this->assertTrue($deprecatedNode->isDeprecated());
341-
$this->assertSame('The "root.foo" node is deprecated.', $deprecatedNode->getDeprecationMessage($deprecatedNode->getName(), $deprecatedNode->getPath()));
341+
$deprecation = $deprecatedNode->getDeprecation($deprecatedNode->getName(), $deprecatedNode->getPath());
342+
$this->assertSame('The "root.foo" node is deprecated.', $deprecation['message']);
343+
$this->assertSame('vendor/package', $deprecation['package']);
344+
$this->assertSame('1.1', $deprecation['version']);
345+
}
346+
347+
/**
348+
* @group legacy
349+
* @expectedDeprecation Since symfony/config 5.1: The signature of method "Symfony\Component\Config\Definition\Builder\NodeDefinition::setDeprecated()" requires 3 arguments: "string $package, string $version, string $message", not defining them is deprecated.
350+
*/
351+
public function testSetDeprecatedWithoutPackageAndVersion()
352+
{
353+
$node = new ArrayNodeDefinition('root');
354+
$node
355+
->children()
356+
->arrayNode('foo')->setDeprecated('The "%path%" node is deprecated.')->end()
357+
->end()
358+
;
359+
$deprecatedNode = $node->getNode()->getChildren()['foo'];
360+
361+
$this->assertTrue($deprecatedNode->isDeprecated());
362+
$deprecation = $deprecatedNode->getDeprecation($deprecatedNode->getName(), $deprecatedNode->getPath());
363+
$this->assertSame('The "root.foo" node is deprecated.', $deprecation['message']);
364+
$this->assertSame('', $deprecation['package']);
365+
$this->assertSame('', $deprecation['version']);
342366
}
343367

344368
public function testCannotBeEmptyOnConcreteNode()

src/Symfony/Component/Config/Tests/Definition/Builder/BooleanNodeDefinitionTest.php

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,14 @@ public function testCannotBeEmptyThrowsAnException()
2727
public function testSetDeprecated()
2828
{
2929
$def = new BooleanNodeDefinition('foo');
30-
$def->setDeprecated('The "%path%" node is deprecated.');
30+
$def->setDeprecated('vendor/package', '1.1', 'The "%path%" node is deprecated.');
3131

3232
$node = $def->getNode();
3333

3434
$this->assertTrue($node->isDeprecated());
35-
$this->assertSame('The "foo" node is deprecated.', $node->getDeprecationMessage($node->getName(), $node->getPath()));
35+
$deprecation = $node->getDeprecation($node->getName(), $node->getPath());
36+
$this->assertSame('The "foo" node is deprecated.', $deprecation['message']);
37+
$this->assertSame('vendor/package', $deprecation['package']);
38+
$this->assertSame('1.1', $deprecation['version']);
3639
}
3740
}

src/Symfony/Component/Config/Tests/Definition/Builder/EnumNodeDefinitionTest.php

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,11 +63,14 @@ public function testSetDeprecated()
6363
{
6464
$def = new EnumNodeDefinition('foo');
6565
$def->values(['foo', 'bar']);
66-
$def->setDeprecated('The "%path%" node is deprecated.');
66+
$def->setDeprecated('vendor/package', '1.1', 'The "%path%" node is deprecated.');
6767

6868
$node = $def->getNode();
6969

7070
$this->assertTrue($node->isDeprecated());
71-
$this->assertSame('The "foo" node is deprecated.', $def->getNode()->getDeprecationMessage($node->getName(), $node->getPath()));
71+
$deprecation = $def->getNode()->getDeprecation($node->getName(), $node->getPath());
72+
$this->assertSame('The "foo" node is deprecated.', $deprecation['message']);
73+
$this->assertSame('vendor/package', $deprecation['package']);
74+
$this->assertSame('1.1', $deprecation['version']);
7275
}
7376
}

src/Symfony/Component/Config/Tests/Definition/Dumper/XmlReferenceDumperTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@ private function getConfigurationAsString()
3838
return str_replace("\n", PHP_EOL, <<<'EOL'
3939
<!-- Namespace: http://example.org/schema/dic/acme_root -->
4040
<!-- scalar-required: Required -->
41-
<!-- scalar-deprecated: Deprecated (The child node "scalar_deprecated" at path "acme_root" is deprecated.) -->
42-
<!-- scalar-deprecated-with-message: Deprecated (Deprecation custom message for "scalar_deprecated_with_message" at "acme_root") -->
41+
<!-- scalar-deprecated: Deprecated (Since vendor/package 1.1: The child node "scalar_deprecated" at path "acme_root" is deprecated.) -->
42+
<!-- scalar-deprecated-with-message: Deprecated (Since vendor/package 1.1: Deprecation custom message for "scalar_deprecated_with_message" at "acme_root") -->
4343
<!-- enum-with-default: One of "this"; "that" -->
4444
<!-- enum: One of "this"; "that" -->
4545
<config

src/Symfony/Component/Config/Tests/Definition/Dumper/YamlReferenceDumperTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,8 +98,8 @@ private function getConfigurationAsString()
9898
- elem1
9999
- elem2
100100
scalar_required: ~ # Required
101-
scalar_deprecated: ~ # Deprecated (The child node "scalar_deprecated" at path "acme_root" is deprecated.)
102-
scalar_deprecated_with_message: ~ # Deprecated (Deprecation custom message for "scalar_deprecated_with_message" at "acme_root")
101+
scalar_deprecated: ~ # Deprecated (Since vendor/package 1.1: The child node "scalar_deprecated" at path "acme_root" is deprecated.)
102+
scalar_deprecated_with_message: ~ # Deprecated (Since vendor/package 1.1: Deprecation custom message for "scalar_deprecated_with_message" at "acme_root")
103103
node_with_a_looong_name: ~
104104
enum_with_default: this # One of "this"; "that"
105105
enum: ~ # One of "this"; "that"

src/Symfony/Component/Config/Tests/Definition/ScalarNodeTest.php

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,13 @@ public function getValidValues()
4444
public function testSetDeprecated()
4545
{
4646
$childNode = new ScalarNode('foo');
47-
$childNode->setDeprecated('"%node%" is deprecated');
47+
$childNode->setDeprecated('vendor/package', '1.1', '"%node%" is deprecated');
4848

4949
$this->assertTrue($childNode->isDeprecated());
50-
$this->assertSame('"foo" is deprecated', $childNode->getDeprecationMessage($childNode->getName(), $childNode->getPath()));
50+
$deprecation = $childNode->getDeprecation($childNode->getName(), $childNode->getPath());
51+
$this->assertSame('"foo" is deprecated', $deprecation['message']);
52+
$this->assertSame('vendor/package', $deprecation['package']);
53+
$this->assertSame('1.1', $deprecation['version']);
5154

5255
$node = new ArrayNode('root');
5356
$node->addChild($childNode);

src/Symfony/Component/Config/Tests/Fixtures/Configuration/ExampleConfiguration.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ public function getConfigTreeBuilder(): TreeBuilder
3434
->scalarNode('scalar_array_empty')->defaultValue([])->end()
3535
->scalarNode('scalar_array_defaults')->defaultValue(['elem1', 'elem2'])->end()
3636
->scalarNode('scalar_required')->isRequired()->end()
37-
->scalarNode('scalar_deprecated')->setDeprecated()->end()
38-
->scalarNode('scalar_deprecated_with_message')->setDeprecated('Deprecation custom message for "%node%" at "%path%"')->end()
37+
->scalarNode('scalar_deprecated')->setDeprecated('vendor/package', '1.1')->end()
38+
->scalarNode('scalar_deprecated_with_message')->setDeprecated('vendor/package', '1.1', 'Deprecation custom message for "%node%" at "%path%"')->end()
3939
->scalarNode('node_with_a_looong_name')->end()
4040
->enumNode('enum_with_default')->values(['this', 'that'])->defaultValue('this')->end()
4141
->enumNode('enum')->values(['this', 'that'])->end()

0 commit comments

Comments
 (0)
0