Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Support] Running Rector on a PHP 7.2 project #2417

Closed
gnutix opened this issue Dec 10, 2019 · 18 comments
Closed

[Support] Running Rector on a PHP 7.2 project #2417

gnutix opened this issue Dec 10, 2019 · 18 comments

Comments

@gnutix
Copy link
Contributor

gnutix commented Dec 10, 2019

I'll centralize all my reports in this ticket, otherwise it'll get messy. All my attempts are simply to get Rector running on my company's project : which is using ocramius/hydrated-generator, which depends on nikic/php-parser, and as we're running on PHP 7.2, it's restricted to a lower version which clashes with the version 4.x included in Rector's vendors.

My latest error has been reported here and still occurs with the latest PHAR version and can be resumed with :

PHP Fatal error:  Uncaught _HumbugBox655fe0f4d050\Nette\FileNotFoundException: File '/composer/vendor/phpstan/phpstan-symfony/extension.neon' is missing or is not readable. in phar:///home/gnutix/dev/oss/rector/tmp/rector.phar/vendor/nette/di/src/DI/Config/Loader.php:29
Stack trace:
#0 phar:///home/gnutix/dev/oss/rector/tmp/rector.phar/vendor/nette/di/src/DI/Config/Loader.php(43): _HumbugBox655fe0f4d050\Nette\DI\Config\Loader->load('/composer/vendo...', false)
#1 phar:///home/gnutix/dev/oss/rector/tmp/rector.phar/vendor/nette/di/src/DI/Compiler.php(98): _HumbugBox655fe0f4d050\Nette\DI\Config\Loader->load('/home/gnutix/de...', false)
#2 phar:///home/gnutix/dev/oss/rector/tmp/rector.phar/vendor/nette/bootstrap/src/Bootstrap/Configurator.php(186): _HumbugBox655fe0f4d050\Nette\DI\Compiler->loadConfig('/home/gnutix/de...', Object(_HumbugBox655fe0f4d050\Nette\DI\Config\Loader))
#3 phar:///home/gnutix/dev/oss/rector/tmp/rector.phar/vendor/nette/di/src/DI/ContainerLoader.php(101): _HumbugBox655fe0f4d050\Nette\Configurator->generateCon in phar:///home/gnutix/dev/oss/rector/tmp/rector.phar/vendor/nette/di/src/DI/Config/Loader.php on line 29
Fatal error: Uncaught _HumbugBox655fe0f4d050\Nette\FileNotFoundException: File '/composer/vendor/phpstan/phpstan-symfony/extension.neon' is missing or is not readable. in phar:///home/gnutix/dev/oss/rector/tmp/rector.phar/vendor/nette/di/src/DI/Config/Loader.php:29
Stack trace:
#0 phar:///home/gnutix/dev/oss/rector/tmp/rector.phar/vendor/nette/di/src/DI/Config/Loader.php(43): _HumbugBox655fe0f4d050\Nette\DI\Config\Loader->load('/composer/vendo...', false)
#1 phar:///home/gnutix/dev/oss/rector/tmp/rector.phar/vendor/nette/di/src/DI/Compiler.php(98): _HumbugBox655fe0f4d050\Nette\DI\Config\Loader->load('/home/gnutix/de...', false)
#2 phar:///home/gnutix/dev/oss/rector/tmp/rector.phar/vendor/nette/bootstrap/src/Bootstrap/Configurator.php(186): _HumbugBox655fe0f4d050\Nette\DI\Compiler->loadConfig('/home/gnutix/de...', Object(_HumbugBox655fe0f4d050\Nette\DI\Config\Loader))
#3 phar:///home/gnutix/dev/oss/rector/tmp/rector.phar/vendor/nette/di/src/DI/ContainerLoader.php(101): _HumbugBox655fe0f4d050\Nette\Configurator->generateCon in phar:///home/gnutix/dev/oss/rector/tmp/rector.phar/vendor/nette/di/src/DI/Config/Loader.php on line 29
# phpstan.neon
includes:
    - '/some/file/in/a/docker/volume'
@gnutix
Copy link
Contributor Author

gnutix commented Dec 10, 2019

To avoid that error, I tried running Rector's PHAR from inside a Docker container (PS: here's my previous attempt) using :

# Dockerfile
FROM php:7.4-alpine
RUN wget https://github.com/rectorphp/rector-prefixed/raw/master/rector \
    -O /usr/bin/rector && chmod +x /usr/bin/rector
ENTRYPOINT ["rector"]

And :

docker build -t custom_rector .
docker run --rm -v $(pwd):/project custom_rector:latest process -vvv --ansi \
    --autoload-file /project/vendor/autoload.php --set symfony44 /project/src

It worked (Rector runs - no error regarding phpstan.neon), yet I still get the dreaded :

Rector 0.6.x-dev@9a330e2

[parsing] project/src/Some/Php/File.php
Fatal error: Declaration of PhpParser\Node\Scalar\LNumber::getSubNodeNames() must be
compatible with PhpParser\Node::getSubNodeNames(): array in
/project/vendor/nikic/php-parser/lib/PhpParser/Node/Scalar/LNumber.php on line 30

