8000 Put undetermined deprecations in the "other" group · symfony/symfony@a2a7612 · GitHub
[go: up one dir, main page]

Skip to content

Commit a2a7612

Browse files
committed
Put undetermined deprecations in the "other" group
Sometimes, you cannot easily know if code was written by a vendor or directly in the application, for instance if the code comes from a file in the cache. In that case, it is better not to classify the deprecation as direct or indirect.
1 parent 31c8700 commit a2a7612

File tree

9 files changed

+115
-56
lines changed

9 files changed

+115
-56
lines changed

src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -139,10 +139,13 @@ public function handleError($type, $msg, $file, $line, $context = [])
139139
$group = 'unsilenced';
140140
} elseif ($deprecation->isLegacy(self::$utilPrefix)) {
141141
$group = 'legacy';
142-
} elseif (!$deprecation->isSelf()) {
143-
$group = $deprecation->isIndirect() ? 'remaining indirect' : 'remaining direct';
144142
} else {
145-
$group = 'remaining self';
143+
$group = [
144+
Deprecation::TYPE_SELF => 'remaining self',
145+
Deprecation::TYPE_DIRECT => 'remaining direct',
146+
Deprecation::TYPE_INDIRECT => 'remaining indirect',
147+
Deprecation::TYPE_UNDETERMINED => 'other',
148+
][$deprecation->getType()];
146149
}
147150

148151
if ($this->getConfiguration()->shouldDisplayStackTrace($msg)) {
@@ -228,9 +231,9 @@ private function getConfiguration()
228231
return $this->configuration = Configuration::inWeakMode();
229232
}
230233
if (self::MODE_WEAK_VENDORS === $mode) {
231-
++$this->deprecations['remaining directCount'];
234+
++$this->deprecations['remaining selfCount'];
232235
$msg = sprintf('Setting SYMFONY_DEPRECATIONS_HELPER to "%s" is deprecated in favor of "max[self]=0"', $mode);
233-
$ref = &$this->deprecations['remaining direct'][$msg]['count'];
236+
$ref = &$this->deprecations['remaining self'][$msg]['count'];
234237
++$ref;
235238
$mode = 'max[self]=0';
236239
}

src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler/Deprecation.php

