Mercurial > hg > isophonics-drupal-site
comparison vendor/symfony/phpunit-bridge/DeprecationErrorHandler.php @ 14:1fec387a4317
Update Drupal core to 8.5.2 via Composer
author | Chris Cannam |
---|---|
date | Mon, 23 Apr 2018 09:46:53 +0100 |
parents | 7a779792577d |
children | c2387f117808 |
comparison
equal
deleted
inserted
replaced
13:5fb285c0d0e3 | 14:1fec387a4317 |
---|---|
17 * @author Nicolas Grekas <p@tchwork.com> | 17 * @author Nicolas Grekas <p@tchwork.com> |
18 */ | 18 */ |
19 class DeprecationErrorHandler | 19 class DeprecationErrorHandler |
20 { | 20 { |
21 const MODE_WEAK = 'weak'; | 21 const MODE_WEAK = 'weak'; |
22 const MODE_WEAK_VENDORS = 'weak_vendors'; | |
22 const MODE_DISABLED = 'disabled'; | 23 const MODE_DISABLED = 'disabled'; |
23 | 24 |
24 private static $isRegistered = false; | 25 private static $isRegistered = false; |
25 | 26 |
26 /** | 27 /** |
27 * Registers and configures the deprecation handler. | 28 * Registers and configures the deprecation handler. |
28 * | 29 * |
29 * The following reporting modes are supported: | 30 * The following reporting modes are supported: |
30 * - use "weak" to hide the deprecation report but keep a global count; | 31 * - use "weak" to hide the deprecation report but keep a global count; |
32 * - use "weak_vendors" to act as "weak" but only for vendors; | |
31 * - use "/some-regexp/" to stop the test suite whenever a deprecation | 33 * - use "/some-regexp/" to stop the test suite whenever a deprecation |
32 * message matches the given regular expression; | 34 * message matches the given regular expression; |
33 * - use a number to define the upper bound of allowed deprecations, | 35 * - use a number to define the upper bound of allowed deprecations, |
34 * making the test suite fail whenever more notices are trigerred. | 36 * making the test suite fail whenever more notices are trigerred. |
35 * | 37 * |
39 { | 41 { |
40 if (self::$isRegistered) { | 42 if (self::$isRegistered) { |
41 return; | 43 return; |
42 } | 44 } |
43 | 45 |
46 $UtilPrefix = class_exists('PHPUnit_Util_ErrorHandler') ? 'PHPUnit_Util_' : 'PHPUnit\Util\\'; | |
47 | |
44 $getMode = function () use ($mode) { | 48 $getMode = function () use ($mode) { |
45 static $memoizedMode = false; | 49 static $memoizedMode = false; |
46 | 50 |
47 if (false !== $memoizedMode) { | 51 if (false !== $memoizedMode) { |
48 return $memoizedMode; | 52 return $memoizedMode; |
49 } | 53 } |
50 if (false === $mode) { | 54 if (false === $mode) { |
51 $mode = getenv('SYMFONY_DEPRECATIONS_HELPER'); | 55 $mode = getenv('SYMFONY_DEPRECATIONS_HELPER'); |
52 } | 56 } |
53 if (DeprecationErrorHandler::MODE_WEAK !== $mode && (!isset($mode[0]) || '/' !== $mode[0])) { | 57 if (DeprecationErrorHandler::MODE_WEAK !== $mode && DeprecationErrorHandler::MODE_WEAK_VENDORS !== $mode && (!isset($mode[0]) || '/' !== $mode[0])) { |
54 $mode = preg_match('/^[1-9][0-9]*$/', $mode) ? (int) $mode : 0; | 58 $mode = preg_match('/^[1-9][0-9]*$/', $mode) ? (int) $mode : 0; |
55 } | 59 } |
56 | 60 |
57 return $memoizedMode = $mode; | 61 return $memoizedMode = $mode; |
62 }; | |
63 | |
64 $inVendors = function ($path) { | |
65 /** @var string[] absolute paths to vendor directories */ | |
66 static $vendors; | |
67 if (null === $vendors) { | |
68 foreach (get_declared_classes() as $class) { | |
69 if ('C' === $class[0] && 0 === strpos($class, 'ComposerAutoloaderInit')) { | |
70 $r = new \ReflectionClass($class); | |
71 $v = dirname(dirname($r->getFileName())); | |
72 if (file_exists($v.'/composer/installed.json')) { | |
73 $vendors[] = $v; | |
74 } | |
75 } | |
76 } | |
77 } | |
78 $realPath = realpath($path); | |
79 if (false === $realPath && '-' !== $path && 'Standard input code' !== $path) { | |
80 return true; | |
81 } | |
82 foreach ($vendors as $vendor) { | |
83 if (0 === strpos($realPath, $vendor) && false !== strpbrk(substr($realPath, strlen($vendor), 1), '/'.DIRECTORY_SEPARATOR)) { | |
84 return true; | |
85 } | |
86 } | |
87 | |
88 return false; | |
58 }; | 89 }; |
59 | 90 |
60 $deprecations = array( | 91 $deprecations = array( |
61 'unsilencedCount' => 0, | 92 'unsilencedCount' => 0, |
62 'remainingCount' => 0, | 93 'remainingCount' => 0, |
63 'legacyCount' => 0, | 94 'legacyCount' => 0, |
64 'otherCount' => 0, | 95 'otherCount' => 0, |
96 'remaining vendorCount' => 0, | |
65 'unsilenced' => array(), | 97 'unsilenced' => array(), |
66 'remaining' => array(), | 98 'remaining' => array(), |
67 'legacy' => array(), | 99 'legacy' => array(), |
68 'other' => array(), | 100 'other' => array(), |
101 'remaining vendor' => array(), | |
69 ); | 102 ); |
70 $deprecationHandler = function ($type, $msg, $file, $line, $context = array()) use (&$deprecations, $getMode) { | 103 $deprecationHandler = function ($type, $msg, $file, $line, $context = array()) use (&$deprecations, $getMode, $UtilPrefix, $inVendors) { |
71 $mode = $getMode(); | 104 $mode = $getMode(); |
72 if ((E_USER_DEPRECATED !== $type && E_DEPRECATED !== $type) || DeprecationErrorHandler::MODE_DISABLED === $mode) { | 105 if ((E_USER_DEPRECATED !== $type && E_DEPRECATED !== $type) || DeprecationErrorHandler::MODE_DISABLED === $mode) { |
73 return \PHPUnit_Util_ErrorHandler::handleError($type, $msg, $file, $line, $context); | 106 $ErrorHandler = $UtilPrefix.'ErrorHandler'; |
107 | |
108 return $ErrorHandler::handleError($type, $msg, $file, $line, $context); | |
74 } | 109 } |
75 | 110 |
76 $trace = debug_backtrace(true); | 111 $trace = debug_backtrace(true); |
77 $group = 'other'; | 112 $group = 'other'; |
113 $isVendor = DeprecationErrorHandler::MODE_WEAK_VENDORS === $mode && $inVendors($file); | |
78 | 114 |
79 $i = count($trace); | 115 $i = count($trace); |
80 while (1 < $i && (!isset($trace[--$i]['class']) || ('ReflectionMethod' === $trace[$i]['class'] || 0 === strpos($trace[$i]['class'], 'PHPUnit_')))) { | 116 while (1 < $i && (!isset($trace[--$i]['class']) || ('ReflectionMethod' === $trace[$i]['class'] || 0 === strpos($trace[$i]['class'], 'PHPUnit_') || 0 === strpos($trace[$i]['class'], 'PHPUnit\\')))) { |
81 // No-op | 117 // No-op |
82 } | 118 } |
83 | 119 |
84 if (isset($trace[$i]['object']) || isset($trace[$i]['class'])) { | 120 if (isset($trace[$i]['object']) || isset($trace[$i]['class'])) { |
85 $class = isset($trace[$i]['object']) ? get_class($trace[$i]['object']) : $trace[$i]['class']; | 121 if (isset($trace[$i]['class']) && 0 === strpos($trace[$i]['class'], 'Symfony\Bridge\PhpUnit\Legacy\SymfonyTestsListenerFor')) { |
86 $method = $trace[$i]['function']; | 122 $parsedMsg = unserialize($msg); |
123 $msg = $parsedMsg['deprecation']; | |
124 $class = $parsedMsg['class']; | |
125 $method = $parsedMsg['method']; | |
126 // If the deprecation has been triggered via | |
127 // \Symfony\Bridge\PhpUnit\Legacy\SymfonyTestsListenerTrait::endTest() | |
128 // then we need to use the serialized information to determine | |
129 // if the error has been triggered from vendor code. | |
130 $isVendor = DeprecationErrorHandler::MODE_WEAK_VENDORS === $mode && isset($parsedMsg['triggering_file']) && $inVendors($parsedMsg['triggering_file']); | |
131 } else { | |
132 $class = isset($trace[$i]['object']) ? get_class($trace[$i]['object']) : $trace[$i]['class']; | |
133 $method = $trace[$i]['function']; | |
134 } | |
135 | |
136 $Test = $UtilPrefix.'Test'; | |
87 | 137 |
88 if (0 !== error_reporting()) { | 138 if (0 !== error_reporting()) { |
89 $group = 'unsilenced'; | 139 $group = 'unsilenced'; |
90 } elseif (0 === strpos($method, 'testLegacy') | 140 } elseif (0 === strpos($method, 'testLegacy') |
91 || 0 === strpos($method, 'provideLegacy') | 141 || 0 === strpos($method, 'provideLegacy') |
92 || 0 === strpos($method, 'getLegacy') | 142 || 0 === strpos($method, 'getLegacy') |
93 || strpos($class, '\Legacy') | 143 || strpos($class, '\Legacy') |
94 || in_array('legacy', \PHPUnit_Util_Test::getGroups($class, $method), true) | 144 || in_array('legacy', $Test::getGroups($class, $method), true) |
95 ) { | 145 ) { |
96 $group = 'legacy'; | 146 $group = 'legacy'; |
147 } elseif ($isVendor) { | |
148 $group = 'remaining vendor'; | |
97 } else { | 149 } else { |
98 $group = 'remaining'; | 150 $group = 'remaining'; |
99 } | 151 } |
100 | 152 |
101 if (isset($mode[0]) && '/' === $mode[0] && preg_match($mode, $msg)) { | 153 if (isset($mode[0]) && '/' === $mode[0] && preg_match($mode, $msg)) { |
126 }; | 178 }; |
127 $oldErrorHandler = set_error_handler($deprecationHandler); | 179 $oldErrorHandler = set_error_handler($deprecationHandler); |
128 | 180 |
129 if (null !== $oldErrorHandler) { | 181 if (null !== $oldErrorHandler) { |
130 restore_error_handler(); | 182 restore_error_handler(); |
131 if (array('PHPUnit_Util_ErrorHandler', 'handleError') === $oldErrorHandler) { | 183 if (array($UtilPrefix.'ErrorHandler', 'handleError') === $oldErrorHandler) { |
132 restore_error_handler(); | 184 restore_error_handler(); |
133 self::register($mode); | 185 self::register($mode); |
134 } | 186 } |
135 } else { | 187 } else { |
136 self::$isRegistered = true; | 188 self::$isRegistered = true; |
160 | 212 |
161 $cmp = function ($a, $b) { | 213 $cmp = function ($a, $b) { |
162 return $b['count'] - $a['count']; | 214 return $b['count'] - $a['count']; |
163 }; | 215 }; |
164 | 216 |
165 foreach (array('unsilenced', 'remaining', 'legacy', 'other') as $group) { | 217 $groups = array('unsilenced', 'remaining'); |
166 if ($deprecations[$group.'Count']) { | 218 if (DeprecationErrorHandler::MODE_WEAK_VENDORS === $mode) { |
167 echo "\n", $colorize(sprintf('%s deprecation notices (%d)', ucfirst($group), $deprecations[$group.'Count']), 'legacy' !== $group), "\n"; | 219 $groups[] = 'remaining vendor'; |
168 | 220 } |
169 uasort($deprecations[$group], $cmp); | 221 array_push($groups, 'legacy', 'other'); |
170 | 222 |
171 foreach ($deprecations[$group] as $msg => $notices) { | 223 $displayDeprecations = function ($deprecations) use ($colorize, $cmp, $groups) { |
172 echo "\n", rtrim($msg, '.'), ': ', $notices['count'], "x\n"; | 224 foreach ($groups as $group) { |
173 | 225 if ($deprecations[$group.'Count']) { |
174 arsort($notices); | 226 echo "\n", $colorize( |
175 | 227 sprintf('%s deprecation notices (%d)', ucfirst($group), $deprecations[$group.'Count']), |
176 foreach ($notices as $method => $count) { | 228 'legacy' !== $group && 'remaining vendor' !== $group |
177 if ('count' !== $method) { | 229 ), "\n"; |
178 echo ' ', $count, 'x in ', preg_replace('/(.*)\\\\(.*?::.*?)$/', '$2 from $1', $method), "\n"; | 230 |
231 uasort($deprecations[$group], $cmp); | |
232 | |
233 foreach ($deprecations[$group] as $msg => $notices) { | |
234 echo "\n ", $notices['count'], 'x: ', $msg, "\n"; | |
235 | |
236 arsort($notices); | |
237 | |
238 foreach ($notices as $method => $count) { | |
239 if ('count' !== $method) { | |
240 echo ' ', $count, 'x in ', preg_replace('/(.*)\\\\(.*?::.*?)$/', '$2 from $1', $method), "\n"; | |
241 } | |
179 } | 242 } |
180 } | 243 } |
181 } | 244 } |
182 } | 245 } |
183 } | 246 if (!empty($notices)) { |
184 if (!empty($notices)) { | 247 echo "\n"; |
185 echo "\n"; | 248 } |
186 } | 249 }; |
187 | 250 |
188 if (DeprecationErrorHandler::MODE_WEAK !== $mode && $mode < $deprecations['unsilencedCount'] + $deprecations['remainingCount'] + $deprecations['otherCount']) { | 251 $displayDeprecations($deprecations); |
189 exit(1); | 252 |
190 } | 253 // store failing status |
254 $isFailing = DeprecationErrorHandler::MODE_WEAK !== $mode && $mode < $deprecations['unsilencedCount'] + $deprecations['remainingCount'] + $deprecations['otherCount']; | |
255 | |
256 // reset deprecations array | |
257 foreach ($deprecations as $group => $arrayOrInt) { | |
258 $deprecations[$group] = is_int($arrayOrInt) ? 0 : array(); | |
259 } | |
260 | |
261 register_shutdown_function(function () use (&$deprecations, $isFailing, $displayDeprecations, $mode) { | |
262 foreach ($deprecations as $group => $arrayOrInt) { | |
263 if (0 < (is_int($arrayOrInt) ? $arrayOrInt : count($arrayOrInt))) { | |
264 echo "Shutdown-time deprecations:\n"; | |
265 break; | |
266 } | |
267 } | |
268 $displayDeprecations($deprecations); | |
269 if ($isFailing || DeprecationErrorHandler::MODE_WEAK !== $mode && $mode < $deprecations['unsilencedCount'] + $deprecations['remainingCount'] + $deprecations['otherCount']) { | |
270 exit(1); | |
271 } | |
272 }); | |
191 }); | 273 }); |
192 } | 274 } |
275 } | |
276 | |
277 public static function collectDeprecations($outputFile) | |
278 { | |
279 $deprecations = array(); | |
280 $previousErrorHandler = set_error_handler(function ($type, $msg, $file, $line, $context = array()) use (&$deprecations, &$previousErrorHandler) { | |
281 if (E_USER_DEPRECATED !== $type && E_DEPRECATED !== $type) { | |
282 if ($previousErrorHandler) { | |
283 return $previousErrorHandler($type, $msg, $file, $line, $context); | |
284 } | |
285 static $autoload = true; | |
286 | |
287 $ErrorHandler = class_exists('PHPUnit_Util_ErrorHandler', $autoload) ? 'PHPUnit_Util_ErrorHandler' : 'PHPUnit\Util\ErrorHandler'; | |
288 $autoload = false; | |
289 | |
290 return $ErrorHandler::handleError($type, $msg, $file, $line, $context); | |
291 } | |
292 $deprecations[] = array(error_reporting(), $msg, $file); | |
293 }); | |
294 | |
295 register_shutdown_function(function () use ($outputFile, &$deprecations) { | |
296 file_put_contents($outputFile, serialize($deprecations)); | |
297 }); | |
193 } | 298 } |
194 | 299 |
195 private static function hasColorSupport() | 300 private static function hasColorSupport() |
196 { | 301 { |
197 if ('\\' === DIRECTORY_SEPARATOR) { | 302 if ('\\' === DIRECTORY_SEPARATOR) { |
198 return | 303 return |
199 '10.0.10586' === PHP_WINDOWS_VERSION_MAJOR.'.'.PHP_WINDOWS_VERSION_MINOR.'.'.PHP_WINDOWS_VERSION_BUILD | 304 defined('STDOUT') && function_exists('sapi_windows_vt100_support') && sapi_windows_vt100_support(STDOUT) |
305 || '10.0.10586' === PHP_WINDOWS_VERSION_MAJOR.'.'.PHP_WINDOWS_VERSION_MINOR.'.'.PHP_WINDOWS_VERSION_BUILD | |
200 || false !== getenv('ANSICON') | 306 || false !== getenv('ANSICON') |
201 || 'ON' === getenv('ConEmuANSI') | 307 || 'ON' === getenv('ConEmuANSI') |
202 || 'xterm' === getenv('TERM'); | 308 || 'xterm' === getenv('TERM'); |
203 } | 309 } |
204 | 310 |