rectorphp / rector

Instant Upgrades and Automated Refactoring of any PHP 5.3+ code
https://getrector.com
MIT License
8.61k stars 680 forks source link

StringExtensionToConfigBuilderRector not propelry working #8474

Closed Perf closed 7 months ago

Perf commented 7 months ago

Bug Report

Subject Details
Rector version 1.0.0
Symfony version 6.4.3
PHP version 8.3.2

I am trying to follow the quide https://getrector.com/blog/modernize-symfony-configs to convert YAML config files to a proper PHP ones with full support for IDE autocomplete. I stuck on a step: "How can we flip those arrays to config builder classes?" I am running command vendor/bin/rector p config/packages/security.php But getting an error:

[ERROR] Could not process "config/packages/security.php" file, due to:
"System error: "Split extensions "security" to multiple separated files first"
Run Rector with "--debug" option and post the report here: https://github.com/rectorphp/rector/issues/new". On line: 40

Debug output

[ERROR] Could not process "config/packages/security.php" file, due to:                                                 
"System error: "Split extensions "security" to multiple separated files first"                                 

Stack trace:                                                                                                   
#0                                                                                                             
vendor/rector/rector/vendor/rector/rector-symfony/rules/CodeQuality/Rector/Closure/StringExtensionToConfigBuild
erRector.php(130):                                                                                             
Rector\Symfony\NodeAnalyzer\SymfonyClosureExtensionMatcher->match(Object(PhpParser\Node\Expr\Closure))         
#1 vendor/rector/rector/src/Rector/AbstractRector.php(136):                                                    
Rector\Symfony\CodeQuality\Rector\Closure\StringExtensionToConfigBuilderRector->refactor(Object(PhpParser\Node 
\Expr\Closure))
#2 vendor/rector/rector/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php(113):
Rector\Rector\AbstractRector->enterNode(Object(PhpParser\Node\Expr\Closure))
#3 vendor/rector/rector/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php(196):
PhpParser\NodeTraverser->traverseNode(Object(PhpParser\Node\Stmt\Return_))
#4 vendor/rector/rector/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php(105):
PhpParser\NodeTraverser->traverseArray(Array)
#5 vendor/rector/rector/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php(196):
PhpParser\NodeTraverser->traverseNode(Object(Rector\PhpParser\Node\CustomNode\FileWithoutNamespace))
#6 vendor/rector/rector/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php(85):
PhpParser\NodeTraverser->traverseArray(Array)
#7 vendor/rector/rector/src/PhpParser/NodeTraverser/RectorNodeTraverser.php(41):
PhpParser\NodeTraverser->traverse(Array)
#8 vendor/rector/rector/src/Application/FileProcessor.php(105):
Rector\PhpParser\NodeTraverser\RectorNodeTraverser->traverse(Array)
#9 vendor/rector/rector/src/Application/ApplicationFileProcessor.php(184):
Rector\Application\FileProcessor->processFile(Object(Rector\ValueObject\Application\File),
Object(Rector\ValueObject\Configuration))
#10 vendor/rector/rector/src/Application/ApplicationFileProcessor.php(161):
Rector\Application\ApplicationFileProcessor->processFile(Object(Rector\ValueObject\Application\File),
Object(Rector\ValueObject\Configuration))
#11 vendor/rector/rector/src/Console/Command/WorkerCommand.php(118):
Rector\Application\ApplicationFileProcessor->processFiles(Array, Object(Rector\ValueObject\Configuration),
Object(Closure))
#12 vendor/rector/rector/vendor/evenement/evenement/src/EventEmitterTrait.php(111):
Rector\Console\Command\WorkerCommand->Rector\Console\Command\{closure}(Array)
#13 vendor/rector/rector/vendor/clue/ndjson-react/src/Decoder.php(117):
RectorPrefix202402\Evenement\EventEmitter->emit('data', Array)
#14 vendor/rector/rector/vendor/evenement/evenement/src/EventEmitterTrait.php(111):
RectorPrefix202402\Clue\React\NDJson\Decoder->handleData(Array)
#15 vendor/rector/rector/vendor/react/stream/src/Util.php(62):
RectorPrefix202402\Evenement\EventEmitter->emit('data', Array)
#16 vendor/rector/rector/vendor/evenement/evenement/src/EventEmitterTrait.php(111):
RectorPrefix202402\React\Stream\Util::RectorPrefix202402\React\Stream\{closure}('{"action":"main...')
#17 vendor/rector/rector/vendor/react/stream/src/DuplexResourceStream.php(154):
RectorPrefix202402\Evenement\EventEmitter->emit('data', Array)
#18 vendor/rector/rector/vendor/react/event-loop/src/StreamSelectLoop.php(201):
RectorPrefix202402\React\Stream\DuplexResourceStream->handleData(Resource id #1916)
#19 vendor/rector/rector/vendor/react/event-loop/src/StreamSelectLoop.php(173):
RectorPrefix202402\React\EventLoop\StreamSelectLoop->waitForStreamActivity(NULL)
#20 vendor/rector/rector/src/Console/Command/WorkerCommand.php(89):
RectorPrefix202402\React\EventLoop\StreamSelectLoop->run()
#21 vendor/rector/rector/vendor/symfony/console/Command/Command.php(327):
Rector\Console\Command\WorkerCommand->execute(Object(RectorPrefix202402\Symfony\Component\Console\Input\ArgvIn
put), Object(RectorPrefix202402\Symfony\Component\Console\Output\ConsoleOutput))
#22 vendor/rector/rector/vendor/symfony/console/Application.php(960):
RectorPrefix202402\Symfony\Component\Console\Command\Command->run(Object(RectorPrefix202402\Symfony\Component\
Console\Input\ArgvInput), Object(RectorPrefix202402\Symfony\Component\Console\Output\ConsoleOutput))
#23 vendor/rector/rector/vendor/symfony/console/Application.php(333):
RectorPrefix202402\Symfony\Component\Console\Application->doRunCommand(Object(Rector\Console\Command\WorkerCom
mand), Object(RectorPrefix202402\Symfony\Component\Console\Input\ArgvInput),
Object(RectorPrefix202402\Symfony\Component\Console\Output\ConsoleOutput))
#24 vendor/rector/rector/src/Console/ConsoleApplication.php(53):
RectorPrefix202402\Symfony\Component\Console\Application->doRun(Object(RectorPrefix202402\Symfony\Component\Co
nsole\Input\ArgvInput), Object(RectorPrefix202402\Symfony\Component\Console\Output\ConsoleOutput))
#25 vendor/rector/rector/vendor/symfony/console/Application.php(216):
Rector\Console\ConsoleApplication->doRun(Object(RectorPrefix202402\Symfony\Component\Console\Input\ArgvInput),
Object(RectorPrefix202402\Symfony\Component\Console\Output\ConsoleOutput))
#26 vendor/rector/rector/bin/rector.php(130): RectorPrefix202402\Symfony\Component\Console\Application->run()
#27 vendor/rector/rector/bin/rector(5): require_once('vendor/rec...')
#28 vendor/bin/rector(119): include('vendor/rec...')
#29 {main}". On line: 40

Expected Behaviour

security.php config should look something like:

use Symfony\Config\SecurityConfig;

return static function (SecurityConfig $securityConfig): void {
    $securityConfig->enableAuthenticatorManager(true);
};
TomasVotruba commented 7 months ago

Thank you for your report!

We'll need an isolated failing demo link from: http://getrector.com/demo, that way we can reproduce the bug.

Perf commented 7 months ago

hey @TomasVotruba, thank you for quick response! I tried to use this environment, but it seems it's not suitable for my case. Nevertheless, here it is: https://getrector.com/demo/f6e93322-c48d-4f01-bfba-cb32b8b680ab

TomasVotruba commented 7 months ago

Thanks :+1:

Looks good, just the configs contained non-existing paths and extra rules. Always use only the reported rule, so we are sure it's not mix of other rules. See: https://getrector.com/demo/7e07ee71-581b-4477-a83b-5f24876c96ee

The provided config could not be converted, because there is dependency on external check:

if ($containerConfigurator->env() === 'test') {

The solution is to split this part as suggested in the exception error. To env /config/tests and load it there without inner condition.

Perf commented 7 months ago

Hi @TomasVotruba, thanx a lot for looking into it! So, as I understood, I need to extract part of code inside if ($containerConfigurator->env() === 'test') { into a separate file like security_test.php, correct?

TomasVotruba commented 7 months ago

Yes, something like that. The exact path depends on your Kernel setup.

Check symfony/demo project for standard location and Kerneloading