Lines changed: 69 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,15 @@
1818
*/
1919
class Deprecation
2020
{
21+
private const PATH_TYPE_VENDOR = 'path_type_vendor';
22+
private const PATH_TYPE_SELF = 'path_type_internal';
23+
private const PATH_TYPE_UNDETERMINED = 'path_type_undetermined';
24+
25+
public const TYPE_SELF = 'type_self';
26+
public const TYPE_DIRECT = 'type_direct';
27+
public const TYPE_INDIRECT = 'type_indirect';
28+
public const TYPE_UNDETERMINED = 'type_undetermined';
29+
2130
/**
2231
* @var array
2332
*/
@@ -39,13 +48,20 @@ class Deprecation
3948
private $originMethod;
4049

4150
/**
42-
* @var bool
51+
* @var string one of the PATH_TYPE_* constants
4352
*/
44-
private $self;
53+
private $triggeringFilePathType;
4554

4655
/** @var string[] absolute paths to vendor directories */
4756
private static $vendors;
4857

58+
/**
59+
* @var string[] absolute paths to source or tests of the project. This
60+
* excludes cache directories, because it is based on autoloading rules and
61+
* cache systems typically do not use those.
62+
*/
63+
private static $internalPaths;
64+
4965
/**
5066
* @param string $message
5167
* @param string $file
@@ -59,7 +75,7 @@ public function __construct($message, array $trace, $file)
5975
// No-op
6076
}
6177
$line = $trace[$i];
62-
$this->self = !$this->pathOriginatesFromVendor($file);
78+
$this->trigerringFilePathType = $this->getPathType($file);
6379
if (isset($line['object']) || isset($line['class'])) {
6480
if (isset($line['class']) && 0 === strpos($line['class'], SymfonyTestsListenerFor::class)) {
6581
$parsedMsg = unserialize($this->message);
@@ -70,8 +86,9 @@ public function __construct($message, array $trace, $file)
7086
// \Symfony\Bridge\PhpUnit\Legacy\SymfonyTestsListenerTrait::endTest()
7187
// then we need to use the serialized information to determine
7288
// if the error has been triggered from vendor code.
73-
$this->self = isset($parsedMsg['triggering_file'])
74-
&& $this->pathOriginatesFromVendor($parsedMsg['triggering_file']);
89+
if (isset($parsedMsg['triggering_file'])) {
90+
$this->trigerringFilePathType = $this->getPathType($parsedMsg['triggering_file']);
91+
}
7592

7693
return;
7794
}
@@ -101,14 +118,6 @@ public function originatesFromAnObject()
101118
return isset($this->originClass);
102119
}
103120

104-
/**
105-
* @return bool
106-
*/
107-
public function isSelf()
108-
{
109-
return $this->self;
110-
}
111-
112121
/**
113122
* @return string
114123
*/
@@ -163,10 +172,16 @@ public function isLegacy($utilPrefix)
163172
* Tells whether both the calling package and the called package are vendor
164173
* packages.
165174
*
166-
* @return bool
175+
* @return string
167176
*/
168-
public function isIndirect()
177+
public function getType()
169178
{
179+
if ($this->trigerringFilePathType === self::PATH_TYPE_SELF) {
180+
return self::TYPE_SELF;
181+
}
182+
if ($this->trigerringFilePathType === self::PATH_TYPE_UNDETERMINED) {
183+
return self::TYPE_UNDETERMINED;
184+
}
170185
$erroringFile = $erroringPackage = null;
171186
foreach ($this->trace as $line) {
172187
if (\in_array($line['function'], ['require', 'require_once', 'include', 'include_once'], true)) {
@@ -179,25 +194,28 @@ public function isIndirect()
179194
if ('-' === $file || 'Standard input code' === $file || !realpath($file)) {
180195
continue;
181196
}
182-
if (!$this->pathOriginatesFromVendor($file)) {
183-
return false;
197+
if (self::PATH_TYPE_SELF === $this->getPathType($file)) {
198+
return self::TYPE_DIRECT;
199+
}
200+
if (self::PATH_TYPE_UNDETERMINED === $this->getPathType($file)) {
201+
return self::TYPE_UNDETERMINED;
184202
}
185203
if (null !== $erroringFile && null !== $erroringPackage) {
186204
$package = $this->getPackage($file);
187205
if ('composer' !== $package && $package !== $erroringPackage) {
188-
return true;
206+
return self::TYPE_INDIRECT;
189207
}
190208
continue;
191209
}
192210
$erroringFile = $file;
193211
$erroringPackage = $this->getPackage($file);
194212
}
195213

196-
return false;
214+
return self::TYPE_DIRECT;
197215
}
198216

199217
/**
200-
* pathOriginatesFromVendor() should always be called prior to calling this method.
218+
* getPathType() should always be called prior to calling this method.
201219
*
202220
* @param string $path
203221
*
@@ -237,6 +255,15 @@ private static function getVendors()
237255
$v = \dirname(\dirname($r->getFileName()));
238256
if (file_exists($v.'/composer/installed.json')) {
239257
self::$vendors[] = $v;
258+
$loader = require $v.'/autoload.php';
259+
$paths = self::getSourcePathsFromPrefixes(array_merge($loader->getPrefixes(), $loader->getPrefixesPsr4()));
260+
}
261+
}
262+
}
263+
foreach ($paths as $path) {
264+
foreach (self::$vendors as $vendor) {
265+
if (0 !== strpos($path, $vendor)) {
266+
self::$internalPaths[] = $path;
240267
}
241268
}
242269
}
@@ -245,24 +272,41 @@ private static function getVendors()
245272
return self::$vendors;
246273
}
247274

275+
private static function getSourcePathsFromPrefixes(array $prefixesByNamespace)
276+
{
277+
foreach ($prefixesByNamespace as $prefixes) {
278+
foreach ($prefixes as $prefix) {
279+
if (false !== realpath($prefix)) {
280+
yield realpath($prefix);
281+
}
282+
}
283+
}
284+
}
285+
248286
/**
249287
* @param string $path
250288
*
251-
* @return bool
289+
* @return string
252290
*/
253-
private function pathOriginatesFromVendor($path)
291+
private function getPathType($path)
254292
{
255293
$realPath = realpath($path);
256294
if (false === $realPath && '-' !== $path && 'Standard input code' !== $path) {
257-
return true;
295+
return self::PATH_TYPE_UNDETERMINED;
258296
}
259297
foreach (self::getVendors() as $vendor) {
260298
if (0 === strpos($realPath, $vendor) && false !== strpbrk(substr($realPath, \strlen($vendor), 1), '/'.\DIRECTORY_SEPARATOR)) {
261-
return true;
299+
return self::PATH_TYPE_VENDOR;
300+
}
301+
}
302+
303+
foreach (self::$internalPaths as $internalPath) {
304+
if (0 === strpos($realPath, $internalPath)) {
305+
return self::PATH_TYPE_SELF;
262306
}
263307
}
264308

265-
return false;
309+
return self::PATH_TYPE_UNDETERMINED;
266310
}
267311

268312
/**

src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/DeprecationTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public function testItCanDetermineTheClassWhereTheDeprecationHappened()
2727
public function testItCanTellWhetherItIsInternal()
2828
{
2929
$deprecation = new Deprecation('💩', $this->debugBacktrace(), __FILE__);
30-
$this->assertTrue($deprecation->isSelf());
30+
$this->assertSame(Deprecation::TYPE_SELF, $deprecation->getType());
3131
}
3232

3333
public function testLegacyTestMethodIsDetectedAsSuch()
@@ -46,7 +46,7 @@ public function testItCanBeConvertedToAString()
4646
public function testItRulesOutFilesOutsideVendorsAsIndirect()
4747
{
4848
$deprecation = new Deprecation('💩', $this->debugBacktrace(), __FILE__);
49-
$this->assertFalse($deprecation->isIndirect());
49+
$this->assertNotSame(Deprecation::TYPE_INDIRECT, $deprecation->getType());
5050
}
5151

5252
/**

src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/default.phpt

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -73,15 +73,13 @@ Unsilenced deprecation notices (3)
7373
1x: unsilenced bar deprecation
7474
1x in FooTestCase::testNonLegacyBar
7575

76-
Remaining self deprecation notices (1)
77-
78-
1x: silenced bar deprecation
79-
1x in FooTestCase::testNonLegacyBar
80-
8176
Legacy deprecation notices (1)
8277

83-
Other deprecation notices (1)
78+
Other deprecation notices (2)
8479

8580
1x: root deprecation
8681

82+
1x: silenced bar deprecation
83+
1x in FooTestCase::testNonLegacyBar
84+
8785
I get precedence over any exit statements inside the deprecation error handler.
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
<?php
22

33
require_once __DIR__.'/composer/autoload_real.php';
4+
5+
return ComposerAutoloaderInitFake::getLoader();
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,22 @@
11
<?php
22

3+
class ComposerLoaderFake
4+
{
5+
public function getPrefixes()
6+
{
7+
return [];
8+
}
9+
10+
public function getPrefixesPsr4()
11+
{
12+
return [];
13+
}
14+
}
15+
316
class ComposerAutoloaderInitFake
417
{
18+
public static function getLoader()
19+
{
20+
return new ComposerLoaderFake();
21+
}
522
}

src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/self_on_non_vendor.phpt

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -61,14 +61,12 @@ Unsilenced deprecation notices (3)
6161
1x: unsilenced bar deprecation
6262
1x in FooTestCase::testNonLegacyBar
6363

64-
Remaining self deprecation notices (1)
65-
66-
1x: silenced bar deprecation
67-
1x in FooTestCase::testNonLegacyBar
68-
6964
Legacy deprecation notices (1)
7065

71-
Other deprecation notices (1)
66+
Other deprecation notices (2)
7267

7368
1x: root deprecation
7469

70+
1x: silenced bar deprecation
71+
1x in FooTestCase::testNonLegacyBar
72+

src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/shutdown_deprecations.phpt

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -73,17 +73,15 @@ Unsilenced deprecation notices (3)
7373
1x: unsilenced bar deprecation
7474
1x in FooTestCase::testNonLegacyBar
7575

76-
Remaining self deprecation notices (1)
77-
78-
1x: silenced bar deprecation
79-
1x in FooTestCase::testNonLegacyBar
80-
8176
Legacy deprecation notices (1)
8277

83-
Other deprecation notices (1)
78+
Other deprecation notices (2)
8479

8580
1x: root deprecation
8681

82+
1x: silenced bar deprecation
83+
1x in FooTestCase::testNonLegacyBar
84+
8785
Shutdown-time deprecations:
8886

8987
Other deprecation notices (1)

src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/weak_vendors_on_non_vendor.phpt

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -61,14 +61,13 @@ Unsilenced deprecation notices (3)
6161
1x: unsilenced bar deprecation
6262
1x in FooTestCase::testNonLegacyBar
6363

64-
Remaining self deprecation notices (1)
65-
66-
1x: silenced bar deprecation
67-
1x in FooTestCase::testNonLegacyBar
68-
6964
Legacy deprecation notices (1)
7065

71-
Other deprecation notices (1)
66+
Other deprecation notices (2)
7267

7368
1x: root deprecation
7469

70+
1x: silenced bar deprecation
71+
1x in FooTestCase::testNonLegacyBar
72+
73+

0 commit comments

Comments
 (0)
0