From 4a02b813b4aaf933b0e4a70f1bfcf82c8bc26ec0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Paris?= Date: Tue, 7 Nov 2017 22:36:17 +0100 Subject: [PATCH 1/8] Refactor inVendors to a private static method Now that we have php 7, we can afford to do this. --- .../PhpUnit/DeprecationErrorHandler.php | 61 ++++++++++--------- 1 file changed, 31 insertions(+), 30 deletions(-) diff --git a/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php b/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php index dcdb0df8efddf..0a7a533fd7411 100644 --- a/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php +++ b/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php @@ -61,33 +61,6 @@ public static function register($mode = 0) return $memoizedMode = $mode; }; - $inVendors = function ($path) { - /** @var string[] absolute paths to vendor directories */ - static $vendors; - if (null === $vendors) { - foreach (get_declared_classes() as $class) { - if ('C' === $class[0] && 0 === strpos($class, 'ComposerAutoloaderInit')) { - $r = new \ReflectionClass($class); - $v = dirname(dirname($r->getFileName())); - if (file_exists($v.'/composer/installed.json')) { - $vendors[] = $v; - } - } - } - } - $realPath = realpath($path); - if (false === $realPath && '-' !== $path && 'Standard input code' !== $path) { - return true; - } - foreach ($vendors as $vendor) { - if (0 === strpos($realPath, $vendor) && false !== strpbrk(substr($realPath, strlen($vendor), 1), '/'.DIRECTORY_SEPARATOR)) { - return true; - } - } - - return false; - }; - $deprecations = array( 'unsilencedCount' => 0, 'remainingCount' => 0, @@ -100,7 +73,7 @@ public static function register($mode = 0) 'other' => array(), 'remaining vendor' => array(), ); - $deprecationHandler = function ($type, $msg, $file, $line, $context = array()) use (&$deprecations, $getMode, $UtilPrefix, $inVendors) { + $deprecationHandler = function ($type, $msg, $file, $line, $context = array()) use (&$deprecations, $getMode, $UtilPrefix) { $mode = $getMode(); if ((E_USER_DEPRECATED !== $type && E_DEPRECATED !== $type) || DeprecationErrorHandler::MODE_DISABLED === $mode) { $ErrorHandler = $UtilPrefix.'ErrorHandler'; @@ -111,7 +84,7 @@ public static function register($mode = 0) $trace = debug_backtrace(true); $group = 'other'; $isVendor = false; - $isWeak = DeprecationErrorHandler::MODE_WEAK === $mode || (DeprecationErrorHandler::MODE_WEAK_VENDORS === $mode && $isVendor = $inVendors($file)); + $isWeak = DeprecationErrorHandler::MODE_WEAK === $mode || (DeprecationErrorHandler::MODE_WEAK_VENDORS === $mode && $isVendor = self::inVendors($file)); $i = count($trace); while (1 < $i && (!isset($trace[--$i]['class']) || ('ReflectionMethod' === $trace[$i]['class'] || 0 === strpos($trace[$i]['class'], 'PHPUnit_') || 0 === strpos($trace[$i]['class'], 'PHPUnit\\')))) { @@ -128,7 +101,7 @@ public static function register($mode = 0) // \Symfony\Bridge\PhpUnit\Legacy\SymfonyTestsListenerTrait::endTest() // then we need to use the serialized information to determine // if the error has been triggered from vendor code. - $isWeak = DeprecationErrorHandler::MODE_WEAK === $mode || (DeprecationErrorHandler::MODE_WEAK_VENDORS === $mode && $isVendor = isset($parsedMsg['triggering_file']) && $inVendors($parsedMsg['triggering_file'])); + $isWeak = DeprecationErrorHandler::MODE_WEAK === $mode || (DeprecationErrorHandler::MODE_WEAK_VENDORS === $mode && $isVendor = isset($parsedMsg['triggering_file']) && self::inVendors($parsedMsg['triggering_file'])); } else { $class = isset($trace[$i]['object']) ? get_class($trace[$i]['object']) : $trace[$i]['class']; $method = $trace[$i]['function']; @@ -254,6 +227,34 @@ public static function register($mode = 0) } } + private static function inVendors(string $path): bool + { + /** @var string[] absolute paths to vendor directories */ + static $vendors; + if (null === $vendors) { + foreach (get_declared_classes() as $class) { + if ('C' === $class[0] && 0 === strpos($class, 'ComposerAutoloaderInit')) { + $r = new \ReflectionClass($class); + $v = dirname(dirname($r->getFileName())); + if (file_exists($v.'/composer/installed.json')) { + $vendors[] = $v; + } + } + } + } + $realPath = realpath($path); + if (false === $realPath && '-' !== $path && 'Standard input code' !== $path) { + return true; + } + foreach ($vendors as $vendor) { + if (0 === strpos($realPath, $vendor) && false !== strpbrk(substr($realPath, strlen($vendor), 1), '/'.DIRECTORY_SEPARATOR)) { + return true; + } + } + + return false; + } + public static function collectDeprecations($outputFile) { $deprecations = array(); From 9fdbe2bbc9f50414d2c8089f08721801215b7f06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Paris?= Date: Sat, 4 Nov 2017 00:27:59 +0100 Subject: [PATCH 2/8] 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. --- .../PhpUnit/DeprecationErrorHandler.php | 84 +++++++++++++++++-- .../acme/lagging-lib/lagging_file.php | 7 ++ .../fake_vendor/acme/lib/SomeService.php | 14 ++++ ...ak_lagging_vendors_directly_on_vendor.phpt | 42 ++++++++++ ...eak_lagging_vendors_on_lagging_vendor.phpt | 35 ++++++++ 5 files changed, 175 insertions(+), 7 deletions(-) create mode 100644 src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/fake_vendor/acme/lagging-lib/lagging_file.php create mode 100644 src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/fake_vendor/acme/lib/SomeService.php create mode 100644 src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/weak_lagging_vendors_directly_on_vendor.phpt create mode 100644 src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/weak_lagging_vendors_on_lagging_vendor.phpt diff --git a/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php b/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php index 0a7a533fd7411..0d4036a3b7b01 100644 --- a/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php +++ b/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php @@ -20,6 +20,7 @@ class DeprecationErrorHandler { const MODE_WEAK = 'weak'; const MODE_WEAK_VENDORS = 'weak_vendors'; + const MODE_WEAK_LAGGING_VENDORS = 'weak_lagging_vendors'; const MODE_DISABLED = 'disabled'; private static $isRegistered = false; @@ -30,6 +31,8 @@ class DeprecationErrorHandler * The following reporting modes are supported: * - use "weak" to hide the deprecation report but keep a global count; * - use "weak_vendors" to act as "weak" but only for vendors; + * - use "weak_lagging_vendors" to act as "weak" but only for vendors that + * failed to keep up with their upstream dependencies deprecations; * - use "/some-regexp/" to stop the test suite whenever a deprecation * message matches the given regular expression; * - use a number to define the upper bound of allowed deprecations, @@ -54,7 +57,11 @@ public static function register($mode = 0) if (false === $mode) { $mode = getenv('SYMFONY_DEPRECATIONS_HELPER'); } - if (DeprecationErrorHandler::MODE_WEAK !== $mode && DeprecationErrorHandler::MODE_WEAK_VENDORS !== $mode && (!isset($mode[0]) || '/' !== $mode[0])) { + if (!in_array($mode, array( + DeprecationErrorHandler::MODE_WEAK, + DeprecationErrorHandler::MODE_WEAK_VENDORS, + DeprecationErrorHandler::MODE_WEAK_LAGGING_VENDORS, + ), true) && (!isset($mode[0]) || '/' !== $mode[0])) { $mode = preg_match('/^[1-9][0-9]*$/', $mode) ? (int) $mode : 0; } @@ -66,11 +73,13 @@ public static function register($mode = 0) 'remainingCount' => 0, 'legacyCount' => 0, 'otherCount' => 0, + 'lagging vendorCount' => 0, 'remaining vendorCount' => 0, 'unsilenced' => array(), 'remaining' => array(), 'legacy' => array(), 'other' => array(), + 'lagging vendor' => array(), 'remaining vendor' => array(), ); $deprecationHandler = function ($type, $msg, $file, $line, $context = array()) use (&$deprecations, $getMode, $UtilPrefix) { @@ -84,8 +93,9 @@ public static function register($mode = 0) $trace = debug_backtrace(true); $group = 'other'; $isVendor = false; - $isWeak = DeprecationErrorHandler::MODE_WEAK === $mode || (DeprecationErrorHandler::MODE_WEAK_VENDORS === $mode && $isVendor = self::inVendors($file)); - + $isWeak = DeprecationErrorHandler::MODE_WEAK === $mode || + (DeprecationErrorHandler::MODE_WEAK_VENDORS === $mode && $isVendor = self::inVendors($file)) || + (DeprecationErrorHandler::MODE_WEAK_LAGGING_VENDORS === $mode && $isLaggingVendor = self::isLaggingVendor($trace)); $i = count($trace); while (1 < $i && (!isset($trace[--$i]['class']) || ('ReflectionMethod' === $trace[$i]['class'] || 0 === strpos($trace[$i]['class'], 'PHPUnit_') || 0 === strpos($trace[$i]['class'], 'PHPUnit\\')))) { // No-op @@ -101,7 +111,9 @@ public static function register($mode = 0) // \Symfony\Bridge\PhpUnit\Legacy\SymfonyTestsListenerTrait::endTest() // then we need to use the serialized information to determine // if the error has been triggered from vendor code. - $isWeak = DeprecationErrorHandler::MODE_WEAK === $mode || (DeprecationErrorHandler::MODE_WEAK_VENDORS === $mode && $isVendor = isset($parsedMsg['triggering_file']) && self::inVendors($parsedMsg['triggering_file'])); + $isWeak = DeprecationErrorHandler::MODE_WEAK === $mode || + (DeprecationErrorHandler::MODE_WEAK_VENDORS === $mode && $isVendor = isset($parsedMsg['triggering_file']) && self::inVendors($parsedMsg['triggering_file'])) || + (DeprecationErrorHandler::MODE_WEAK_LAGGING_VENDORS === $mode); // not enough information to make the right call, so let's be lenient } else { $class = isset($trace[$i]['object']) ? get_class($trace[$i]['object']) : $trace[$i]['class']; $method = $trace[$i]['function']; @@ -118,6 +130,8 @@ public static function register($mode = 0) || in_array('legacy', $Test::getGroups($class, $method), true) ) { $group = 'legacy'; + } elseif (DeprecationErrorHandler::MODE_WEAK_LAGGING_VENDORS === $mode && $isLaggingVendor) { + $group = 'lagging vendor'; } elseif (DeprecationErrorHandler::MODE_WEAK_VENDORS === $mode && $isVendor) { $group = 'remaining vendor'; } else { @@ -192,13 +206,16 @@ public static function register($mode = 0) if (DeprecationErrorHandler::MODE_WEAK_VENDORS === $mode) { $groups[] = 'remaining vendor'; } + if (DeprecationErrorHandler::MODE_WEAK_LAGGING_VENDORS === $mode) { + $groups[] = 'lagging vendor'; + } array_push($groups, 'legacy', 'other'); foreach ($groups as $group) { if ($deprecations[$group.'Count']) { echo "\n", $colorize( sprintf('%s deprecation notices (%d)', ucfirst($group), $deprecations[$group.'Count']), - 'legacy' !== $group && 'remaining vendor' !== $group + !in_array($group, array('legacy', 'remaining vendor', 'lagging vendor'), true) ), "\n"; uasort($deprecations[$group], $cmp); @@ -227,11 +244,58 @@ public static function register($mode = 0) } } - private static function inVendors(string $path): bool + private static function isLaggingVendor(array $trace): bool + { + $erroringFile = $erroringPackage = null; + foreach ($trace as $line) { + if (!isset($line['file'])) { + continue; + } + $file = $line['file']; + if ('-' === $file) { + continue; + } + if (!self::inVendors($file)) { + return false; + } + if (null !== $erroringFile && null !== $erroringPackage) { + if (self::getPackage($file) !== $erroringPackage) { + return true; + } + } else { + $erroringFile = $file; + $erroringPackage = self::getPackage($file); + } + } + + return false; + } + + /** + * inVendors() should always be called prior to calling this method. + */ + private static function getPackage(string $path): string + { + $path = realpath($path) ?: $path; + foreach (self::getVendors() as $vendorRoot) { + if (0 === strpos($path, $vendorRoot)) { + $relativePath = substr($path, strlen($vendorRoot) + 1); + $vendor = strstr($relativePath, DIRECTORY_SEPARATOR, true); + + return $vendor.'/'.strstr(substr($relativePath, strlen($vendor) + 1), DIRECTORY_SEPARATOR, true); + } + } + + throw new \RuntimeException('No vendors found'); + } + + private static function getVendors(): array { /** @var string[] absolute paths to vendor directories */ static $vendors; + if (null === $vendors) { + $vendors = array(); foreach (get_declared_classes() as $class) { if ('C' === $class[0] && 0 === strpos($class, 'ComposerAutoloaderInit')) { $r = new \ReflectionClass($class); @@ -242,11 +306,17 @@ private static function inVendors(string $path): bool } } } + + return $vendors; + } + + private static function inVendors(string $path): bool + { $realPath = realpath($path); if (false === $realPath && '-' !== $path && 'Standard input code' !== $path) { return true; } - foreach ($vendors as $vendor) { + foreach (self::getVendors() as $vendor) { if (0 === strpos($realPath, $vendor) && false !== strpbrk(substr($realPath, strlen($vendor), 1), '/'.DIRECTORY_SEPARATOR)) { return true; } diff --git a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/fake_vendor/acme/lagging-lib/lagging_file.php b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/fake_vendor/acme/lagging-lib/lagging_file.php new file mode 100644 index 0000000000000..73d8d6a5782dc --- /dev/null +++ b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/fake_vendor/acme/lagging-lib/lagging_file.php @@ -0,0 +1,7 @@ +deprecatedApi(); diff --git a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/fake_vendor/acme/lib/SomeService.php b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/fake_vendor/acme/lib/SomeService.php new file mode 100644 index 0000000000000..6a354103ff3ce --- /dev/null +++ b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/fake_vendor/acme/lib/SomeService.php @@ -0,0 +1,14 @@ +deprecatedApi(); + + +?> +--EXPECTF-- +Remaining deprecation notices (1) + +deprecatedApi is deprecated! You should stop relying on it!: 1x + 1x in SomeService::deprecatedApi from acme\lib + diff --git a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/weak_lagging_vendors_on_lagging_vendor.phpt b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/weak_lagging_vendors_on_lagging_vendor.phpt new file mode 100644 index 0000000000000..50c7f79971a6f --- /dev/null +++ b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/weak_lagging_vendors_on_lagging_vendor.phpt @@ -0,0 +1,35 @@ +--TEST-- +Test DeprecationErrorHandler in weak vendors mode on vendor file +--FILE-- + +--EXPECTF-- +Lagging vendor deprecation notices (1) From b17db802a2530f163cdf6c4b837d0ea440b0d22e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Paris?= Date: Sun, 28 Jan 2018 20:52:11 +0100 Subject: [PATCH 3/8] Skip if php 7.2 and php input or phar --- src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php b/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php index 0d4036a3b7b01..fdda4317470c2 100644 --- a/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php +++ b/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php @@ -252,7 +252,7 @@ private static function isLaggingVendor(array $trace): bool continue; } $file = $line['file']; - if ('-' === $file) { + if ('-' === $file || 'Standard input code' === $file || !realpath($file)) { continue; } if (!self::inVendors($file)) { From de52e933fae70c355a5c5092d622cc2e106213e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Paris?= Date: Sun, 28 Jan 2018 20:52:48 +0100 Subject: [PATCH 4/8] Give out more details --- src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php b/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php index fdda4317470c2..eb86e4361e888 100644 --- a/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php +++ b/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php @@ -286,7 +286,10 @@ private static function getPackage(string $path): string } } - throw new \RuntimeException('No vendors found'); + throw new \RuntimeException(sprintf( + 'No vendors found for path "%s"', + $path + )); } private static function getVendors(): array From 8566bd6416af4d461e070ca4c0c2b86ec3178ba6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Paris?= Date: Sun, 28 Jan 2018 20:53:10 +0100 Subject: [PATCH 5/8] Include the trace in the deprecation metadata --- src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php | 4 ++-- .../Bridge/PhpUnit/Legacy/SymfonyTestsListenerTrait.php | 8 +++++++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php b/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php index eb86e4361e888..659b53fabeb67 100644 --- a/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php +++ b/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php @@ -113,7 +113,7 @@ public static function register($mode = 0) // if the error has been triggered from vendor code. $isWeak = DeprecationErrorHandler::MODE_WEAK === $mode || (DeprecationErrorHandler::MODE_WEAK_VENDORS === $mode && $isVendor = isset($parsedMsg['triggering_file']) && self::inVendors($parsedMsg['triggering_file'])) || - (DeprecationErrorHandler::MODE_WEAK_LAGGING_VENDORS === $mode); // not enough information to make the right call, so let's be lenient + (DeprecationErrorHandler::MODE_WEAK_LAGGING_VENDORS === $mode) && $isLaggingVendor = isset($parsedMsg['trace']) && self::isLaggingVendor($parsedMsg['trace']); } else { $class = isset($trace[$i]['object']) ? get_class($trace[$i]['object']) : $trace[$i]['class']; $method = $trace[$i]['function']; @@ -343,7 +343,7 @@ public static function collectDeprecations($outputFile) return $ErrorHandler::handleError($type, $msg, $file, $line, $context); } - $deprecations[] = array(error_reporting(), $msg, $file); + $deprecations[] = array(error_reporting(), $msg, $file, debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS)); }); register_shutdown_function(function () use ($outputFile, &$deprecations) { diff --git a/src/Symfony/Bridge/PhpUnit/Legacy/SymfonyTestsListenerTrait.php b/src/Symfony/Bridge/PhpUnit/Legacy/SymfonyTestsListenerTrait.php index 7ded32a782464..6cd53914887fe 100644 --- a/src/Symfony/Bridge/PhpUnit/Legacy/SymfonyTestsListenerTrait.php +++ b/src/Symfony/Bridge/PhpUnit/Legacy/SymfonyTestsListenerTrait.php @@ -263,7 +263,13 @@ public function endTest($test, $time) unlink($this->runsInSeparateProcess); putenv('SYMFONY_DEPRECATIONS_SERIALIZE'); foreach ($deprecations ? unserialize($deprecations) : array() as $deprecation) { - $error = serialize(array('deprecation' => $deprecation[1], 'class' => $className, 'method' => $test->getName(false), 'triggering_file' => isset($deprecation[2]) ? $deprecation[2] : null)); + $error = serialize(array( + 'deprecation' => $deprecation[1], + 'class' => $className, + 'method' => $test->getName(false), + 'triggering_file' => isset($deprecation[2]) ? $deprecation[2] : null, + 'trace' => isset($deprecation[3]) ? $deprecation[3] : null, + )); if ($deprecation[0]) { trigger_error($error, E_USER_DEPRECATED); } else { From cc6e2bbfc377bbd6ba9e80ce5a0618e23dcbb80a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Paris?= Date: Sun, 28 Jan 2018 20:57:15 +0100 Subject: [PATCH 6/8] Adapt to new message format --- .../weak_lagging_vendors_directly_on_vendor.phpt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/weak_lagging_vendors_directly_on_vendor.phpt b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/weak_lagging_vendors_directly_on_vendor.phpt index 765956fbfcf21..067f6b23a83de 100644 --- a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/weak_lagging_vendors_directly_on_vendor.phpt +++ b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/weak_lagging_vendors_directly_on_vendor.phpt @@ -37,6 +37,6 @@ $defraculator->deprecatedApi(); --EXPECTF-- Remaining deprecation notices (1) -deprecatedApi is deprecated! You should stop relying on it!: 1x + 1x: deprecatedApi is deprecated! You should stop relying on it! 1x in SomeService::deprecatedApi from acme\lib From f613ebf81d88dd37d546a11a95b69c4af9931d44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Paris?= Date: Sun, 28 Jan 2018 21:00:54 +0100 Subject: [PATCH 7/8] Refactor static variable to static property This is slightly less weird than a static local variable. --- .../Bridge/PhpUnit/DeprecationErrorHandler.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php b/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php index 659b53fabeb67..4556f76620aeb 100644 --- a/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php +++ b/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php @@ -25,6 +25,9 @@ class DeprecationErrorHandler private static $isRegistered = false; + /** @var string[] absolute paths to vendor directories */ + private static $vendors; + /** * Registers and configures the deprecation handler. * @@ -294,23 +297,20 @@ private static function getPackage(string $path): string private static function getVendors(): array { - /** @var string[] absolute paths to vendor directories */ - static $vendors; - - if (null === $vendors) { - $vendors = array(); + if (null === self::$vendors) { + self::$vendors = array(); foreach (get_declared_classes() as $class) { if ('C' === $class[0] && 0 === strpos($class, 'ComposerAutoloaderInit')) { $r = new \ReflectionClass($class); $v = dirname(dirname($r->getFileName())); if (file_exists($v.'/composer/installed.json')) { - $vendors[] = $v; + self::$vendors[] = $v; } } } } - return $vendors; + return self::$vendors; } private static function inVendors(string $path): bool From 4d404070135e28d803d5914a236e101c15a5ec0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Paris?= Date: Mon, 29 Jan 2018 19:35:56 +0100 Subject: [PATCH 8/8] Refactor lagging into outdated --- .../PhpUnit/DeprecationErrorHandler.php | 26 +++++++++---------- ..._outdated_vendors_directly_on_vendor.phpt} | 2 +- ...w_outdated_vendors_on_lagging_vendor.phpt} | 6 ++--- .../outdated_file.php} | 0 4 files changed, 17 insertions(+), 17 deletions(-) rename src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/{weak_lagging_vendors_directly_on_vendor.phpt => allow_outdated_vendors_directly_on_vendor.phpt} (93%) rename src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/{weak_lagging_vendors_on_lagging_vendor.phpt => allow_outdated_vendors_on_lagging_vendor.phpt} (77%) rename src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/fake_vendor/acme/{lagging-lib/lagging_file.php => outdated-lib/outdated_file.php} (100%) diff --git a/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php b/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php index 4556f76620aeb..8d8b9d41a0304 100644 --- a/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php +++ b/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php @@ -20,7 +20,7 @@ class DeprecationErrorHandler { const MODE_WEAK = 'weak'; const MODE_WEAK_VENDORS = 'weak_vendors'; - const MODE_WEAK_LAGGING_VENDORS = 'weak_lagging_vendors'; + const MODE_ALLOW_OUTDATED_VENDORS = 'allow_outdated_vendors'; const MODE_DISABLED = 'disabled'; private static $isRegistered = false; @@ -34,7 +34,7 @@ class DeprecationErrorHandler * The following reporting modes are supported: * - use "weak" to hide the deprecation report but keep a global count; * - use "weak_vendors" to act as "weak" but only for vendors; - * - use "weak_lagging_vendors" to act as "weak" but only for vendors that + * - use "allow_outdated_vendors" to act as "weak" but only for vendors that * failed to keep up with their upstream dependencies deprecations; * - use "/some-regexp/" to stop the test suite whenever a deprecation * message matches the given regular expression; @@ -63,7 +63,7 @@ public static function register($mode = 0) if (!in_array($mode, array( DeprecationErrorHandler::MODE_WEAK, DeprecationErrorHandler::MODE_WEAK_VENDORS, - DeprecationErrorHandler::MODE_WEAK_LAGGING_VENDORS, + DeprecationErrorHandler::MODE_ALLOW_OUTDATED_VENDORS, ), true) && (!isset($mode[0]) || '/' !== $mode[0])) { $mode = preg_match('/^[1-9][0-9]*$/', $mode) ? (int) $mode : 0; } @@ -76,13 +76,13 @@ public static function register($mode = 0) 'remainingCount' => 0, 'legacyCount' => 0, 'otherCount' => 0, - 'lagging vendorCount' => 0, + 'outdated vendorCount' => 0, 'remaining vendorCount' => 0, 'unsilenced' => array(), 'remaining' => array(), 'legacy' => array(), 'other' => array(), - 'lagging vendor' => array(), + 'outdated vendor' => array(), 'remaining vendor' => array(), ); $deprecationHandler = function ($type, $msg, $file, $line, $context = array()) use (&$deprecations, $getMode, $UtilPrefix) { @@ -98,7 +98,7 @@ public static function register($mode = 0) $isVendor = false; $isWeak = DeprecationErrorHandler::MODE_WEAK === $mode || (DeprecationErrorHandler::MODE_WEAK_VENDORS === $mode && $isVendor = self::inVendors($file)) || - (DeprecationErrorHandler::MODE_WEAK_LAGGING_VENDORS === $mode && $isLaggingVendor = self::isLaggingVendor($trace)); + (DeprecationErrorHandler::MODE_ALLOW_OUTDATED_VENDORS === $mode && $isOutdatedVendor = self::isOutdatedVendor($trace)); $i = count($trace); while (1 < $i && (!isset($trace[--$i]['class']) || ('ReflectionMethod' === $trace[$i]['class'] || 0 === strpos($trace[$i]['class'], 'PHPUnit_') || 0 === strpos($trace[$i]['class'], 'PHPUnit\\')))) { // No-op @@ -116,7 +116,7 @@ public static function register($mode = 0) // if the error has been triggered from vendor code. $isWeak = DeprecationErrorHandler::MODE_WEAK === $mode || (DeprecationErrorHandler::MODE_WEAK_VENDORS === $mode && $isVendor = isset($parsedMsg['triggering_file']) && self::inVendors($parsedMsg['triggering_file'])) || - (DeprecationErrorHandler::MODE_WEAK_LAGGING_VENDORS === $mode) && $isLaggingVendor = isset($parsedMsg['trace']) && self::isLaggingVendor($parsedMsg['trace']); + (DeprecationErrorHandler::MODE_ALLOW_OUTDATED_VENDORS === $mode) && $isOutdatedVendor = isset($parsedMsg['trace']) && self::isOutdatedVendor($parsedMsg['trace']); } else { $class = isset($trace[$i]['object']) ? get_class($trace[$i]['object']) : $trace[$i]['class']; $method = $trace[$i]['function']; @@ -133,8 +133,8 @@ public static function register($mode = 0) || in_array('legacy', $Test::getGroups($class, $method), true) ) { $group = 'legacy'; - } elseif (DeprecationErrorHandler::MODE_WEAK_LAGGING_VENDORS === $mode && $isLaggingVendor) { - $group = 'lagging vendor'; + } elseif (DeprecationErrorHandler::MODE_ALLOW_OUTDATED_VENDORS === $mode && $isOutdatedVendor) { + $group = 'outdated vendor'; } elseif (DeprecationErrorHandler::MODE_WEAK_VENDORS === $mode && $isVendor) { $group = 'remaining vendor'; } else { @@ -209,8 +209,8 @@ public static function register($mode = 0) if (DeprecationErrorHandler::MODE_WEAK_VENDORS === $mode) { $groups[] = 'remaining vendor'; } - if (DeprecationErrorHandler::MODE_WEAK_LAGGING_VENDORS === $mode) { - $groups[] = 'lagging vendor'; + if (DeprecationErrorHandler::MODE_ALLOW_OUTDATED_VENDORS === $mode) { + $groups[] = 'outdated vendor'; } array_push($groups, 'legacy', 'other'); @@ -218,7 +218,7 @@ public static function register($mode = 0) if ($deprecations[$group.'Count']) { echo "\n", $colorize( sprintf('%s deprecation notices (%d)', ucfirst($group), $deprecations[$group.'Count']), - !in_array($group, array('legacy', 'remaining vendor', 'lagging vendor'), true) + !in_array($group, array('legacy', 'remaining vendor', 'outdated vendor'), true) ), "\n"; uasort($deprecations[$group], $cmp); @@ -247,7 +247,7 @@ public static function register($mode = 0) } } - private static function isLaggingVendor(array $trace): bool + private static function isOutdatedVendor(array $trace): bool { $erroringFile = $erroringPackage = null; foreach ($trace as $line) { diff --git a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/weak_lagging_vendors_directly_on_vendor.phpt b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/allow_outdated_vendors_directly_on_vendor.phpt similarity index 93% rename from src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/weak_lagging_vendors_directly_on_vendor.phpt rename to src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/allow_outdated_vendors_directly_on_vendor.phpt index 067f6b23a83de..fc1905594b801 100644 --- a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/weak_lagging_vendors_directly_on_vendor.phpt +++ b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/allow_outdated_vendors_directly_on_vendor.phpt @@ -3,7 +3,7 @@ Test DeprecationErrorHandler in weak vendors mode when calling deprecated api --FILE-- --EXPECTF-- -Lagging vendor deprecation notices (1) +Outdated vendor deprecation notices (1) diff --git a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/fake_vendor/acme/lagging-lib/lagging_file.php b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/fake_vendor/acme/outdated-lib/outdated_file.php similarity index 100% rename from src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/fake_vendor/acme/lagging-lib/lagging_file.php rename to src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/fake_vendor/acme/outdated-lib/outdated_file.php