AutoLoadOne
AutoLoadOne copied to clipboard
-externalpath and phpstan
Hello,
I feel very honored to be the first person to report something here. :-) I hope it will be of use and interest to you, as it is a tight knot I cannot untangle for me. So let's start:
I have a PHP code where I would like to do some static analysis with phpstan. For this, I did, in some working directory (it doesn't matter where):
composer create-project phpstan/phpstan phpstan
This creates a phpstan directory inside your working directory, with all you need from phpstan. Trying it a bit, I realized that it needs to know the paths to the class files, otherwise it cannot work (of course, since it is a static analyzer, it cannot run the code to execute the include's). This is described in https://github.com/phpstan/phpstan/issues/5276 - so it is a good idea to read that too, so I don't have to repeat it here. My question there was:
Is there some tool that can do this for me (read a file and all its include's recursively, then write the autoloader.php for me)?
Now you see: AutoLoadOne is this tool! :-) Thus I am trying to make it create an autoload.php for me that I can pass to phpstan with its -a option so that it can find my classes. For this I did:
cd /my/project/dir/
php /full/path/to/AutoLoadOne.php -generate -folder . -excludepath '/xxx*,/yyy*,/zzz*' -save yes -savefilename autoload -externalpath relative/path/to/phpstan/vendor
This indeed creates an autoload.php file. But there are problems - that I will discuss in my next post, so stay tuned...
In the above, I forgot: you need a phpstan extension that you can install by:
cd phpstan
You are in the directory that was created by Composer (you see a composer.json file, then you are in the right place). Type:
composer require --dev phpstan/extension-installer
Now, the problems:
First of all some minor issues:
- If you don't pass -save yes, no file is created, contrary to what is suggested in the README of the project (what is displayed on the project's page).
- If you pass -save yes, but no -savefilename option, the file created will have the strange name '.php' - an invisible file in *nix OS. Therefore, you must pass both:
-save yes -savefilename autoload
- I had to check the delimiter used in the explode command for excludepath to see that it is a comma-separated list.
- Still, /xxx is not excluded - or, phrased better: it is excluded, but I get errors complaining about duplicate entries - where I told it to exclude it! It seems that the check for the duplicate entries comes first, and the exclusion comes after it. This is not what people expect, as it creates "red messages" for directories that should actually be excluded:
Error Conflict:Class with name ... -> /xxx/bla/bla is already defined. File ./xxx/bla/bla...
(where '/xxx*' is in -excludepath)
- Specifying
-excludepath '/xxx/,/yyy/,/zzz/'
did not exclude the local directories ./xxx, ./yyy and ./zzz from scanning their classes. I had to use the wildcard * at the end.
These are minor annoyances however. What bothers me is this:
Trying to pass the resulting autoload.php to phpstan with
/full/path/to/phpstan/phpstan analyse --level 0 -a autoload.php relative-path-to-some-php-file-to-check
from inside /my/project/dir/, results in:
In autoload.php line 194:
AutoLoadOne Error: No file found for class [PHPStan\ExtensionInstaller\GeneratedConfig]
but PHPStan\ExtensionInstaller is included in autoload.php, in the xxxxxx__arrautoload array, with a relative path (relative to /my/project/dir/)
'PHPStan\ExtensionInstaller' => '../relative/path/to/phpstan/vendor/phpstan/extension-installer/src'
The only way to make autoload.php load it, is to make $xxxxxx__arrautoload and $autoloadone__debug global:
global $xxxxxx__arrautoload;
global $autoloadone__debug;
which is nowhere mentioned and is something whose logic evades me. And then, when I do this and rerun
/full/path/to/phpstan/phpstan analyse --level 0 -a autoload.php relative-path-to-some-php-file-to-check
the PHPStan\ExtensionInstaller\GeneratedConfig class is obviously found and loaded(!), because now I get:
In Resolver.php line 342:
Service 'php8Lexer' (type of PhpParser\Lexer\Emulative): AutoLoadOne Error: No file found for class [mixed]
In autoload.php line 193:
AutoLoadOne Error: No file found for class [mixed]
which is too much for me. Can you help? Why can't autoload.php find php8Lexer? Is it because (as far as I can see) php8Lexer is inside phpstan's PHAR and the whole phpstan code is actually "hidden" inside the phpstan.phar file (which, possibly, cannot be traversed or handled by AutoLoadOne)???
:-| ok, let's me check this out.
Any progress on this?
Sorry, but I didn't have time to check it. :-P
First, I decided to update to PHP 8.1 and drop the support of any version of PHP lower than PHP 7.1.5 Second, I decided to move to a better CLI interface and to fix the problems. Third, I decided to drop the web interface. This tool is aimed at CLI only.
ps: I also blame the pandemic 😷