[2.x] [rector] error thrown using `FoundrySetList` && `PersistenceResolver` w/ custom generator
>> rector process -c ./rector.php --clear-cache --dry-run produces:
...
[ERROR] Could not process "/home/jrdev/develop/php/big-desk/src/Factory/NoteFactory.php" file, due to:
"System error: "Cannot instantiate custom generator : array (
'class' => 'doctrine.uuid_generator',
)"
Run Rector with "--debug" option and post the report here: https://github.com/rectorphp/rector/issues/new". On line: 23
w/ --debug
[ERROR] Could not process "/home/jrdev/develop/php/big-desk/src/Factory/NoteFactory.php" file, due to:
"System error: "Cannot instantiate custom generator : array (
'class' => 'doctrine.uuid_generator',
)"
Stack trace:
#0 vendor/doctrine/orm/src/Mapping/ClassMetadataFactory.php(604):
Doctrine\ORM\Mapping\Exception\InvalidCustomGenerator::onMissingClass(Array)
#1 vendor/doctrine/orm/src/Mapping/ClassMetadataFactory.php(174):
Doctrine\ORM\Mapping\ClassMetadataFactory->completeIdGeneratorMapping(Object(Doctrine\ORM\Mapping\ClassMetadat
a))
#2 vendor/doctrine/persistence/src/Persistence/Mapping/AbstractClassMetadataFactory.php(343):
Doctrine\ORM\Mapping\ClassMetadataFactory->doLoadMetadata(Object(Doctrine\ORM\Mapping\ClassMetadata), NULL,
false, Array)
#3 vendor/doctrine/persistence/src/Persistence/Mapping/AbstractClassMetadataFactory.php(225):
Doctrine\Persistence\Mapping\AbstractClassMetadataFactory->loadMetadata('App\\Entity\\Note')
#4 tools/rector/vendor/phpstan/phpstan-doctrine/src/Type/Doctrine/ObjectMetadataResolver.php(129):
Doctrine\Persistence\Mapping\AbstractClassMetadataFactory->getMetadataFor('App\\Entity\\Note')
#5 vendor/zenstruck/foundry/utils/rector/src/PersistenceResolver.php(109):
PHPStan\Type\Doctrine\ObjectMetadataResolver->getClassMetadata('App\\Entity\\Note')
#6 vendor/zenstruck/foundry/utils/rector/src/PersistenceResolver.php(62):
Zenstruck\Foundry\Utils\Rector\PersistenceResolver->isPersisted('App\\Entity\\Note')
#7 vendor/zenstruck/foundry/utils/rector/src/PersistenceResolver.php(54):
Zenstruck\Foundry\Utils\Rector\PersistenceResolver->shouldUseProxyFactory('App\\Entity\\Note')
#8 vendor/zenstruck/foundry/utils/rector/src/RewriteFactoryPhpDoc/RewriteFactoryPhpDoc.php(97):
Zenstruck\Foundry\Utils\Rector\PersistenceResolver->shouldTransformFactoryIntoObjectFactory('App\\Factory\\Not
...')
#9 tools/rector/vendor/rector/rector/src/Rector/AbstractRector.php(136):
Zenstruck\Foundry\Utils\Rector\RewriteFactoryPhpDoc\RewriteFactoryPhpDoc->refactor(Object(PhpParser\Node\Stmt\
Class_))
#10 tools/rector/vendor/rector/rector/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php(176):
Rector\Rector\AbstractRector->enterNode(Object(PhpParser\Node\Stmt\Class_))
#11 tools/rector/vendor/rector/rector/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php(105):
PhpParser\NodeTraverser->traverseArray(Array)
#12 tools/rector/vendor/rector/rector/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php(196):
PhpParser\NodeTraverser->traverseNode(Object(PhpParser\Node\Stmt\Namespace_))
#13 tools/rector/vendor/rector/rector/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php(85):
PhpParser\NodeTraverser->traverseArray(Array)
#14 tools/rector/vendor/rector/rector/src/PhpParser/NodeTraverser/RectorNodeTraverser.php(41):
PhpParser\NodeTraverser->traverse(Array)
#15 tools/rector/vendor/rector/rector/src/Application/FileProcessor.php(105):
Rector\PhpParser\NodeTraverser\RectorNodeTraverser->traverse(Array)
#16 tools/rector/vendor/rector/rector/src/Application/ApplicationFileProcessor.php(184):
Rector\Application\FileProcessor->processFile(Object(Rector\ValueObject\Application\File),
Object(Rector\ValueObject\Configuration))
#17 tools/rector/vendor/rector/rector/src/Application/ApplicationFileProcessor.php(161):
Rector\Application\ApplicationFileProcessor->processFile(Object(Rector\ValueObject\Application\File),
Object(Rector\ValueObject\Configuration))
#18 tools/rector/vendor/rector/rector/src/Console/Command/WorkerCommand.php(118):
Rector\Application\ApplicationFileProcessor->processFiles(Array, Object(Rector\ValueObject\Configuration),
Object(Closure))
#19 tools/rector/vendor/rector/rector/vendor/evenement/evenement/src/EventEmitterTrait.php(111):
Rector\Console\Command\WorkerCommand->Rector\Console\Command\{closure}(Array)
#20 tools/rector/vendor/rector/rector/vendor/clue/ndjson-react/src/Decoder.php(117):
RectorPrefix202402\Evenement\EventEmitter->emit('data', Array)
#21 tools/rector/vendor/rector/rector/vendor/evenement/evenement/src/EventEmitterTrait.php(111):
RectorPrefix202402\Clue\React\NDJson\Decoder->handleData(Array)
#22 tools/rector/vendor/rector/rector/vendor/react/stream/src/Util.php(62):
RectorPrefix202402\Evenement\EventEmitter->emit('data', Array)
#23 tools/rector/vendor/rector/rector/vendor/evenement/evenement/src/EventEmitterTrait.php(111):
RectorPrefix202402\React\Stream\Util::RectorPrefix202402\React\Stream\{closure}('{"action":"main...')
#24 tools/rector/vendor/rector/rector/vendor/react/stream/src/DuplexResourceStream.php(154):
RectorPrefix202402\Evenement\EventEmitter->emit('data', Array)
#25 tools/rector/vendor/rector/rector/vendor/react/event-loop/src/StreamSelectLoop.php(201):
RectorPrefix202402\React\Stream\DuplexResourceStream->handleData(Resource id #1970)
#26 tools/rector/vendor/rector/rector/vendor/react/event-loop/src/StreamSelectLoop.php(173):
RectorPrefix202402\React\EventLoop\StreamSelectLoop->waitForStreamActivity(NULL)
#27 tools/rector/vendor/rector/rector/src/Console/Command/WorkerCommand.php(89):
RectorPrefix202402\React\EventLoop\StreamSelectLoop->run()
#28 tools/rector/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))
#29 tools/rector/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))
#30 tools/rector/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))
#31 tools/rector/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))
#32 tools/rector/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))
#33 tools/rector/vendor/rector/rector/bin/rector.php(130):
RectorPrefix202402\Symfony\Component\Console\Application->run()
#34 tools/rector/vendor/rector/rector/bin/rector(5): require_once('/home/jrdev/dev...')
#35 tools/rector/vendor/bin/rector(119): include('/home/jrdev/dev...')
#36 {main}". On line: 23
Entity Property:
// Symfony's UID Component
#[
ORM\Id,
ORM\Column(type: UuidType::NAME),
ORM\GeneratedValue(strategy: 'CUSTOM'),
ORM\CustomIdGenerator(class: 'doctrine.uuid_generator')
]
protected Uuid $id;
Rector config:
<?php
use Rector\Config\RectorConfig;
use Rector\PHPUnit\CodeQuality\Rector\Class_\PreferPHPUnitThisCallRector;
use Rector\PHPUnit\Set\PHPUnitSetList;
use Rector\Set\ValueObject\LevelSetList;
use Rector\Set\ValueObject\SetList;
use Rector\Symfony\Set\SymfonySetList;
return static function (RectorConfig $config): void {
$config->paths([
__DIR__.'/src',
__DIR__.'/tests',
]);
$config->bootstrapFiles([
__DIR__.'/vendor/autoload.php',
__DIR__.'/tools/rector/vendor/autoload.php',
]);
$config->symfonyContainerXml(__DIR__.'/var/cache/test/App_KernelTestDebugContainer.xml');
$config->symfonyContainerPhp(__DIR__.'/tests/rector-bootstrap.php');
$config->singleton(\Zenstruck\Foundry\Utils\Rector\PersistenceResolver::class,
static fn() => new \Zenstruck\Foundry\Utils\Rector\PersistenceResolver(
// Note- rector-bootstrap returns a ContainerInterface for the symfonyContainerPhp() method above
(require __DIR__.'/tests/rector-bootstrap.php')->get('doctrine')->getManager())
);
$config->sets([
\Zenstruck\Foundry\Utils\Rector\FoundrySetList::UP_TO_FOUNDRY_2,
LevelSetList::UP_TO_PHP_83,
SetList::DEAD_CODE,
SymfonySetList::SYMFONY_64,
PHPUnitSetList::ANNOTATIONS_TO_ATTRIBUTES,
PHPUnitSetList::PHPUNIT_100,
]);
$config->skip([
PreferPHPUnitThisCallRector::class
]);
};
Temp. Workaround: Comment out the attribute(s) for the generator -> run rector -> remove comments.
// Symfony's UID Component
// #[
// ORM\Id,
// ORM\Column(type: UuidType::NAME),
// ORM\GeneratedValue(strategy: 'CUSTOM'),
// ORM\CustomIdGenerator(class: 'doctrine.uuid_generator')
// ]
protected Uuid $id;
thank you to give a try to this whole upgrade path! I've tested it on several projects of mine, as well as @kbond did, but that's cool it gets tested on other projects before we release it
don't hesitate to post other problems you encounter, I'll fix them quickly
Hi @jrushlow
could you show your rector-bootstrap.php file please?
it seems strange that you have the problem, because it seems you're passing the entity manager from Symfony's container, and based on what is said in the following issues, this seems enough :thinking:
https://github.com/phpstan/phpstan-doctrine/issues/297 https://github.com/rectorphp/rector/issues/7911
I'm closing this, since it's kinda not related to Foundry