Skip to content

Commit 38d61f7

Browse files
committed
[OptionsResolver] Improve the deprecation feature by handling package + version
1 parent bfe6b6f commit 38d61f7

File tree

10 files changed

+169
-48
lines changed

10 files changed

+169
-48
lines changed

UPGRADE-5.1.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,11 @@ Notifier
8686
* [BC BREAK] The `EmailMessage::fromNotification()` and `SmsMessage::fromNotification()`
8787
methods' `$transport` argument was removed.
8888

89+
OptionsResolver
90+
---------------
91+
92+
* The signature of method `OptionsResolver::setDeprecated()` has been updated to `OptionsResolver::setDeprecated(string $option, string $package, string $version, $message)`.
93+
8994
PhpUnitBridge
9095
-------------
9196

UPGRADE-6.0.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,11 @@ Messenger
6969
* The signature of method `RetryStrategyInterface::isRetryable()` has been updated to `RetryStrategyInterface::isRetryable(Envelope $message, \Throwable $throwable = null)`.
7070
* The signature of method `RetryStrategyInterface::getWaitingTime()` has been updated to `RetryStrategyInterface::getWaitingTime(Envelope $message, \Throwable $throwable = null)`.
7171

72+
OptionsResolver
73+
---------------
74+
75+
* The signature of method `OptionsResolver::setDeprecated()` has been updated to `OptionsResolver::setDeprecated(string $option, string $package, string $version, $message)`.
76+
7277
PhpUnitBridge
7378
-------------
7479

