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

Skip to content

Commit f4de76d

Browse files
atailouloutenicolas-grekas
authored andcommitted
[Config] Improve the deprecation features by handling package and version
1 parent 9381dd6 commit f4de76d

18 files changed

+199
-29
lines changed

UPGRADE-5.1.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
UPGRADE FROM 5.0 to 5.1
22
=======================
33

4+
Config
5+
------
6+
7+
* The signature of method `NodeDefinition::setDeprecated()` has been updated to `NodeDefinition::setDeprecation(string $package, string $version, string $message)`.
8+
* The signature of method `BaseNode::setDeprecated()` has been updated to `BaseNode::setDeprecation(string $package, string $version, string $message)`.
9+
* Passing a null message to `BaseNode::setDeprecated()` to un-deprecate a node is deprecated
10+
411
Console
512
-------
613

UPGRADE-6.0.md

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

4+
Config
5+
------
6+
7+
* The signature of method `NodeDefinition::setDeprecated()` has been updated to `NodeDefinition::setDeprecation(string $package, string $version, string $message)`.
8+
* The signature of method `BaseNode::setDeprecated()` has been updated to `BaseNode::setDeprecation(string $package, string $version, string $message)`.
9+
* Passing a null message to `BaseNode::setDeprecated()` to un-deprecate a node is not supported anymore.
10+
411
Console
512
-------
613

src/Symfony/Component/Config/CHANGELOG.md

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

4+
5.1.0
5+
-----
6+
7+
* updated the signature of method `NodeDefinition::setDeprecated()` to `NodeDefinition::setDeprecation(string $package, string $version, string $message)`
8+
* updated the signature of method `BaseNode::setDeprecated()` to `BaseNode::setDeprecation(string $package, string $version, string $message)`
9+
* deprecated passing a null message to `BaseNode::setDeprecated()` to un-deprecate a node
10+
411
5.0.0
512
-----
613

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 funct E377 ion 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() < 2) {
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] ?? 'The child node "%node%" at path "%path%" is deprecated.');
229+
}
230+
231+
$this->deprecation = [
232+
'package' => $package,
233+
'version' => $version,
234+
'message' => $message,
235+
];
207236
}
208237

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

255284
/**
@@ -259,10 +288,27 @@ public function isDeprecated()
259288
* @param string $path the path of the node
260289
*
261290
* @return string
291+
*
292+
* @deprecated since Symfony 5.1, use "getDeprecation()" instead.
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: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -435,10 +435,13 @@ protected function createNode()
435435
$node->addEquivalentValue(false, $this->falseEquivalent);
436436
$node->setPerformDeepMerging($this->performDeepMerging);
437437
$node->setRequired($this->required);
438-
$node->setDeprecated($this->deprecationMessage);
439438
$node->setIgnoreExtraKeys($this->ignoreExtraKeys, $this->removeExtraKeys);
440439
$node->setNormalizeKeys($this->normalizeKeys);
441440

441+
if ($this->deprecation) {
442+
$node->setDeprecated($this->deprecation['package'], $this->deprecation['version'], $this->deprecation['message']);
443+
}
444+
442445
if (null !== $this->normalization) {
443446
$node->setNormalizationClosures($this->normalization->before);
444447
$node->setXmlRemappings($this->normalization->remappings);

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() < 2) {
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: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,10 @@ 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+
58+
if ($this->deprecation) {
59+
$node->setDeprecated($this->deprecation['package'], $this->deprecation['version'], $this->deprecation['message']);
60+
}
5861

5962
if (null !== $this->validation) {
6063
$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: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,15 @@
1212
namespace Symfony\Component\Config\Tests\Definition;
1313

1414
use PHPUnit\Framework\TestCase;
15+
use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait;
1516
use Symfony\Component\Config\Definition\ArrayNode;
1617
use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
1718
use Symfony\Component\Config\Definition\ScalarNode;
1819

1920
class ArrayNodeTest extends TestCase
2021
{
22+
use ExpectDeprecationTrait;
23+
2124
public function testNormalizeThrowsExceptionWhenFalseIsNotAllowed()
2225
{
2326
$this->expectException('Symfony\Component\Config\Definition\Exception\InvalidTypeException');
@@ -227,10 +230,13 @@ public function testGetDefaultValueWithoutDefaultValue()
227230
public function testSetDeprecated()
228231
{
229232
$childNode = new ArrayNode('foo');
230-
$childNode->setDeprecated('"%node%" is deprecated');
233+
$childNode->setDeprecated('vendor/package', '1.1', '"%node%" is deprecated');
231234

232235
$this->assertTrue($childNode->isDeprecated());
233-
$this->assertSame('"foo" is deprecated', $childNode->getDeprecationMessage($childNode->getName(), $childNode->getPath()));
236+
$deprecation = $childNode->getDeprecation($childNode->getName(), $childNode->getPath());
237+
$this->assertSame('"foo" is deprecated', $deprecation['message']);
238+
$this->assertSame('vendor/package', $deprecation['package']);
239+
$this->assertSame('1.1', $deprecation['version']);
234240

235241
$node = new ArrayNode('root');
236242
$node->addChild($childNo F438 de);
@@ -256,6 +262,37 @@ public function testSetDeprecated()
256262
$this->assertTrue($deprecationTriggered, '->finalize() should trigger if the deprecated node is set');
257263
}
258264

265+
/**
266+
* @group legacy
267+
*/
268+
public function testUnDeprecateANode()
269+
{
270+
$this->expectDeprecation('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.');
271+
$this->expectDeprecation('Since symfony/config 5.1: Passing a null message to un-deprecate a node is deprecated.');
272+
273+
$node = new ArrayNode('foo');
274+
$node->setDeprecated('"%node%" is deprecated');
275+
$node->setDeprecated(null);
276+
277+
$this->assertFalse($node->isDeprecated());
278+
}
279+
280+
/**
281+
* @group legacy
282+
*/
283+
public function testSetDeprecatedWithoutPackageAndVersion()
284+
{
285+
$this->expectDeprecation('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.');
286+
287+
$node = new ArrayNode('foo');
288+
$node->setDeprecated('"%node%" is deprecated');
289+
290+
$deprecation = $node->getDeprecation($node->getName(), $node->getPath());
291+
$this->assertSame('"foo" is deprecated', $deprecation['message']);
292+
$this->assertSame('', $deprecation['package']);
293+
$this->assertSame('', $deprecation['version']);
294+
}
295+
259296
/**
260297
* @dataProvider getDataWithIncludedExtraKeys
261298
*/

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

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
namespace Symfony\Component\Config\Tests\Definition\Builder;
1313

