Skip to content

Commit c8ddd80

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

17 files changed

+180
-29
lines changed

UPGRADE-6.0.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
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+
410
Console
511
-------
612

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() < 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,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() < 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: 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
*/

0 commit comments

Comments
 (0)