src/Symfony/Component/Form/Tests/Command/DebugCommandTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ public function configureOptions(OptionsResolver $resolver)
198198
{
199199
$resolver->setRequired('foo');
200200
$resolver->setDefined('bar');
201-
$resolver->setDeprecated('bar');
201+
$resolver->setDeprecated('bar', 'vendor/package', '1.1');
202202
$resolver->setDefault('empty_data', function (Options $options) {
203203
$foo = $options['foo'];
204204

src/Symfony/Component/Form/Tests/Console/Descriptor/AbstractDescriptorTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ public function configureOptions(OptionsResolver $resolver)
150150
{
151151
$resolver->setRequired('foo');
152152
$resolver->setDefined('bar');
153-
$resolver->setDeprecated('bar');
153+
$resolver->setDeprecated('bar', 'vendor/package', '1.1');
154154
$resolver->setDefault('empty_data', function (Options $options, $value) {
155155
$foo = $options['foo'];
156156

src/Symfony/Component/OptionsResolver/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ CHANGELOG
66

77
* added fluent configuration of options using `OptionResolver::define()`
88
* added `setInfo()` and `getInfo()` methods
9+
* updated the signature of method `OptionsResolver::setDeprecated()` to `OptionsResolver::setDeprecation(string $option, string $package, string $version, $message)`
910

1011
5.0.0
1112
-----

src/Symfony/Component/OptionsResolver/Debug/OptionsResolverIntrospector.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,20 @@ public function getNormalizers(string $option): array
100100
* @return string|\Closure
101101
*
102102
* @throws NoConfigurationException on no configured deprecation
103+
*
104+
* @deprecated since Symfony 5.1, use "getDeprecation()" instead.
103105
*/
104106
public function getDeprecationMessage(string $option)
107+
{
108+
trigger_deprecation('symfony/options-resolver', '5.1', 'The "%s()" method is deprecated, use "getDeprecation()" instead.', __METHOD__);
109+
110+
return $this->getDeprecation($option)['message'];
111+
}
112+
113+
/**
114+
* @throws NoConfigurationException on no configured deprecation
115+
*/
116+
public function getDeprecation(string $option): array
105117
{
106118
return ($this->get)('deprecated', $option, sprintf('No deprecation was set for the "%s" option.', $option));
107119
}

src/Symfony/Component/OptionsResolver/OptionConfigurator.php

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -84,13 +84,28 @@ public function define(string $option): self
8484
/**
8585
* Marks this option as deprecated.
8686
*
87-
* @return $this
87+
* @param string $package The name of the composer package that is triggering the deprecation
88+
* @param string $version The version of the package that introduced the deprecation
89+
* @param string|\Closure $message The deprecation message to use
8890
*
89-
* @param string|\Closure $deprecationMessage
91+
* @return $this
9092
*/
91-
public function deprecated($deprecationMessage = 'The option "%name%" is deprecated.'): self
93+
public function deprecated(/*string $package, string $version, $message = 'The option "%name%" is deprecated.'*/): self
9294
{
93-
$this->resolver->setDeprecated($this->name, $deprecationMessage);
95+
$args = \func_get_args();
96+
97+
if (\func_num_args() < 2) {
98+
trigger_deprecation('symfony/options-resolver', '5.1', 'The signature of method "%s()" requires 2 new arguments: "string $package, string $version", not defining them is deprecated.', __METHOD__);
99+
100+
$message = $args[0] ?? 'The option "%name%" is deprecated.';
101+
$package = (string) $version = '';
102+
} else {
103+
$package = (string) $args[0];
104+
$version = (string) $args[1];
105+
$message = (string) ($args[2] ?? 'The option "%name%" is deprecated.');
106+
}
107+
108+
$this->resolver->setDeprecated($this->name, $package, $version, $message);
94109

95110
return $this;
96111
}

src/Symfony/Component/OptionsResolver/OptionsResolver.php

Lines changed: 34 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -421,9 +421,11 @@ public function isNested(string $option): bool
421421
* passed to the closure is the value of the option after validating it
422422
* and before normalizing it.
423423
*
424-
* @param string|\Closure $deprecationMessage
424+
* @param string $package The name of the composer package that is triggering the deprecation
425+
* @param string $version The version of the package that introduced the deprecation
426+
* @param string|\Closure $message The deprecation message to use
425427
*/
426-
public function setDeprecated(string $option, $deprecationMessage = 'The option "%name%" is deprecated.'): self
428+
public function setDeprecated(string $option/*, string $package, string $version, $message = 'The option "%name%" is deprecated.' */): self
427429
{
428430
if ($this->locked) {
429431
throw new AccessException('Options cannot be deprecated from a lazy option or normalizer.');
@@ -433,16 +435,33 @@ public function setDeprecated(string $option, $deprecationMessage = 'The option
433435
throw new UndefinedOptionsException(sprintf('The option "%s" does not exist, defined options are: "%s".', $this->formatOptions([$option]), implode('", "', array_keys($this->defined))));
434436
}
435437

436-
if (!\is_string($deprecationMessage) && !$deprecationMessage instanceof \Closure) {
437-
throw new InvalidArgumentException(sprintf('Invalid type for deprecation message argument, expected string or \Closure, but got "%s".', get_debug_type($deprecationMessage)));
438+
$args = \func_get_args();
439+
440+
if (\func_num_args() < 3) {
441+
trigger_deprecation('symfony/options-resolver', '5.1', 'The signature of method "%s()" requires 2 new arguments: "string $package, string $version", not defining them is deprecated.', __METHOD__);
442+
443+
$message = $args[1] ?? 'The option "%name%" is deprecated.';
444+
$package = $version = '';
445+
} else {
446+
$package = $args[1];
447+
$version = $args[2];
448+
$message = $args[3] ?? 'The option "%name%" is deprecated.';
449+
}
450+
451+
if (!\is_string($message) && !$message instanceof \Closure) {
452+
throw new InvalidArgumentException(sprintf('Invalid type for deprecation message argument, expected string or \Closure, but got "%s".', get_debug_type($message)));
438453
}
439454

440455
// ignore if empty string
441-
if ('' === $deprecationMessage) {
456+
if ('' === $message) {
442457
return $this;
443458
}
444459

445-
$this->deprecated[$option] = $deprecationMessage;
460+
$this->deprecated[$option] = [
461+
'package' => $package,
462+
'version' => $version,
463+
'message' => $message,
464+
];
446465

447466
// Make sure the option is processed
448467
unset($this->resolved[$option]);
@@ -903,8 +922,8 @@ public function offsetGet($option, bool $triggerDeprecation = true)
903922

904923
// Shortcut for resolved options
905924
if (isset($this->resolved[$option]) || \array_key_exists($option, $this->resolved)) {
906-
if ($triggerDeprecation && isset($this->deprecated[$option]) && (isset($this->given[$option]) || $this->calling) && \is_string($this->deprecated[$option])) {
907-
trigger_deprecation('', '', strtr($this->deprecated[$option], ['%name%' => $option]));
925+
if ($triggerDeprecation && isset($this->deprecated[$option]) && (isset($this->given[$option]) || $this->calling) && \is_string($this->deprecated[$option]['message'])) {
926+
trigger_deprecation($this->deprecated[$option]['package'], $this->deprecated[$option]['version'], strtr($this->deprecated[$option]['message'], ['%name%' => $option]));
908927
}
909928

910929
return $this->resolved[$option];
@@ -1048,26 +1067,27 @@ public function offsetGet($option, bool $triggerDeprecation = true)
10481067
// Check whether the option is deprecated
10491068
// and it is provided by the user or is being called from a lazy evaluation
10501069
if ($triggerDeprecation && isset($this->deprecated[$option]) && (isset($this->given[$option]) || ($this->calling && \is_string($this->deprecated[$option])))) {
1051-
$deprecationMessage = $this->deprecated[$option];
1070+
$deprecation = $this->deprecated[$option];
1071+
$message = $this->deprecated[$option]['message'];
10521072

1053-
if ($deprecationMessage instanceof \Closure) {
1073+
if ($message instanceof \Closure) {
10541074
// If the closure is already being called, we have a cyclic dependency
10551075
if (isset($this->calling[$option])) {
10561076
throw new OptionDefinitionException(sprintf('The options "%s" have a cyclic dependency.', $this->formatOptions(array_keys($this->calling))));
10571077
}
10581078

10591079
$this->calling[$option] = true;
10601080
try {
1061-
if (!\is_string($deprecationMessage = $deprecationMessage($this, $value))) {
1062-
throw new InvalidOptionsException(sprintf('Invalid type for deprecation message, expected string but got "%s", return an empty string to ignore.', get_debug_type($deprecationMessage)));
1081+
if (!\is_string($message = $message($this, $value))) {
1082+
throw new InvalidOptionsException(sprintf('Invalid type for deprecation message, expected string but got "%s", return an empty string to ignore.', get_debug_type($message)));
10631083
}
10641084
} finally {
10651085
unset($this->calling[$option]);
10661086
}
10671087
}
10681088

1069-
if ('' !== $deprecationMessage) {
1070-
trigger_deprecation('', '', strtr($deprecationMessage, ['%name%' => $option]));
1089+
if ('' !== $message) {
1090+
trigger_deprecation($deprecation['package'], $deprecation['version'], strtr($message, ['%name%' => $option]));
10711091
}
10721092
}
10731093

src/Symfony/Component/OptionsResolver/Tests/Debug/OptionsResolverIntrospectorTest.php

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,9 @@ public function testGetNormalizersThrowsOnNotDefinedOption()
213213
$debug->getNormalizers('foo');
214214
}
215215

216+
/**
217+
* @group legacy
218+
*/
216219
public function testGetDeprecationMessage()
217220
{
218221
$resolver = new OptionsResolver();
@@ -223,6 +226,9 @@ public function testGetDeprecationMessage()
223226
$this->assertSame('The option "foo" is deprecated.', $debug->getDeprecationMessage('foo'));
224227
}
225228

229+
/**
230+
* @group legacy
231+
*/
226232
public function testGetClosureDeprecationMessage()
227233
{
228234
$resolver = new OptionsResolver();
@@ -233,6 +239,34 @@ public function testGetClosureDeprecationMessage()
233239
$this->assertSame($closure, $debug->getDeprecationMessage('foo'));
234240
}
235241

242+
public function testGetDeprecation()
243+
{
244+
$resolver = new OptionsResolver();
245+
$resolver->setDefined('foo');
246+
$resolver->setDeprecated('foo', 'vendor/package', '1.1', 'The option "foo" is deprecated.');
247+
248+
$debug = new OptionsResolverIntrospector($resolver);
249+
$this->assertSame([
250+
'package' => 'vendor/package',
251+
'version' => '1.1',
252+
'message' => 'The option "foo" is deprecated.',
253+
], $debug->getDeprecation('foo'));
254+
}
255+
256+
public function testGetClosureDeprecation()
257+
{
258+
$resolver = new OptionsResolver();
259+
$resolver->setDefined('foo');
260+
$resolver->setDeprecated('foo', 'vendor/package', '1.1', $closure = function (Options $options, $value) {});
261+
262+
$debug = new OptionsResolverIntrospector($resolver);
263+
$this->assertSame([
264+
'package' => 'vendor/package',
265+
'version' => '1.1',
266+
'message' => $closure,
267+
], $debug->getDeprecation('foo'));
268+
}
269+
236270
public function testGetDeprecationMessageThrowsOnNoConfiguredValue()
237271
{
238272
$this->expectException('Symfony\Component\OptionsResolver\Exception\NoConfigurationException');
@@ -241,7 +275,7 @@ public function testGetDeprecationMessageThrowsOnNoConfiguredValue()
241275
$resolver->setDefined('foo');
242276

243277
$debug = new OptionsResolverIntrospector($resolver);
244-
$this->assertSame('bar', $debug->getDeprecationMessage('foo'));
278+
$debug->getDeprecation('foo');
245279
}
246280

247281
public function testGetDeprecationMessageThrowsOnNotDefinedOption()
@@ -251,6 +285,6 @@ public function testGetDeprecationMessageThrowsOnNotDefinedOption()
251285
$resolver = new OptionsResolver();
252286

253287
$debug = new OptionsResolverIntrospector($resolver);
254-
$this->assertSame('bar', $debug->getDeprecationMessage('foo'));
288+
$debug->getDeprecation('foo');
255289
}
256290
}

0 commit comments

Comments
 (0)