|
| 1 | +#!/usr/bin/env php |
| 2 | +<?php |
| 3 | + |
| 4 | +/* |
| 5 | + * This file is part of the Symfony package. |
| 6 | + * |
| 7 | + * (c) Fabien Potencier <fabien@symfony.com> |
| 8 | + * |
| 9 | + * For the full copyright and license information, please view the LICENSE |
| 10 | + * file that was distributed with this source code. |
| 11 | + */ |
| 12 | + |
| 13 | +if (\in_array('-h', $argv) || \in_array('--help', $argv)) { |
| 14 | + echo implode(PHP_EOL, [ |
| 15 | + ' Patches type declarations based on "@return" PHPDoc and triggers deprecations for', |
| 16 | + ' incompatible method declarations.', |
| 17 | + '', |
| 18 | + ' This assists you to make your package compatible with Symfony 6, but it can be used', |
| 19 | + ' for any class/package.', |
| 20 | + '', |
| 21 | + ' Available configuration via environment variables:', |
| 22 | + ' SYMFONY_PATCH_TYPE_DECLARATIONS', |
| 23 | + ' An url-encoded string to change the behavior of the script. Available parameters:', |
| 24 | + ' - "force": any value enables deprecation notices - can be any of:', |
| 25 | + ' - "phpdoc" to patch only docblock annotations', |
| 26 | + ' - "2" to add all possible return types', |
| 27 | + ' - "1" to add return types but only to tests/final/internal/private methods', |
| 28 | + ' - "php": the target version of PHP - e.g. "7.1" doesn\'t generate "object" types', |
| 29 | + ' - "deprecations": "1" to trigger a deprecation notice when a child class misses a', |
| 30 | + ' return type while the parent declares an "@return" annotation', |
| 31 | + '', |
| 32 | + ' SYMFONY_PATCH_TYPE_EXCLUDE', |
| 33 | + ' A regex matched against the full path to the class - any match will be excluded', |
| 34 | + '', |
| 35 | + ' Example: "SYMFONY_PATCH_TYPE_DECLARATIONS=php=7.4 ./patch-type-declarations"', |
| 36 | + ]); |
| 37 | + exit; |
| 38 | +} |
| 39 | + |
| 40 | +if (false === getenv('SYMFONY_PATCH_TYPE_DECLARATIONS')) { |
| 41 | + putenv('SYMFONY_PATCH_TYPE_DECLARATIONS=force=2'); |
| 42 | + echo 'No SYMFONY_PATCH_TYPE_DECLARATIONS env var set, patching type declarations in all methods (run the command with "-h" for more information).'.PHP_EOL; |
| 43 | +} |
| 44 | + |
| 45 | +if (is_file($autoload = __DIR__.'/../../../autoload.php')) { |
| 46 | + // noop |
| 47 | +} elseif (is_file($autoload = __DIR__.'/../../../../../autoload.php')) { |
| 48 | + // noop |
| 49 | +} else { |
| 50 | + echo PHP_EOL.' /!\ Cannot find the Composer autoloader, did you forget to run "composer install"?'.PHP_EOL; |
| 51 | + exit(1); |
| 52 | +} |
| 53 | + |
| 54 | +if (is_file($phpunitAutoload = dirname($autoload).'/bin/.phpunit/phpunit/vendor/autoload.php')) { |
| 55 | + require $phpunitAutoload; |
| 56 | +} |
| 57 | + |
| 58 | +$loader = require $autoload; |
| 59 | + |
| 60 | +Symfony\Component\ErrorHandler\DebugClassLoader::enable(); |
| 61 | + |
| 62 | +$deprecations = []; |
| 63 | +set_error_handler(function ($type, $msg, $file, $line, $context = []) use (&$deprecations) { |
| 64 | + if (\E_USER_DEPRECATED !== $type) { |
| 65 | + return; |
| 66 | + } |
| 67 | + |
| 68 | + [,,,,, $class,] = explode('"', $msg); |
| 69 | + $deprecations[$class][] = $msg; |
| 70 | +}); |
| 71 | + |
| 72 | +$exclude = getenv('SYMFONY_PATCH_TYPE_EXCLUDE') ?: null; |
| 73 | +foreach ($loader->getClassMap() as $class => $file) { |
| 74 | + if ($exclude && preg_match($exclude, realpath($file))) { |
| 75 | + continue; |
| 76 | + } |
| 77 | + |
| 78 | + class_exists($class); |
| 79 | +} |
| 80 | + |
| 81 | +Symfony\Component\ErrorHandler\DebugClassLoader::checkClasses(); |
| 82 | + |
| 83 | +foreach ($deprecations as $class => $classDeprecations) { |
| 84 | + echo $class.' ('.\count($classDeprecations).')'.PHP_EOL; |
| 85 | + echo implode(PHP_EOL, $classDeprecations).PHP_EOL.PHP_EOL; |
| 86 | +} |
| 87 | + |
| 88 | +if ($deprecations && false !== strpos(getenv('SYMFONY_PATCH_TYPE_DECLARATIONS') ?? '', 'force')) { |
| 89 | + echo 'These deprecations might be fixed by the patch script, run this again to check for type deprecations.'.PHP_EOL; |
| 90 | +} |
0 commit comments