I thought the intent of building a PHAR version was to prefix Rector's dependencies (like nikic/php-parser) so that it wouldn't clash with the project's autoload ? ... (now I'm not only desperate but confused too 🤔 )

@gnutix gnutix changed the title phpstan.neon (containing extensions loaded within Docker) breaks Rector Running Rector on a PHP 7.2 project Dec 10, 2019
@gnutix gnutix changed the title Running Rector on a PHP 7.2 project [Support] Running Rector on a PHP 7.2 project Dec 10, 2019
@TomasVotruba
Copy link
Member

The PHAR file needs to be tested in the wild first to catch all edge cases we didn't think of.

It seems there are 2 differnt version of php-parser.

  • What php-parser version do you have installed?
  • What phpstan type and version do you use?

@gnutix
Copy link
Contributor Author

gnutix commented Dec 11, 2019

The project is using ocramius/generated-hydrator:2.2(as we're running on PHP 7.2), which depends on nikic/php-parser:~2.0|~3.0. It clashes with the version 4.x included in Rector. PHPStan is installed in a separate Docker container, freshly migrated to 0.12.

@TomasVotruba
Copy link
Member

PHPStan 0.12 needs nikic/php-parser 4 https://packagist.org/packages/phpstan/phpstan

That's the only dependency that needs to be in sync with these tool

@TomasVotruba
Copy link
Member

TomasVotruba commented Dec 11, 2019

Try upgrading hydrator to v3, it should do the job
https://github.com/Ocramius/GeneratedHydrator/blob/3.0.0/composer.json#L23

@gnutix
Copy link
Contributor Author

gnutix commented Dec 11, 2019

v3 requires php: ^7.3... if it were that simple, I would have done it 15 issues ago. ;( So I'm stuck in a CircularReferenceException, basically.

@TomasVotruba
Copy link
Member

Ah, I didn't notice that.

Here are more ideas:

{
    "nikic/php-parser": "4.3 as 3.0"
}

or

composer require rector/rector --ignore-platform-reqs

Also you might ask @Ocramius to go down with PHP 7.2 to allow it.

@gnutix
Copy link
Contributor Author

gnutix commented Dec 11, 2019

Looking at generated-hydrator's 3.0 release notes, I think the whole point was to upgrade nikic/php-parser... so that's pretty surely a no-go.

I'm not sure how to use your tricks in this Docker context, but I'll give it a try.

@TomasVotruba
Copy link
Member

I think the whole point was to upgrade nikic/php-parser... so that's pretty surely a no-go.

php-parser 4.3 allows PHP 7.0, so that's unrelated. It's rather pushing people to upgrade code (which is a good thing), just clashes with your code :/

@TomasVotruba
Copy link
Member

TomasVotruba commented Dec 11, 2019

If I were you, I'd just:

It's 10 minute work and works perfectly for your temporary situation

@Ocramius
Copy link

As mentioned in Ocramius/GeneratedHydrator#114 (comment), forking is the correct workaround if upgrading (endorsed - endorsement conveyed by me bumping dependency version regularly) isn't viable.

I realise it's painful, but making it painful is part of why I do it: it makes companies more aware that newer stuff requires newer environments, and not everything comes for free (as @gnutix already noticed directly)

@gnutix gnutix reopened this Dec 11, 2019
@gnutix
Copy link
Contributor Author

gnutix commented Dec 11, 2019

So I've forked ocramius/generator-hydrated to allow PHP 7.2, which gives me the following dependencies in my project :

nikic/php-parser: v4.3.0
phpstan/phpdoc-parser: 0.3.5
ocramius/generator-hydrated: 3.0.0 (adapted for PHP 7.2)

And rector.phar within a Docker container built with :

# Dockerfile
FROM php:7.4-alpine
RUN wget https://github.com/rectorphp/rector-prefixed/raw/master/rector \
    -O /usr/bin/rector && chmod +x /usr/bin/rector
ENTRYPOINT ["rector"]
$ docker pull php:7.4-alpine && docker build -t custom_rector .
$ docker run --rm -v $(pwd):/app custom_rector process -vvv --ansi --autoload-file /app/vendor/autoload.php --set symfony43 /app/src
Rector 0.6.x-dev@9a330e2

[parsing] app/src/Some/File.php
Fatal error: Uncaught Error: Call to undefined method PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocNode::getImplementsTagValues() in phar:///usr/bin/rector/vendor/phpstan/phpstan-src/src/PhpDoc/PhpDocNodeResolver.php:136
Stack trace:
#0 phar:///usr/bin/rector/vendor/phpstan/phpstan-src/src/PhpDoc/ResolvedPhpDocBlock.php(164): PHPStan\PhpDoc\PhpDocNodeResolver->resolveImplementsTags(Object(PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocNode), Object(PHPStan\Analyser\NameScope))
#1 phar:///usr/bin/rector/vendor/phpstan/phpstan-src/src/Reflection/ClassReflection.php(617): PHPStan\PhpDoc\ResolvedPhpDocBlock->getImplementsTags()
#2 phar:///usr/bin/rector/vendor/phpstan/phpstan-src/src/Reflection/ClassReflection.php(376): PHPStan\Reflection\ClassReflection->getImplementsTags()
#3 phar:///usr/bin/rector/vendor/phpstan/phpstan-src/src/Reflection/Annotations/AnnotationsMethodsClassReflectionExtension.php(48): PHPStan\Reflection\ClassReflection->getInterfaces()
#4 phar:///usr/bin/rector/vendor/phpstan/phpstan-src/src/Reflection/Annotations/Annotat in phar:///usr/bin/rector/vendor/phpstan/phpstan-src/src/PhpDoc/PhpDocNodeResolver.php on line 136

So this is yet another dependency conflict, but on phpstan/phpdoc-parser : we use symplify/easy-coding-standard on a Symfony 4.3 project. But you either get 6.1 which depends on slevomat/coding-standard:^0.3 which requires phpstan/phpdoc-parser:^0.3 (which conflicts with Rector's requirement of phpstan/phpdoc-parser:^0.4), or you get 7.1 which depends on symfony/*: ^4.4.

What were the odds ? 🙄 Guess I'll use ECS in a Docker container too...

@gnutix
Copy link
Contributor Author

gnutix commented Dec 11, 2019

Got it running by using ECS in Docker. Finally!! 🎆

@gnutix gnutix closed this as completed Dec 11, 2019
@gnutix gnutix reopened this Dec 11, 2019
@gnutix
Copy link
Contributor Author

gnutix commented Dec 11, 2019

Ever seen these ones ? Here's the project configuration, running on both src/ and tests/ codebase.

# psr-4
 [ERROR] Could not process "/app/src/Some/Php/File.php" file, 
         due to:                                                                
         "Unable to read file '//composer.json'. failed to open stream: No such 
         file or directory".

I guess this is probably due to the fact that I'm executing Rector from / (inside the container) and composer.json lies in /app/composer.json ? Is there an option like --autoload-file for composer.json ? I might have an idea how to fix that in the future (awaiting some Docker upgrade on our project first).

# symfony-code-quality
 [ERROR] Could not process "/app/tests/unit/Some/TestFile.php" file,  
         due to:                                                                
         "Kernel class "App\Kernel" provided in "parameters > kernel_class" is  
         not instance of                                                        
         "_HumbugBox655fe0f4d050\Symfony\Component\HttpKernel\Kernel". Make sure
         it is.".

This seems related to the new prefixed feature. I tried setting kernel_class: _HumbugBox655fe0f4d050\Symfony\Component\HttpKernel\Kernel but it failed with Cannot instantiate abstract class _HumbugBox655fe0f4d050\Symfony\Component\HttpKernel\Kernel.

# type-declaration
 [ERROR] Could not process "/app/src/Some/Php/File.php"
         file, due to:                                                          
         "Rector\NodeTypeResolver\StaticTypeMapper::mapPHPStanPhpDocTypeNodeToPH
         PStanType for                                                          
         Rector\BetterPhpDocParser\Attributes\Ast\PhpDoc\Type\AttributeAwareGene
         ricTypeNode".

This seems to conflict with PHPStan annotations (like @param class-string[]).

@TomasVotruba
Copy link
Member

TomasVotruba commented Dec 26, 2019

Sorry, there was too many issues at once to focus clearly, so I'm checking it just now.

This seems related to the new prefixed feature. I tried setting kernel_class: _HumbugBox655fe0f4d050\Symfony\Component\HttpKernel\Kernel but it failed with Cannot instantiate abstract class _HumbugBox655fe0f4d050\Symfony\Component\HttpKernel\Kernel

It should have been your app's Kernel, not Rectors. But this process was refactored to container.xml, see #2442


This seems to conflict with PHPStan annotations (like @param class-string[]).

According to error, this format is not implemented yet in mapPHPStanPhpDocTypeNodeToPHPStanType

I'll see what I can do about it

@TomasVotruba
Copy link
Member

"Unable to read file '//composer.json'. failed to open stream: No such
file or directory".

This look like path issue related to Docker. I assume this line won't get out of Docker:

return getcwd() . '/composer.json';

@TomasVotruba
Copy link
Member

This seems to conflict with PHPStan annotations (like @param class-string[]).

I tried to do experimental testing but didn't make it fail.
I need file that is causing it + the responsible set/rule to examine propperly.

If that's still a problem, create new issues so prevent flood of mised problems here. Thank you ❤️

@gnutix
Copy link
Contributor Author

gnutix commented Dec 30, 2019

  1. Using [Symfony] refactor to ServiceMap #2442 fixed the set symfony-code-quality.
  2. I ended up renaming ./phpstan.neon to ./phpstan-main.neon so that Rector doesn't pick it up, thus allowing to point my Docker container to WORKDIR /app and therefore fixed the set psr-4.
  3. Here's a specific issue for the PHPStan annotations related to type-declaration.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants