From 3805c92b97c88c80e35fcdd78694d0bb20846945 Mon Sep 17 00:00:00 2001 From: TomasVotruba Date: Sat, 18 Jul 2020 20:26:57 +0200 Subject: [PATCH 1/4] load rector.php config --- create-rector.php | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 create-rector.php diff --git a/create-rector.php b/create-rector.php new file mode 100644 index 000000000000..f5b415b3ca5a --- /dev/null +++ b/create-rector.php @@ -0,0 +1,38 @@ +parameters(); + + $parameters->set(Option::RECTOR_RECIPE, [ + # run "bin/rector create" to create a new Rector + tests from this config + 'package' => 'Symfony', + 'name' => 'RemoveDefaultGetBlockPrefixRector', + 'node_types' => ['ClassMethod'], + 'description' => 'Rename `getBlockPrefix()` if it returns the default value - class to underscore, e.g. UserFormType = user_form', + 'code_before' => ' ' [ + # e.g. link to RFC or headline in upgrade guide, 1 or more in the list + 'https://github.com/symfony/symfony/blob/3.4/UPGRADE-3.0.md', + ], + # e.g. symfony30, target config to append this rector to + 'set' => 'symfony30', + ]); +}; From f7d78436d19975ee66a46d85bfd2c314905c43f7 Mon Sep 17 00:00:00 2001 From: TomasVotruba Date: Sun, 19 Jul 2020 10:28:33 +0200 Subject: [PATCH 2/4] switch YAML to PHP --- compiler/config/config.php | 34 +++++++++++++++++++ compiler/config/config.yaml | 20 ----------- .../src/HttpKernel/RectorCompilerKernel.php | 2 +- 3 files changed, 35 insertions(+), 21 deletions(-) create mode 100644 compiler/config/config.php delete mode 100644 compiler/config/config.yaml diff --git a/compiler/config/config.php b/compiler/config/config.php new file mode 100644 index 000000000000..0de088c65e08 --- /dev/null +++ b/compiler/config/config.php @@ -0,0 +1,34 @@ +parameters(); + + $parameters->set('dataDir', __DIR__ . '/../build'); + + $parameters->set('buildDir', __DIR__ . '/../..'); + + $services = $containerConfigurator->services(); + + $services->defaults() + ->public() + ->autowire(); + + $services->load('Rector\Compiler\\', __DIR__ . '/../src') + ->exclude([ + __DIR__ . '/../src/Exception/*', + __DIR__ . '/../src/DependencyInjection/*', + __DIR__ . '/../src/HttpKernel/*', + __DIR__ . '/../src/PhpScoper/*', + ]); + + $services->set(Filesystem::class); + + $services->set(CiDetector::class); +}; diff --git a/compiler/config/config.yaml b/compiler/config/config.yaml deleted file mode 100644 index 72088b7ef588..000000000000 --- a/compiler/config/config.yaml +++ /dev/null @@ -1,20 +0,0 @@ -parameters: - dataDir: '%kernel.project_dir%/build' - buildDir: '%kernel.project_dir%/..' - -services: - _defaults: - public: true - autowire: true - - Rector\Compiler\: - resource: '../src' - exclude: - - '../src/Exception/*' - - '../src/DependencyInjection/*' - - '../src/HttpKernel/*' - - '../src/PhpScoper/*' - - Symfony\Component\Filesystem\Filesystem: null - - OndraM\CiDetector\CiDetector: null diff --git a/compiler/src/HttpKernel/RectorCompilerKernel.php b/compiler/src/HttpKernel/RectorCompilerKernel.php index 850f366a9664..c296fd7f7235 100644 --- a/compiler/src/HttpKernel/RectorCompilerKernel.php +++ b/compiler/src/HttpKernel/RectorCompilerKernel.php @@ -27,7 +27,7 @@ public function getLogDir(): string public function registerContainerConfiguration(LoaderInterface $loader): void { - $loader->load(__DIR__ . '/../../config/config.yaml'); + $loader->load(__DIR__ . '/../../config/config.php'); } /** From 46b3090e3784361bc61e01e189621d75dd012a1a Mon Sep 17 00:00:00 2001 From: TomasVotruba Date: Sun, 19 Jul 2020 10:34:30 +0200 Subject: [PATCH 3/4] move symfony style to root config --- compiler/build/scoper.inc.php | 17 +++++++-- .../src/Console/Command/CompileCommand.php | 2 +- config/services.php | 7 ++++ create-rector.php | 38 ------------------- packages/console-differ/config/config.php | 5 --- 5 files changed, 22 insertions(+), 47 deletions(-) delete mode 100644 create-rector.php diff --git a/compiler/build/scoper.inc.php b/compiler/build/scoper.inc.php index baa2d88da5e5..6e32483729c0 100644 --- a/compiler/build/scoper.inc.php +++ b/compiler/build/scoper.inc.php @@ -88,15 +88,26 @@ function (string $filePath, string $prefix, string $content): string { // unprefix configuraion in sets, @see https://github.com/rectorphp/rector/issues/3227 function (string $filePath, string $prefix, string $content): string { - // only *.yaml files - if (! Strings::endsWith($filePath, '.yaml')) { + // only sets + if (! Strings::startsWith($filePath, 'config/set/')) { return $content; } - if (! Strings::startsWith($filePath, 'config/set/')) { + return StaticEasyPrefixer::unPrefixQuotedValues($prefix, $content); + }, + + // unprefix all excluded classes + function (string $filePath, string $prefix, string $content): string { + // only sets + if (! Strings::endsWith($filePath, '*.php')) { return $content; } + foreach (StaticEasyPrefixer::EXCLUDED_NAMESPACES_AND_CLASSES as $excludedNamespaceAndClass) { + dump($excludedNamespaceAndClass); + die; + } + return StaticEasyPrefixer::unPrefixQuotedValues($prefix, $content); }, diff --git a/compiler/src/Console/Command/CompileCommand.php b/compiler/src/Console/Command/CompileCommand.php index 1134b6616ec6..076428c4b8a8 100644 --- a/compiler/src/Console/Command/CompileCommand.php +++ b/compiler/src/Console/Command/CompileCommand.php @@ -137,7 +137,7 @@ private function restoreDependenciesLocallyIfNotCi(OutputInterface $output): voi return; } - $process = new Process(['composer', 'install'], $this->buildDir, null, null, null); + $process = new Process(['composer', 'install', '--ansi'], $this->buildDir, null, null, null); $process->mustRun(static function (string $type, string $buffer) use ($output): void { $output->write($buffer); }); diff --git a/config/services.php b/config/services.php index d1d5eb69fcce..5fecd863d2df 100644 --- a/config/services.php +++ b/config/services.php @@ -16,7 +16,9 @@ use Rector\Core\PhpParser\Parser\NikicPhpParserFactory; use Symfony\Component\Console\Application as SymfonyApplication; use Symfony\Component\Console\Descriptor\TextDescriptor; +use Symfony\Component\Console\Style\SymfonyStyle; use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator; +use Symplify\PackageBuilder\Console\Style\SymfonyStyleFactory; use function Symfony\Component\DependencyInjection\Loader\Configurator\ref; use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\Filesystem\Filesystem; @@ -89,4 +91,9 @@ $services->alias(EventDispatcherInterface::class, AutowiredEventDispatcher::class); $services->set(SmartFileSystem::class); + + $services->set(SymfonyStyleFactory::class); + + $services->set(SymfonyStyle::class) + ->factory([ref(SymfonyStyleFactory::class), 'create']); }; diff --git a/create-rector.php b/create-rector.php deleted file mode 100644 index f5b415b3ca5a..000000000000 --- a/create-rector.php +++ /dev/null @@ -1,38 +0,0 @@ -parameters(); - - $parameters->set(Option::RECTOR_RECIPE, [ - # run "bin/rector create" to create a new Rector + tests from this config - 'package' => 'Symfony', - 'name' => 'RemoveDefaultGetBlockPrefixRector', - 'node_types' => ['ClassMethod'], - 'description' => 'Rename `getBlockPrefix()` if it returns the default value - class to underscore, e.g. UserFormType = user_form', - 'code_before' => ' ' [ - # e.g. link to RFC or headline in upgrade guide, 1 or more in the list - 'https://github.com/symfony/symfony/blob/3.4/UPGRADE-3.0.md', - ], - # e.g. symfony30, target config to append this rector to - 'set' => 'symfony30', - ]); -}; diff --git a/packages/console-differ/config/config.php b/packages/console-differ/config/config.php index d305a5dbaf34..9de2535f0f49 100644 --- a/packages/console-differ/config/config.php +++ b/packages/console-differ/config/config.php @@ -50,9 +50,4 @@ $services->set(ColorConsoleDiffFormatter::class); $services->set(ConsoleDiffer::class); - - $services->set(SymfonyStyleFactory::class); - - $services->set(SymfonyStyle::class) - ->factory([ref(SymfonyStyleFactory::class), 'create']); }; From 0a29fe0c0a9461224a8f6b7dc6f9be5489027391 Mon Sep 17 00:00:00 2001 From: TomasVotruba Date: Mon, 20 Jul 2020 10:20:23 +0200 Subject: [PATCH 4/4] fix scoper --- compiler/build/scoper.inc.php | 72 ++++++++++++------- compiler/config/config.php | 1 - .../src/Composer/ComposerJsonManipulator.php | 4 +- .../src/Console/Command/CompileCommand.php | 30 +++++--- compiler/src/PhpScoper/StaticEasyPrefixer.php | 26 +++++-- config/services.php | 2 +- packages/console-differ/config/config.php | 2 - 7 files changed, 93 insertions(+), 44 deletions(-) diff --git a/compiler/build/scoper.inc.php b/compiler/build/scoper.inc.php index 6e32483729c0..52bb6453bfe2 100644 --- a/compiler/build/scoper.inc.php +++ b/compiler/build/scoper.inc.php @@ -20,7 +20,7 @@ 'files-whitelist' => $whitelistedStubsProvider->provide(), 'patchers' => [ function (string $filePath, string $prefix, string $content): string { - if ($filePath !== 'bin/rector') { + if ($filePath !== 'bin/rector' /* && ! Strings::contains($filePath, 'config/')*/) { return $content; } @@ -61,7 +61,7 @@ function (string $filePath, string $prefix, string $content): string { ); }, function (string $filePath, string $prefix, string $content): string { - if ($filePath !== 'src/Testing/TestCase.php') { + if ($filePath !== 'vendor/phpstan/phpstan-src/src/Testing/TestCase.php') { return $content; } @@ -72,7 +72,7 @@ function (string $filePath, string $prefix, string $content): string { ); }, function (string $filePath, string $prefix, string $content): string { - if ($filePath !== 'src/Testing/LevelsTestCase.php') { + if ($filePath !== 'vendor/phpstan/phpstan-src/src/Testing/LevelsTestCase.php') { return $content; } @@ -86,29 +86,15 @@ function (string $filePath, string $prefix, string $content): string { ); }, - // unprefix configuraion in sets, @see https://github.com/rectorphp/rector/issues/3227 + // unprefix excluded classes + // fixes https://github.com/humbug/box/issues/470 function (string $filePath, string $prefix, string $content): string { - // only sets - if (! Strings::startsWith($filePath, 'config/set/')) { - return $content; + foreach (StaticEasyPrefixer::EXCLUDED_CLASSES as $excludedClass) { + $prefixedClassPattern = '#' . $prefix . '\\\\' . preg_quote($excludedClass, '#') . '#'; + $content = Strings::replace($content, $prefixedClassPattern, $excludedClass); } - return StaticEasyPrefixer::unPrefixQuotedValues($prefix, $content); - }, - - // unprefix all excluded classes - function (string $filePath, string $prefix, string $content): string { - // only sets - if (! Strings::endsWith($filePath, '*.php')) { - return $content; - } - - foreach (StaticEasyPrefixer::EXCLUDED_NAMESPACES_AND_CLASSES as $excludedNamespaceAndClass) { - dump($excludedNamespaceAndClass); - die; - } - - return StaticEasyPrefixer::unPrefixQuotedValues($prefix, $content); + return $content; }, // mimics https://github.com/phpstan/phpstan-src/commit/5a6a22e5c4d38402c8cc888d8732360941c33d43#diff-463a36e4a5687fb2366b5ee56cdad92d @@ -161,6 +147,44 @@ function (string $filePath, string $prefix, string $content): string { return StaticEasyPrefixer::unPreSlashQuotedValues($content); }, + + // mimics + // https://github.com/phpstan/phpstan-src/commit/9c2eb91b630bdfee2c1bb642a4c81ebfa0f1ca9a#diff-87f75ce3f908a819a9a2c77ffeffcc38 + // https://github.com/phpstan/phpstan-src/commit/7048109ab17aa16102dc0fd21190782e6d6d5e7e#diff-87f75ce3f908a819a9a2c77ffeffcc38 + function (string $filePath, string $prefix, string $content): string { + if (! in_array($filePath, [ + 'vendor/phpstan/phpstan-src/src/Type/TypehintHelper.php', + 'vendor/ondrejmirtes/better-reflection/src/Reflection/Adapter/ReflectionUnionType.php', + ], true)) { + return $content; + } + + return str_replace(sprintf('%s\\ReflectionUnionType', $prefix), 'ReflectionUnionType', $content); + }, + + // mimics: https://github.com/phpstan/phpstan-src/commit/6bb92ed7b92b186bb1eb5111bc49ec7679ed780f#diff-87f75ce3f908a819a9a2c77ffeffcc38 + function (string $filePath, string $prefix, string $content): string { + return str_replace('private static final', 'private static', $content); + }, + + // mimics: https://github.com/phpstan/phpstan-src/commit/1c63a785e5fce8d031b04f52c61904bd57b51e27#diff-87f75ce3f908a819a9a2c77ffeffcc38 + function (string $filePath, string $prefix, string $content): string { + if (! in_array($filePath, [ + 'vendor/phpstan/phpstan-src/src/Testing/TestCaseSourceLocatorFactory.php', + 'vendor/phpstan/phpstan-src/src/Testing/TestCase.php', + ], true)) { + return $content; + } + + return str_replace( + sprintf('%s\\Composer\\Autoload\\ClassLoader', $prefix), + 'Composer\\Autoload\\ClassLoader', + $content + ); + }, + + + ], - 'whitelist' => StaticEasyPrefixer::EXCLUDED_NAMESPACES_AND_CLASSES, + 'whitelist' => StaticEasyPrefixer::getExcludedNamespacesAndClasses(), ]; diff --git a/compiler/config/config.php b/compiler/config/config.php index 0de088c65e08..95932bf91635 100644 --- a/compiler/config/config.php +++ b/compiler/config/config.php @@ -3,7 +3,6 @@ declare(strict_types=1); use OndraM\CiDetector\CiDetector; -use Rector\Core\Configuration\Option; use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator; use Symfony\Component\Filesystem\Filesystem; diff --git a/compiler/src/Composer/ComposerJsonManipulator.php b/compiler/src/Composer/ComposerJsonManipulator.php index eecd7ee11547..e9d006cb6197 100644 --- a/compiler/src/Composer/ComposerJsonManipulator.php +++ b/compiler/src/Composer/ComposerJsonManipulator.php @@ -65,7 +65,9 @@ public function fixComposerJson(string $composerJsonFile): void $encodedJson = Json::encode($json, Json::PRETTY); // show diff - $this->consoleDiffer->diff($this->originalComposerJsonFileContent, $encodedJson); + if ($encodedJson !== $this->originalComposerJsonFileContent) { + $this->consoleDiffer->diff($this->originalComposerJsonFileContent, $encodedJson); + } $this->filesystem->dumpFile($composerJsonFile, $encodedJson); } diff --git a/compiler/src/Console/Command/CompileCommand.php b/compiler/src/Console/Command/CompileCommand.php index 076428c4b8a8..e0b7358050a1 100644 --- a/compiler/src/Console/Command/CompileCommand.php +++ b/compiler/src/Console/Command/CompileCommand.php @@ -20,6 +20,11 @@ */ final class CompileCommand extends Command { + /** + * @var string + */ + private const ANSI = '--ansi'; + /** * @var string */ @@ -80,6 +85,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int $composerJsonFile = $this->buildDir . '/composer.json'; $this->symfonyStyle->title('1. Adding "phpstan/phpstan-src" to ' . $composerJsonFile); + $this->composerJsonManipulator->fixComposerJson($composerJsonFile); $this->symfonyStyle->newLine(2); @@ -93,39 +99,43 @@ protected function execute(InputInterface $input, OutputInterface $output): int '--prefer-dist', '--no-interaction', '--classmap-authoritative', - '--ansi', + self::ANSI, ], $this->buildDir, null, null, null); - $process->mustRun(static function (string $type, string $buffer) use ($output): void { $output->write($buffer); }); $this->symfonyStyle->newLine(2); + $this->symfonyStyle->title('3. Downgrading PHPStan code to PHP 7.1'); + $this->downgradePHPStanCodeToPHP71($output); - $this->symfonyStyle->title('3. Renaming PHPStorm stubs from "*.php" to ".stub"'); + $this->symfonyStyle->title('4. Renaming PHPStorm stubs from "*.php" to ".stub"'); $this->jetbrainsStubsRenamer->renamePhpStormStubs($this->buildDir); - $this->symfonyStyle->newLine(2); // the '--no-parallel' is needed, so "scoper.php.inc" can "require __DIR__ ./vendor/autoload.php" // and "Nette\Neon\Neon" class can be used there - $this->symfonyStyle->title('4. Packing and prefixing rector.phar with Box and PHP Scoper'); - - $process = new Process(['php', 'box.phar', 'compile', '--no-parallel'], $this->dataDir, null, null, null); + $this->symfonyStyle->title('5. Packing and prefixing rector.phar with Box and PHP Scoper'); + $process = new Process([ + 'php', + 'box.phar', + 'compile', + '--no-parallel', + self::ANSI, + ], $this->dataDir, null, null, null); $process->mustRun(static function (string $type, string $buffer) use ($output): void { $output->write($buffer); }); $this->symfonyStyle->newLine(2); - $this->symfonyStyle->title('5. Restoring root composer.json with "require-dev"'); + $this->symfonyStyle->title('6. Restoring root composer.json with "require-dev"'); $this->composerJsonManipulator->restoreComposerJson($composerJsonFile); - $this->restoreDependenciesLocallyIfNotCi($output); return ShellCode::SUCCESS; @@ -137,7 +147,7 @@ private function restoreDependenciesLocallyIfNotCi(OutputInterface $output): voi return; } - $process = new Process(['composer', 'install', '--ansi'], $this->buildDir, null, null, null); + $process = new Process(['composer', 'install', self::ANSI], $this->buildDir, null, null, null); $process->mustRun(static function (string $type, string $buffer) use ($output): void { $output->write($buffer); }); diff --git a/compiler/src/PhpScoper/StaticEasyPrefixer.php b/compiler/src/PhpScoper/StaticEasyPrefixer.php index 8602cb71995a..3f4a2c2e7565 100644 --- a/compiler/src/PhpScoper/StaticEasyPrefixer.php +++ b/compiler/src/PhpScoper/StaticEasyPrefixer.php @@ -11,22 +11,30 @@ final class StaticEasyPrefixer /** * @var string[] */ - public const EXCLUDED_NAMESPACES_AND_CLASSES = [ + public const EXCLUDED_CLASSES = [ + 'Symfony\Component\EventDispatcher\EventSubscriberInterface', + 'Symfony\Component\Console\Style\SymfonyStyle', + // doctrine annotations to autocomplete + 'JMS\DiExtraBundle\Annotation\Inject', + ]; + + /** + * @var string[] + */ + private const EXCLUDED_NAMESPACES = [ 'Hoa\*', 'PhpParser\*', 'PHPStan\*', 'Rector\*', 'Symplify\SmartFileSystem\*', - 'Symfony\Component\EventDispatcher\EventSubscriberInterface', - 'Symfony\Component\Console\Style\SymfonyStyle', + 'Symplify\ConsoleColorDiff\*', // doctrine annotations to autocomplete 'Doctrine\ORM\Mapping\*', - 'JMS\DiExtraBundle\Annotation\Inject', ]; public static function prefixClass(string $class, string $prefix): string { - foreach (self::EXCLUDED_NAMESPACES_AND_CLASSES as $excludedNamespace) { + foreach (self::EXCLUDED_NAMESPACES as $excludedNamespace) { $excludedNamespace = Strings::substring($excludedNamespace, 0, -2) . '\\'; if (Strings::startsWith($class, $excludedNamespace)) { return $class; @@ -54,4 +62,12 @@ public static function unPreSlashQuotedValues(string $content): string { return Strings::replace($content, '#\'\\\\(\w|@)#', "'$1"); } + + /** + * @return string[] + */ + public static function getExcludedNamespacesAndClasses(): array + { + return array_merge(self::EXCLUDED_NAMESPACES, self::EXCLUDED_CLASSES); + } } diff --git a/config/services.php b/config/services.php index 5fecd863d2df..20e8fd4fb045 100644 --- a/config/services.php +++ b/config/services.php @@ -18,10 +18,10 @@ use Symfony\Component\Console\Descriptor\TextDescriptor; use Symfony\Component\Console\Style\SymfonyStyle; use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator; -use Symplify\PackageBuilder\Console\Style\SymfonyStyleFactory; use function Symfony\Component\DependencyInjection\Loader\Configurator\ref; use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\Filesystem\Filesystem; +use Symplify\PackageBuilder\Console\Style\SymfonyStyleFactory; use Symplify\PackageBuilder\Parameter\ParameterProvider; use Symplify\PackageBuilder\Reflection\PrivatesAccessor; use Symplify\PackageBuilder\Reflection\PrivatesCaller; diff --git a/packages/console-differ/config/config.php b/packages/console-differ/config/config.php index 9de2535f0f49..17dcd667a02b 100644 --- a/packages/console-differ/config/config.php +++ b/packages/console-differ/config/config.php @@ -8,12 +8,10 @@ use SebastianBergmann\Diff\Differ; use SebastianBergmann\Diff\Output\StrictUnifiedDiffOutputBuilder; use SebastianBergmann\Diff\Output\UnifiedDiffOutputBuilder; -use Symfony\Component\Console\Style\SymfonyStyle; use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator; use function Symfony\Component\DependencyInjection\Loader\Configurator\ref; use Symplify\ConsoleColorDiff\Console\Formatter\ColorConsoleDiffFormatter; use Symplify\ConsoleColorDiff\Console\Output\ConsoleDiffer; -use Symplify\PackageBuilder\Console\Style\SymfonyStyleFactory; return static function (ContainerConfigurator $containerConfigurator): void { $services = $containerConfigurator->services();