Skip to content

[Scoper] Remove Doctrine\Inflector\Inflector from exclude class#582

Merged
TomasVotruba merged 2 commits intomainfrom
move-doctrine-inflector-exclude
Aug 3, 2021
Merged

[Scoper] Remove Doctrine\Inflector\Inflector from exclude class#582
TomasVotruba merged 2 commits intomainfrom
move-doctrine-inflector-exclude

Conversation

@samsonasik
Copy link
Copy Markdown
Member

@samsonasik samsonasik commented Aug 3, 2021

Fixes rectorphp/rector#6607

to avoid error:

[ERROR] Could not process "app/Models/User.php" file, due to:                                                          
         "RectorPrefix20210802\Doctrine\Inflector\Inflector::__construct(): Argument #1 ($singularizer) must be of type 
         RectorPrefix20210802\Doctrine\Inflector\WordInflector, Doctrine\Inflector\CachedWordInflector given, called in 
         vendor/laravel/framework/src/Illuminate/Support/Pluralizer.php:140". On line: 28      

@samsonasik
Copy link
Copy Markdown
Member Author

/cc @soilSpoon this is to fix the doctrine inflector issue on rectorphp/rector#6607 beside the autoload definition that I send to your repo soilSpoon/example-app#2

@samsonasik
Copy link
Copy Markdown
Member Author

All checks have passed 🎉 @TomasVotruba it is ready for review.

@TomasVotruba
Copy link
Copy Markdown
Member

I think this would make Inflector part of public API which is not our intention. doctrine/inflector is quite commonly used package, so we should avoid conflicting it.

Reproducible repository is needed in this case.

@samsonasik
Copy link
Copy Markdown
Member Author

@TomasVotruba the reproducible repository is on @soilSpoon's https://github.com/soilSpoon/example-app for app path.

@soilSpoon other solution is by manually add more require-dev :

composer require --dev doctrine/inflector

after use of custom bootstrap at PR soilSpoon/example-app#2

@TomasVotruba
Copy link
Copy Markdown
Member

TomasVotruba commented Aug 3, 2021

Thanks 👍

What is the command being run to see the error? This works for me:

composer install
vendor/bin/rector p -n --clear-cache

@samsonasik
Copy link
Copy Markdown
Member Author

On PR soilSpoon/example-app#2 , I set the paths to app/Providers to make rector works, which original issue is on path app. If changed to:

-    $parameters->set(Option::PATHS, [__DIR__ . '/app/Providers']);
+    $parameters->set(Option::PATHS, [__DIR__ . '/app']);

it will got error:

vendor/bin/rector p -n --clear-cache
 19/19 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%
1 file with changes
===================

1) app/Models/User.php

    ---------- begin diff ----------
@@ @@
-<?php
-
-namespace App\Models;
-
-use Illuminate\Contracts\Auth\MustVerifyEmail;
-use Illuminate\Database\Eloquent\Factories\HasFactory;
-use Illuminate\Database\Eloquent\Relations\HasMany;
-use Illuminate\Foundation\Auth\User as Authenticatable;
-use Illuminate\Notifications\Notifiable;
-
-class User extends Authenticatable
-{
-    use HasFactory;
-    use Notifiable;
-    /**
-     * The attributes that are mass assignable.
-     *
-     * @var array
-     */
-    protected $fillable = [
-        'name',
-        'email',
-        'password',
-    ];
-
-    /**
-     * The attributes that should be hidden for arrays.
-     *
-     * @var array
-     */
-    protected $hidden = [
-        'password',
-        'remember_token',
-    ];
-
-    /**
-     * The attributes that should be cast to native types.
-     *
-     * @var array
-     */
-    protected $casts = [
-        'email_verified_at' => 'datetime',
-    ];
-
-    public function user(): HasMany
-    {
-        return $this->hasMany(Post::class);
-    }
-
-    public function getPosts()
-    {
-        return $this->name === 'foo' ? Post::all() : collect();
-    }
-}
    ----------- end diff -----------

                                                                                                                        
 [ERROR] Could not process "app/Models/User.php" file, due to:                                                          
         "RectorPrefix20210802\Doctrine\Inflector\Inflector::__construct(): Argument #1 ($singularizer) must be of type 
         RectorPrefix20210802\Doctrine\Inflector\WordInflector, Doctrine\Inflector\CachedWordInflector given, called in 
         vendor/laravel/framework/src/Illuminate/Support/Pluralizer.php:140". On line: 28      

@samsonasik
Copy link
Copy Markdown
Member Author

Adding:

composer require --dev doctrine/inflector

seems still not the solution, it still got error:

 [ERROR] Could not process "app/Models/User.php" file, due to:                                                          
         "RectorPrefix20210802\Doctrine\Inflector\Inflector::__construct(): Argument #1 ($singularizer) must be of type 
         RectorPrefix20210802\Doctrine\Inflector\WordInflector, Doctrine\Inflector\CachedWordInflector given, called in 
         vendor/laravel/framework/src/Illuminate/Support/Pluralizer.php:140". On line: 28   

which looking for non-existent RectorPrefix20210802\Doctrine\Inflector\WordInflector

@TomasVotruba
Copy link
Copy Markdown
Member

Good, this command breaks 👍 Thanks

vendor/bin/rector p app/Models/User.php -n --clear-cache --debug

@samsonasik
Copy link
Copy Markdown
Member Author

is it merge-able then? or need to add :

'Doctrine\Inflector\WordInflector'

to EXCLUDED_CLASSES constant value?

@TomasVotruba
Copy link
Copy Markdown
Member

I'm looking at it an it seems the Laravel loads Doctrine/Inflector first in /var/www/example-app/vendor/laravel/framework/src/Illuminate/Support/Pluralizer.php

Then Rector gets the same class and crashes. Rector needs the prefixed version.

I think it might help to add /vendor/doctrine/inflector to preload.php - https://github.com/rectorphp/rector/blob/main/preload.php
We solved similar conflicts with php-parser, when project had own php-parser but Rector needed its own version.

Could you verify?

@samsonasik
Copy link
Copy Markdown
Member Author

Add to vendor/doctrine/inflector to preload.php seems still error:

Screen Shot 2021-08-03 at 19 28 31

@samsonasik
Copy link
Copy Markdown
Member Author

samsonasik commented Aug 3, 2021

Add only Doctrine\Inflector\WordInflector and Doctrine\Inflector\Inflector seems make different error:

➜  example-app git:(bar) vendor/bin/rector p app/Models/User.php -n --clear-cache --debug                            
[parsing] app/Models/User.php
PHP Fatal error:  Declaration of Doctrine\Inflector\CachedWordInflector::inflect(string $word): string must be compatible with RectorPrefix20210803\Doctrine\Inflector\WordInflector::inflect($word): string in /Users/samsonasik/www/example-app/vendor/doctrine/inflector/lib/Doctrine/Inflector/CachedWordInflector.php on line 20

   Symfony\Component\ErrorHandler\Error\FatalError 

  Declaration of Doctrine\Inflector\CachedWordInflector::inflect(string $word): string must be compatible with RectorPrefix20210803\Doctrine\Inflector\WordInflector::inflect($word): string

  at vendor/doctrine/inflector/lib/Doctrine/Inflector/CachedWordInflector.php:20
     16▕     {
     17▕         $this->wordInflector = $wordInflector;
     18▕     }
     19▕ 
  ➜  20▕     public function inflect(string $word) : string
     21▕     {
     22▕         return $this->cache[$word] ?? $this->cache[$word] = $this->wordInflector->inflect($word);
     23▕     }
     24▕ }


   Whoops\Exception\ErrorException 

  Declaration of Doctrine\Inflector\CachedWordInflector::inflect(string $word): string must be compatible with RectorPrefix20210803\Doctrine\Inflector\WordInflector::inflect($word): string

  at vendor/doctrine/inflector/lib/Doctrine/Inflector/CachedWordInflector.php:20
     16▕     {
     17▕         $this->wordInflector = $wordInflector;
     18▕     }
     19▕ 
  ➜  20▕     public function inflect(string $word) : string
     21▕     {
     22▕         return $this->cache[$word] ?? $this->cache[$word] = $this->wordInflector->inflect($word);
     23▕     }
     24▕ }

      +1 vendor frames 
  2   [internal]:0
      Whoops\Run::handleShutdown()

@samsonasik
Copy link
Copy Markdown
Member Author

Remove completely Doctrine\Inflector from the exclude seems fixed it 🎉

Screen Shot 2021-08-03 at 23 49 15

Step to reproduce:

  • run sh ./full_build.sh
  • remove the example-app vendor/rector/rector/* content except preload.php and bootstrap.php
  • copy the content of prefixed to the example-app vendor/rector/rector
  • run:
vendor/bin/rector p app/Models/User.php -n --clear-cache --debug

@samsonasik
Copy link
Copy Markdown
Member Author

All checks have passed 🎉 @TomasVotruba let's give it a try?

@samsonasik samsonasik changed the title [Scoper] Move Doctrine\Inflector\* to Excluded Namespace [Scoper] Remove Doctrine\Inflector\Inflector from exclude class Aug 3, 2021
@TomasVotruba
Copy link
Copy Markdown
Member

Thank you! It makes sense, and the bug also. When we scope only some classes from one namespace, the rest can be autoloaded with priority by the project itself.

Let's ship it 👍

@TomasVotruba TomasVotruba merged commit aff0c5d into main Aug 3, 2021
@TomasVotruba TomasVotruba deleted the move-doctrine-inflector-exclude branch August 3, 2021 17:10
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

Successfully merging this pull request may close these issues.

Rector processing errors in laravel.

2 participants