1414
use PHPUnit\Framework\TestCase;
15+
use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait;
1516
use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
1617
use Symfony\Component\Config\Definition\Builder\BooleanNodeDefinition;
1718
use Symfony\Component\Config\Definition\Builder\NodeDefinition;
@@ -21,6 +22,8 @@
2122

2223
class ArrayNodeDefinitionTest extends TestCase
2324
{
25+
use ExpectDeprecationTrait;
26+
2427
public function testAppendingSomeNode()
2528
{
2629
$parent = new ArrayNodeDefinition('root');
@@ -332,13 +335,37 @@ public function testSetDeprecated()
332335
$node = new ArrayNodeDefinition('root');
333336
$node
334337
->children()
335-
->arrayNode('foo')->setDeprecated('The "%path%" node is deprecated.')->end()
338+
->arrayNode('foo')->setDeprecated('vendor/package', '1.1', 'The "%path%" node is deprecated.')->end()
339+
->end()
340+
;
341+
$deprecatedNode = $node->getNode()->getChildren()['foo'];
342+
343+
$this->assertTrue($deprecatedNode->isDeprecated());
344+
$deprecation = $deprecatedNode->getDeprecation($deprecatedNode->getName(), $deprecatedNode->getPath());
345+
$this->assertSame('The "root.foo" node is deprecated.', $deprecation['message']);
346+
$this->assertSame('vendor/package', $deprecation['package']);
347+
$this->assertSame('1.1', $deprecation['version']);
348+
}
349+
350+
/**
351+
* @group legacy
352+
*/
353+
public function testSetDeprecatedWithoutPackageAndVersion()
354+
{
355+
$this->expectDeprecation('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.');
356+
$node = new ArrayNodeDefinition('root');
357+
$node
358+
->children()
359+
->arrayNode('foo')->setDeprecated('The "%path%" node is deprecated.')->end()
336360
->end()
337361
;
338362
$deprecatedNode = $node->getNode()->getChildren()['foo'];
339363

340364
$this->assertTrue($deprecatedNode->isDeprecated());
341-
$this->assertSame('The "root.foo" node is deprecated.', $deprecatedNode->getDeprecationMessage($deprecatedNode->getName(), $deprecatedNode->getPath()));
365+
$deprecation = $deprecatedNode->getDeprecation($deprecatedNode->getName(), $deprecatedNode->getPath());
366+
$this->assertSame('The "root.foo" node is deprecated.', $deprecation['message']);
367+
$this->assertSame('', $deprecation['package']);
368+
$this->assertSame('', $deprecation['version']);
342369
}
343370

344371
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
}

0 commit comments

Comments
 (0)
0