comparison vendor/symfony/phpunit-bridge/DeprecationErrorHandler.php @ 17:129ea1e6d783

Update, including to Drupal core 8.6.10
author Chris Cannam
date Thu, 28 Feb 2019 13:21:36 +0000
parents c2387f117808
children af1871eacc83
comparison
equal deleted inserted replaced
16:c2387f117808 17:129ea1e6d783
31 * - 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; 32 * - use "weak_vendors" to act as "weak" but only for vendors;
33 * - use "/some-regexp/" to stop the test suite whenever a deprecation 33 * - use "/some-regexp/" to stop the test suite whenever a deprecation
34 * message matches the given regular expression; 34 * message matches the given regular expression;
35 * - use a number to define the upper bound of allowed deprecations, 35 * - use a number to define the upper bound of allowed deprecations,
36 * making the test suite fail whenever more notices are trigerred. 36 * making the test suite fail whenever more notices are triggered.
37 * 37 *
38 * @param int|string|false $mode The reporting mode, defaults to not allowing any deprecations 38 * @param int|string|false $mode The reporting mode, defaults to not allowing any deprecations
39 */ 39 */
40 public static function register($mode = 0) 40 public static function register($mode = 0)
41 { 41 {
52 return $memoizedMode; 52 return $memoizedMode;
53 } 53 }
54 if (false === $mode) { 54 if (false === $mode) {
55 $mode = getenv('SYMFONY_DEPRECATIONS_HELPER'); 55 $mode = getenv('SYMFONY_DEPRECATIONS_HELPER');
56 } 56 }
57 if (DeprecationErrorHandler::MODE_WEAK !== $mode && DeprecationErrorHandler::MODE_WEAK_VENDORS !== $mode && (!isset($mode[0]) || '/' !== $mode[0])) { 57 if (self::MODE_DISABLED !== $mode
58 && self::MODE_WEAK !== $mode
59 && self::MODE_WEAK_VENDORS !== $mode
60 && (!isset($mode[0]) || '/' !== $mode[0])
61 ) {
58 $mode = preg_match('/^[1-9][0-9]*$/', $mode) ? (int) $mode : 0; 62 $mode = preg_match('/^[1-9][0-9]*$/', $mode) ? (int) $mode : 0;
59 } 63 }
60 64
61 return $memoizedMode = $mode; 65 return $memoizedMode = $mode;
62 }; 66 };
66 static $vendors; 70 static $vendors;
67 if (null === $vendors) { 71 if (null === $vendors) {
68 foreach (get_declared_classes() as $class) { 72 foreach (get_declared_classes() as $class) {
69 if ('C' === $class[0] && 0 === strpos($class, 'ComposerAutoloaderInit')) { 73 if ('C' === $class[0] && 0 === strpos($class, 'ComposerAutoloaderInit')) {
70 $r = new \ReflectionClass($class); 74 $r = new \ReflectionClass($class);
71 $v = dirname(dirname($r->getFileName())); 75 $v = \dirname(\dirname($r->getFileName()));
72 if (file_exists($v.'/composer/installed.json')) { 76 if (file_exists($v.'/composer/installed.json')) {
73 $vendors[] = $v; 77 $vendors[] = $v;
74 } 78 }
75 } 79 }
76 } 80 }
78 $realPath = realpath($path); 82 $realPath = realpath($path);
79 if (false === $realPath && '-' !== $path && 'Standard input code' !== $path) { 83 if (false === $realPath && '-' !== $path && 'Standard input code' !== $path) {
80 return true; 84 return true;
81 } 85 }
82 foreach ($vendors as $vendor) { 86 foreach ($vendors as $vendor) {
83 if (0 === strpos($realPath, $vendor) && false !== strpbrk(substr($realPath, strlen($vendor), 1), '/'.DIRECTORY_SEPARATOR)) { 87 if (0 === strpos($realPath, $vendor) && false !== strpbrk(substr($realPath, \strlen($vendor), 1), '/'.\DIRECTORY_SEPARATOR)) {
84 return true; 88 return true;
85 } 89 }
86 } 90 }
87 91
88 return false; 92 return false;
100 'other' => array(), 104 'other' => array(),
101 'remaining vendor' => array(), 105 'remaining vendor' => array(),
102 ); 106 );
103 $deprecationHandler = function ($type, $msg, $file, $line, $context = array()) use (&$deprecations, $getMode, $UtilPrefix, $inVendors) { 107 $deprecationHandler = function ($type, $msg, $file, $line, $context = array()) use (&$deprecations, $getMode, $UtilPrefix, $inVendors) {
104 $mode = $getMode(); 108 $mode = $getMode();
105 if ((E_USER_DEPRECATED !== $type && E_DEPRECATED !== $type) || DeprecationErrorHandler::MODE_DISABLED === $mode) { 109 if ((E_USER_DEPRECATED !== $type && E_DEPRECATED !== $type) || self::MODE_DISABLED === $mode) {
106 $ErrorHandler = $UtilPrefix.'ErrorHandler'; 110 $ErrorHandler = $UtilPrefix.'ErrorHandler';
107 111
108 return $ErrorHandler::handleError($type, $msg, $file, $line, $context); 112 return $ErrorHandler::handleError($type, $msg, $file, $line, $context);
109 } 113 }
110 114
111 $trace = debug_backtrace(true); 115 $trace = debug_backtrace();
112 $group = 'other'; 116 $group = 'other';
113 $isVendor = DeprecationErrorHandler::MODE_WEAK_VENDORS === $mode && $inVendors($file); 117 $isVendor = self::MODE_WEAK_VENDORS === $mode && $inVendors($file);
114 118
115 $i = count($trace); 119 $i = \count($trace);
116 while (1 < $i && (!isset($trace[--$i]['class']) || ('ReflectionMethod' === $trace[$i]['class'] || 0 === strpos($trace[$i]['class'], 'PHPUnit_') || 0 === strpos($trace[$i]['class'], 'PHPUnit\\')))) { 120 while (1 < $i && (!isset($trace[--$i]['class']) || ('ReflectionMethod' === $trace[$i]['class'] || 0 === strpos($trace[$i]['class'], 'PHPUnit_') || 0 === strpos($trace[$i]['class'], 'PHPUnit\\')))) {
117 // No-op 121 // No-op
118 } 122 }
119 123
120 if (isset($trace[$i]['object']) || isset($trace[$i]['class'])) { 124 if (isset($trace[$i]['object']) || isset($trace[$i]['class'])) {
125 $method = $parsedMsg['method']; 129 $method = $parsedMsg['method'];
126 // If the deprecation has been triggered via 130 // If the deprecation has been triggered via
127 // \Symfony\Bridge\PhpUnit\Legacy\SymfonyTestsListenerTrait::endTest() 131 // \Symfony\Bridge\PhpUnit\Legacy\SymfonyTestsListenerTrait::endTest()
128 // then we need to use the serialized information to determine 132 // then we need to use the serialized information to determine
129 // if the error has been triggered from vendor code. 133 // if the error has been triggered from vendor code.
130 $isVendor = DeprecationErrorHandler::MODE_WEAK_VENDORS === $mode && isset($parsedMsg['triggering_file']) && $inVendors($parsedMsg['triggering_file']); 134 $isVendor = self::MODE_WEAK_VENDORS === $mode && isset($parsedMsg['triggering_file']) && $inVendors($parsedMsg['triggering_file']);
131 } else { 135 } else {
132 $class = isset($trace[$i]['object']) ? get_class($trace[$i]['object']) : $trace[$i]['class']; 136 $class = isset($trace[$i]['object']) ? \get_class($trace[$i]['object']) : $trace[$i]['class'];
133 $method = $trace[$i]['function']; 137 $method = $trace[$i]['function'];
134 } 138 }
135 139
136 $Test = $UtilPrefix.'Test'; 140 $Test = $UtilPrefix.'Test';
137 141
139 $group = 'unsilenced'; 143 $group = 'unsilenced';
140 } elseif (0 === strpos($method, 'testLegacy') 144 } elseif (0 === strpos($method, 'testLegacy')
141 || 0 === strpos($method, 'provideLegacy') 145 || 0 === strpos($method, 'provideLegacy')
142 || 0 === strpos($method, 'getLegacy') 146 || 0 === strpos($method, 'getLegacy')
143 || strpos($class, '\Legacy') 147 || strpos($class, '\Legacy')
144 || in_array('legacy', $Test::getGroups($class, $method), true) 148 || \in_array('legacy', $Test::getGroups($class, $method), true)
145 ) { 149 ) {
146 $group = 'legacy'; 150 $group = 'legacy';
147 } elseif ($isVendor) { 151 } elseif ($isVendor) {
148 $group = 'remaining vendor'; 152 $group = 'remaining vendor';
149 } else { 153 } else {
152 156
153 if (isset($mode[0]) && '/' === $mode[0] && preg_match($mode, $msg)) { 157 if (isset($mode[0]) && '/' === $mode[0] && preg_match($mode, $msg)) {
154 $e = new \Exception($msg); 158 $e = new \Exception($msg);
155 $r = new \ReflectionProperty($e, 'trace'); 159 $r = new \ReflectionProperty($e, 'trace');
156 $r->setAccessible(true); 160 $r->setAccessible(true);
157 $r->setValue($e, array_slice($trace, 1, $i)); 161 $r->setValue($e, \array_slice($trace, 1, $i));
158 162
159 echo "\n".ucfirst($group).' deprecation triggered by '.$class.'::'.$method.':'; 163 echo "\n".ucfirst($group).' deprecation triggered by '.$class.'::'.$method.':';
160 echo "\n".$msg; 164 echo "\n".$msg;
161 echo "\nStack trace:"; 165 echo "\nStack trace:";
162 echo "\n".str_replace(' '.getcwd().DIRECTORY_SEPARATOR, ' ', $e->getTraceAsString()); 166 echo "\n".str_replace(' '.getcwd().\DIRECTORY_SEPARATOR, ' ', $e->getTraceAsString());
163 echo "\n"; 167 echo "\n";
164 168
165 exit(1); 169 exit(1);
166 } 170 }
167 if ('legacy' !== $group && DeprecationErrorHandler::MODE_WEAK !== $mode) { 171 if ('legacy' !== $group && self::MODE_WEAK !== $mode) {
168 $ref = &$deprecations[$group][$msg]['count']; 172 $ref = &$deprecations[$group][$msg]['count'];
169 ++$ref; 173 ++$ref;
170 $ref = &$deprecations[$group][$msg][$class.'::'.$method]; 174 $ref = &$deprecations[$group][$msg][$class.'::'.$method];
171 ++$ref; 175 ++$ref;
172 } 176 }
173 } elseif (DeprecationErrorHandler::MODE_WEAK !== $mode) { 177 } elseif (self::MODE_WEAK !== $mode) {
174 $ref = &$deprecations[$group][$msg]['count']; 178 $ref = &$deprecations[$group][$msg]['count'];
175 ++$ref; 179 ++$ref;
176 } 180 }
177 ++$deprecations[$group.'Count']; 181 ++$deprecations[$group.'Count'];
178 }; 182 };
201 return; 205 return;
202 } 206 }
203 $currErrorHandler = set_error_handler('var_dump'); 207 $currErrorHandler = set_error_handler('var_dump');
204 restore_error_handler(); 208 restore_error_handler();
205 209
206 if (DeprecationErrorHandler::MODE_WEAK === $mode) { 210 if (self::MODE_WEAK === $mode) {
207 $colorize = function ($str) { return $str; }; 211 $colorize = function ($str) { return $str; };
208 } 212 }
209 if ($currErrorHandler !== $deprecationHandler) { 213 if ($currErrorHandler !== $deprecationHandler) {
210 echo "\n", $colorize('THE ERROR HANDLER HAS CHANGED!', true), "\n"; 214 echo "\n", $colorize('THE ERROR HANDLER HAS CHANGED!', true), "\n";
211 } 215 }
213 $cmp = function ($a, $b) { 217 $cmp = function ($a, $b) {
214 return $b['count'] - $a['count']; 218 return $b['count'] - $a['count'];
215 }; 219 };
216 220
217 $groups = array('unsilenced', 'remaining'); 221 $groups = array('unsilenced', 'remaining');
218 if (DeprecationErrorHandler::MODE_WEAK_VENDORS === $mode) { 222 if (self::MODE_WEAK_VENDORS === $mode) {
219 $groups[] = 'remaining vendor'; 223 $groups[] = 'remaining vendor';
220 } 224 }
221 array_push($groups, 'legacy', 'other'); 225 array_push($groups, 'legacy', 'other');
222 226
223 $displayDeprecations = function ($deprecations) use ($colorize, $cmp, $groups) { 227 $displayDeprecations = function ($deprecations) use ($colorize, $cmp, $groups) {
249 }; 253 };
250 254
251 $displayDeprecations($deprecations); 255 $displayDeprecations($deprecations);
252 256
253 // store failing status 257 // store failing status
254 $isFailing = DeprecationErrorHandler::MODE_WEAK !== $mode && $mode < $deprecations['unsilencedCount'] + $deprecations['remainingCount'] + $deprecations['otherCount']; 258 $isFailing = self::MODE_WEAK !== $mode && $mode < $deprecations['unsilencedCount'] + $deprecations['remainingCount'] + $deprecations['otherCount'];
255 259
256 // reset deprecations array 260 // reset deprecations array
257 foreach ($deprecations as $group => $arrayOrInt) { 261 foreach ($deprecations as $group => $arrayOrInt) {
258 $deprecations[$group] = is_int($arrayOrInt) ? 0 : array(); 262 $deprecations[$group] = \is_int($arrayOrInt) ? 0 : array();
259 } 263 }
260 264
261 register_shutdown_function(function () use (&$deprecations, $isFailing, $displayDeprecations, $mode) { 265 register_shutdown_function(function () use (&$deprecations, $isFailing, $displayDeprecations, $mode) {
262 foreach ($deprecations as $group => $arrayOrInt) { 266 foreach ($deprecations as $group => $arrayOrInt) {
263 if (0 < (is_int($arrayOrInt) ? $arrayOrInt : count($arrayOrInt))) { 267 if (0 < (\is_int($arrayOrInt) ? $arrayOrInt : \count($arrayOrInt))) {
264 echo "Shutdown-time deprecations:\n"; 268 echo "Shutdown-time deprecations:\n";
265 break; 269 break;
266 } 270 }
267 } 271 }
268 $displayDeprecations($deprecations); 272 $displayDeprecations($deprecations);
269 if ($isFailing || DeprecationErrorHandler::MODE_WEAK !== $mode && $mode < $deprecations['unsilencedCount'] + $deprecations['remainingCount'] + $deprecations['otherCount']) { 273 if ($isFailing || self::MODE_WEAK !== $mode && $mode < $deprecations['unsilencedCount'] + $deprecations['remainingCount'] + $deprecations['otherCount']) {
270 exit(1); 274 exit(1);
271 } 275 }
272 }); 276 });
273 }); 277 });
274 } 278 }
305 * 309 *
306 * @return bool 310 * @return bool
307 */ 311 */
308 private static function hasColorSupport() 312 private static function hasColorSupport()
309 { 313 {
310 if (!defined('STDOUT')) { 314 if (!\defined('STDOUT')) {
311 return false; 315 return false;
312 } 316 }
313 317
314 if (DIRECTORY_SEPARATOR === '\\') { 318 if ('Hyper' === getenv('TERM_PROGRAM')) {
315 return (function_exists('sapi_windows_vt100_support') 319 return true;
320 }
321
322 if (\DIRECTORY_SEPARATOR === '\\') {
323 return (\function_exists('sapi_windows_vt100_support')
316 && sapi_windows_vt100_support(STDOUT)) 324 && sapi_windows_vt100_support(STDOUT))
317 || false !== getenv('ANSICON') 325 || false !== getenv('ANSICON')
318 || 'ON' === getenv('ConEmuANSI') 326 || 'ON' === getenv('ConEmuANSI')
319 || 'xterm' === getenv('TERM'); 327 || 'xterm' === getenv('TERM');
320 } 328 }
321 329
322 if (function_exists('stream_isatty')) { 330 if (\function_exists('stream_isatty')) {
323 return stream_isatty(STDOUT); 331 return stream_isatty(STDOUT);
324 } 332 }
325 333
326 if (function_exists('posix_isatty')) { 334 if (\function_exists('posix_isatty')) {
327 return posix_isatty(STDOUT); 335 return posix_isatty(STDOUT);
328 } 336 }
329 337
330 $stat = fstat(STDOUT); 338 $stat = fstat(STDOUT);
331 // Check if formatted mode is S_IFCHR 339 // Check if formatted mode is S_IFCHR