Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 9ef2619

Browse filesBrowse files
greg0ireGrégoire Paris
authored and
Grégoire Paris
committed
Introduce weak_lagging_vendors mode
In this mode, failures coming from vendors that call other vendors in a deprecated way are not taken into account when deciding to make the build fail. They also appear in a separate group.
1 parent e2cc16a commit 9ef2619
Copy full SHA for 9ef2619

File tree

5 files changed

+166
-7
lines changed
Filter options

5 files changed

+166
-7
lines changed

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

Copy file name to clipboardExpand all lines: src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php
+69-7Lines changed: 69 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ class DeprecationErrorHandler
2020
{
2121
const MODE_WEAK = 'weak';
2222
const MODE_WEAK_VENDORS = 'weak_vendors';
23+
const MODE_WEAK_LAGGING_VENDORS = 'weak_lagging_vendors';
2324
const MODE_DISABLED = 'disabled';
2425

2526
private static $isRegistered = false;
@@ -30,6 +31,8 @@ class DeprecationErrorHandler
3031
* The following reporting modes are supported:
3132
* - use "weak" to hide the deprecation report but keep a global count;
3233
* - use "weak_vendors" to act as "weak" but only for vendors;
34+
* - use "weak_lagging_vendors" to act as "weak" but only for vendors that
35+
* failed to keep up with their upstream dependencies deprecations;
3336
* - use "/some-regexp/" to stop the test suite whenever a deprecation
3437
* message matches the given regular expression;
3538
* - use a number to define the upper bound of allowed deprecations,
@@ -54,24 +57,29 @@ public static function register($mode = 0)
5457
if (false === $mode) {
5558
$mode = getenv('SYMFONY_DEPRECATIONS_HELPER');
5659
}
57-
if (DeprecationErrorHandler::MODE_WEAK !== $mode && DeprecationErrorHandler::MODE_WEAK_VENDORS !== $mode && (!isset($mode[0]) || '/' !== $mode[0])) {
60+
if (!in_array($mode, array(
61+
DeprecationErrorHandler::MODE_WEAK,
62+
DeprecationErrorHandler::MODE_WEAK_VENDORS,
63+
DeprecationErrorHandler::MODE_WEAK_LAGGING_VENDORS,
64+
), true) && (!isset($mode[0]) || '/' !== $mode[0])) {
5865
$mode = preg_match('/^[1-9][0-9]*$/', $mode) ? (int) $mode : 0;
5966
}
6067

6168
return $memoizedMode = $mode;
6269
};
6370

64-
6571
$deprecations = array(
6672
'unsilencedCount' => 0,
6773
'remainingCount' => 0,
6874
'legacyCount' => 0,
6975
'otherCount' => 0,
76+
'lagging vendorCount' => 0,
7077
'remaining vendorCount' => 0,
7178
'unsilenced' => array(),
7279
'remaining' => array(),
7380
'legacy' => array(),
7481
'other' => array(),
82+
'lagging vendor' => array(),
7583
'remaining vendor' => array(),
7684
);
7785
$deprecationHandler = function ($type, $msg, $file, $line, $context = array()) use (&$deprecations, $getMode, $UtilPrefix) {
@@ -85,8 +93,9 @@ public static function register($mode = 0)
8593
$trace = debug_backtrace(true);
8694
$group = 'other';
8795

88-
$isWeak = DeprecationErrorHandler::MODE_WEAK === $mode || (DeprecationErrorHandler::MODE_WEAK_VENDORS === $mode && $isVendor = self::inVendors($file));
89-
96+
$isWeak = DeprecationErrorHandler::MODE_WEAK === $mode ||
97+
(DeprecationErrorHandler::MODE_WEAK_VENDORS === $mode && $isVendor = self::inVendors($file)) ||
98+
(DeprecationErrorHandler::MODE_WEAK_LAGGING_VENDORS === $mode && $isLaggingVendor = self::isLaggingVendor($trace));
9099
$i = count($trace);
91100
while (1 < $i && (!isset($trace[--$i]['class']) || ('ReflectionMethod' === $trace[$i]['class'] || 0 === strpos($trace[$i]['class'], 'PHPUnit_') || 0 === strpos($trace[$i]['class'], 'PHPUnit\\')))) {
92101
// No-op
@@ -114,6 +123,8 @@ public static function register($mode = 0)
114123
|| in_array('legacy', $Test::getGroups($class, $method), true)
115124
) {
116125
$group = 'legacy';
126+
} elseif (DeprecationErrorHandler::MODE_WEAK_LAGGING_VENDORS === $mode && $isLaggingVendor) {
127+
$group = 'lagging vendor';
117128
} elseif (DeprecationErrorHandler::MODE_WEAK_VENDORS === $mode && $isVendor) {
118129
$group = 'remaining vendor';
119130
} else {
@@ -188,13 +199,16 @@ public static function register($mode = 0)
188199
if (DeprecationErrorHandler::MODE_WEAK_VENDORS === $mode) {
189200
$groups[] = 'remaining vendor';
190201
}
202+
if (DeprecationErrorHandler::MODE_WEAK_LAGGING_VENDORS === $mode) {
203+
$groups[] = 'lagging vendor';
204+
}
191205
array_push($groups, 'legacy', 'other');
192206

193207
foreach ($groups as $group) {
194208
if ($deprecations[$group.'Count']) {
195209
echo "\n", $colorize(
196210
sprintf('%s deprecation notices (%d)', ucfirst($group), $deprecations[$group.'Count']),
197-
'legacy' !== $group && 'remaining vendor' !== $group
211+
!in_array($group, array('legacy', 'remaining vendor', 'lagging vendor'), true)
198212
), "\n";
199213

200214
uasort($deprecations[$group], $cmp);
@@ -223,10 +237,52 @@ public static function register($mode = 0)
223237
}
224238
}
225239

226-
private static function inVendors(string $path): bool
240+
private static function isLaggingVendor(array $trace): bool
241+
{
242+
foreach ($trace as $line) {
243+
if (isset($line['file'])) {
244+
$file = $line['file'];
245+
if ('-' === $file) {
246+
continue;
247+
}
248+
if (!self::inVendors($file)) {
249+
return false;
250+
}
251+
if (isset($erroringFile, $erroringPackage)) {
252+
if (self::getPackage($file) !== $erroringPackage) {
253+
return true;
254+
}
255+
} else {
256+
$erroringFile = $file;
257+
$erroringPackage = self::getPackage($file);
258+
}
259+
}
260+
}
261+
262+
return false;
263+
}
264+
265+
/**
266+
* inVendors() should always be called prior to calling this method.
267+
*/
268+
private static function getPackage(string $path): string
269+
{
270+
$path = realpath($path) ?: $path;
271+
foreach (self::getVendors() as $vendorRoot) {
272+
if (0 === strpos($path, $vendorRoot)) {
273+
$relativePath = substr($path, strlen($vendorRoot) + 1);
274+
$vendor = strstr($relativePath, DIRECTORY_SEPARATOR, true);
275+
276+
return $vendor.'/'.strstr(substr($relativePath, strlen($vendor) + 1), DIRECTORY_SEPARATOR, true);
277+
}
278+
}
279+
}
280+
281+
private static function getVendors(): ?array
227282
{
228283
/** @var string[] absolute paths to vendor directories */
229284
static $vendors;
285+
230286
if (null === $vendors) {
231287
foreach (get_declared_classes() as $class) {
232288
if ('C' === $class[0] && 0 === strpos($class, 'ComposerAutoloaderInit')) {
@@ -238,8 +294,14 @@ private static function inVendors(string $path): bool
238294
}
239295
}
240296
}
297+
298+
return $vendors;
299+
}
300+
301+
private static function inVendors(string $path): bool
302+
{
241303
$path = realpath($path) ?: $path;
242-
foreach ($vendors as $vendor) {
304+
foreach (self::getVendors() as $vendor) {
243305
if (0 === strpos($path, $vendor) && false !== strpbrk(substr($path, strlen($vendor), 1), '/'.DIRECTORY_SEPARATOR)) {
244306
return true;
245307
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?php
2+
/* We have not caught up on the deprecations yet and still call the other lib
3+
in a deprecated way. */
4+
5+
include __DIR__.'/../lib/deprecated_api.php';
6+
$defraculator = new \Acme\Lib\SomeService();
7+
$defraculator->deprecatedApi();
+13Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
namespace Acme\Lib;
3+
4+
class SomeService
5+
{
6+
public function deprecatedApi()
7+
{
8+
@trigger_error(
9+
__FUNCTION__.' is deprecated! You should stop relying on it!',
10+
E_USER_DEPRECATED
11+
);
12+
}
13+
}
+42Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
--TEST--
2+
Test DeprecationErrorHandler in weak vendors mode when calling deprecated api
3+
--FILE--
4+
<?php
5+
6+
putenv('SYMFONY_DEPRECATIONS_HELPER=weak_lagging_vendors');
7+
putenv('ANSICON');
8+
putenv('ConEmuANSI');
9+
putenv('TERM');
10+
11+
$vendor = __DIR__;
12+
while (!file_exists($vendor.'/vendor')) {
13+
$vendor = dirname($vendor);
14+
}
15+
define('PHPUNIT_COMPOSER_INSTALL', $vendor.'/vendor/autoload.php');
16+
require PHPUNIT_COMPOSER_INSTALL;
17+
require_once __DIR__.'/../../bootstrap.php';
18+
eval(<<<'EOPHP'
19+
namespace PHPUnit\Util;
20+
21+
class Test
22+
{
23+
public static function getGroups()
24+
{
25+
return array();
26+
}
27+
}
28+
EOPHP
29+
);
30+
require __DIR__.'/fake_vendor/autoload.php';
31+
require __DIR__.'/fake_vendor/acme/lib/deprecated_api.php';
32+
$defraculator = new \Acme\Lib\SomeService();
33+
$defraculator->deprecatedApi();
34+
35+
36+
?>
37+
--EXPECTF--
38+
Remaining deprecation notices (1)
39+
40+
deprecatedApi is deprecated! You should stop relying on it!: 1x
41+
1x in SomeService::deprecatedApi from Acme\Lib
42+
+35Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
--TEST--
2+
Test DeprecationErrorHandler in weak vendors mode on vendor file
3+
--FILE--
4+
<?php
5+
6+
putenv('SYMFONY_DEPRECATIONS_HELPER=weak_lagging_vendors');
7+
putenv('ANSICON');
8+
putenv('ConEmuANSI');
9+
putenv('TERM');
10+
11+
$vendor = __DIR__;
12+
while (!file_exists($vendor.'/vendor')) {
13+
$vendor = dirname($vendor);
14+
}
15+
define('PHPUNIT_COMPOSER_INSTALL', $vendor.'/vendor/autoload.php');
16+
require PHPUNIT_COMPOSER_INSTALL;
17+
require_once __DIR__.'/../../bootstrap.php';
18+
eval(<<<'EOPHP'
19+
namespace PHPUnit\Util;
20+
21+
class Test
22+
{
23+
public static function getGroups()
24+
{
25+
return array();
26+
}
27+
}
28+
EOPHP
29+
);
30+
require __DIR__.'/fake_vendor/autoload.php';
31+
require __DIR__.'/fake_vendor/acme/lagging-lib/lagging_file.php';
32+
33+
?>
34+
--EXPECTF--
35+
Lagging vendor deprecation notices (1)

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.