Closed reypm closed 2 years ago
As discussed in Slack, the basic psalm command runs fine without arguments. The error happens when running the command through composer with find ../* -prune -type d | while IFS= read -r DIR; do echo '>> ' ${DIR}; ./vendor/bin/psalm ${DIR}; done
I believe this may be related to https://github.com/vimeo/psalm/pull/7210
Yes it could be related to #7210. I assume ../framework
is some shell script which calls psalm? Does this shell script call psalm in a different way than the composer script does?
If it is called the same way as in the composer script it shouldn't have worked before as well (there's multiple paths and it's not .
or ./
so it would have ignored the projectFiles
).
The rule is basically: if you supply any paths/files via the command line the projectFiles
definition in the psalm.xml (including the ignoreFiles
) is not applied.
I assume ../framework is some shell script which calls psalm
I was told it's just the path. The command is the one in the composer command
The rule is basically: if you supply any paths/files via the command line the projectFiles definition in the psalm.xml (including the ignoreFiles) is not applied.
Oh right, I forgot that.
@reypm what is the goal to have the path in argument in your composer script?
Ah now I get it yes, it's the output from the composer script, and I didn't read it correctly - it calls psalm multiple times but with just one argument. So now that I'm not confused anymore I can say for sure that it's because of #7210.
The "../framework" is the .
and was filtered out before 4.17 so the projectFiles
of the psalm.xml
was applied for this case so that's why it worked before (for the framework directory at least, it would have still scanned the vendors in the other "sibling" directories).
So yes as @orklah said, it's best to run psalm without any arguments so the composer script would just be
"psalm": "./vendor/bin/psalm"
Now if you have vendor
directories in other sibling directories than just ../framework
I would suggest to use this glob:
<directory name="../*/vendor"/>
This would exclude all sibling vendor directories, because the glob *vendor just excludes the vendor directory in ../framework
, since the paths in projectFiles are alway relative to the path where the psalm.xml is.
@orklah, @vstm the idea with the command and the path is to move into different directories. See for example the following project structure:
my-app/
├─ .git/
├─ Dockerfiles/
├─ Folder1/
├─ framework/
│ ├─ config/
│ ├─ features/
│ ├─ src/
│ ├─ var/
│ ├─ vendor/
├─ Folder 2/
├─ .gitignore
├─ README.md
First of all, I will start saying psalm
is living inside framework/vendor/bin
. I would like to scan the following dirs: Folder1
, framework/src
, Folder2
and the only way I have found to do so is through that script line and adding the path to the psalm
command.
If I run just psalm
it will scan|avoid only what is inside framework
and will skip everything else, I have tried this and yes, psalm works fine if no path is supplied while running the command.
Can any of you think in a different way to achieve this? 🤔
Thank you for the explanation. It should be possible to do this with just the psalm.xml config. The question is where is your psalm.xml located in the project structure, is it also in the framework folder?
All the paths in the projectFiles are relative to the psalm.xml, so that's why it's important where it is located.
So if your psalm.xml is in the framework directory it actually should work like you would expect. I tried to replicate your structure and psalm scans also in the other directories (I have included the exact xml config in the output):
➜ framework ./vendor/bin/psalm --version
Psalm 4.18.0.0
➜ framework ./vendor/bin/psalm
Target PHP version: 7.4 (inferred from current PHP version)
Scanning files...
Analyzing files...
ERROR: UndefinedGlobalVariable - ../Folder1/Fail.php:1:6 - Cannot find referenced variable $fail in global scope (see https://psalm.dev/127)
?php $fail->fail();
ERROR: UndefinedGlobalVariable - ../Folder2/Fail.php:1:6 - Cannot find referenced variable $fail in global scope (see https://psalm.dev/127)
?php $fail->fail();
ERROR: UndefinedGlobalVariable - src/Fail.php:1:6 - Cannot find referenced variable $fail in global scope (see https://psalm.dev/127)
?php $fail->fail();
------------------------------
3 errors found
------------------------------
3 other issues found.
You can display them with --show-info=true
------------------------------
Checks took 0.01 seconds and used 4.939MB of memory
No files analyzed
Psalm was able to infer types for 0.0000% of the codebase
➜ framework cat psalm.xml
<?xml version="1.0"?>
<psalm xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" errorLevel="7" totallyTyped="true"
strictBinaryOperands="true" useDocblockPropertyTypes="true"
xmlns="https://getpsalm.org/schema/config"
xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd">
<projectFiles>
<directory name=".." />
<ignoreFiles>
<directory name="../.git" />
<directory name="../Dockerfiles" />
<directory name="vendor" />
<directory name="features" />
<directory name="var" />
</ignoreFiles>
</projectFiles>
</psalm>
➜ framework tree -L 3 ../../my-app
../../my-app
├── Dockerfiles
├── Folder1
│ └── Fail.php
├── Folder2
│ └── Fail.php
├── framework
│ ├── composer.json
│ ├── composer.lock
│ ├── config
│ ├── features
│ │ └── Fail.php
│ ├── psalm.xml
│ ├── src
│ │ └── Fail.php
│ ├── var
│ │ └── Fail.php
│ └── vendor
│ ├── ... omitted
└── psalm.xml
@vstm thank you a lot, gonna give this a try and will see if it works then if everything is fine will close this issue.
@vstm in my case seems not to be working ... :( I have exactly what you have and psalm seems to be scanning only what is inside framework
but not outside of that directory:
root@3ff6e051f8c6:/var/www/framework# composer psalm
> ./vendor/bin/psalm
Target PHP version: 8.1 (inferred from composer.json)
Scanning files...
Analyzing files...
------------------------------
No errors found!
------------------------------
65 other issues found.
You can display them with --show-info=true
------------------------------
Checks took 0.01 seconds and used 12.380MB of memory
No files analyzed
Psalm was able to infer types for 90.8057% of the codebase
any ideas in what could be wrong here?
Oh, at the moment I have no idea. It seems that it doesn't even scan the framework folder now (It says "No files analyzed
" in the output). Can you do a cat /var/www/framework/psalm.xml
and give me the output so I can see how your psalm.xml looks now?
@vstm here it is ...
<?xml version="1.0"?>
<psalm xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" errorLevel="7" totallyTyped="true"
strictBinaryOperands="true" useDocblockPropertyTypes="true"
xmlns="https://getpsalm.org/schema/config"
xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd">
<projectFiles>
<directory name=".."/>
<ignoreFiles>
<directory name="vendor"/>
<directory name="var"/>
<directory name="features"/>
<file name="phpinsights.php"/>
<file name="rector.php"/>
</ignoreFiles>
</projectFiles>
<plugins>
<pluginClass class="Psalm\SymfonyPsalmPlugin\Plugin">
<containerXml>var/cache/dev/App_KernelDevDebugContainer.xml</containerXml>
</pluginClass>
<pluginClass class="Weirdan\DoctrinePsalmPlugin\Plugin"/>
</plugins>
<issueHandlers>
<MethodSignatureMismatch errorLevel="suppress"/>
<UndefinedDocblockClass errorLevel="suppress"/>
<MissingFile errorLevel="suppress"/>
<UndefinedClass errorLevel="suppress"/>
<PluginIssue name="RepositoryStringShortcut" errorLevel="suppress" />
</issueHandlers>
</psalm>
I executed it one more time and now seems to be working 🤔 I haven't made any other changes and/or updates. However I am not sure what directory is Psalm scanning or files, any way to know those?
# composer psalm
> ./vendor/bin/psalm
Target PHP version: 8.1 (inferred from composer.json)
Scanning files...
Analyzing files...
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 60 / 82 (73%)
░░░░░░░░░░░░░░░░░░░░░░
------------------------------
No errors found!
------------------------------
65 other issues found.
You can display them with --show-info=true
------------------------------
Psalm can automatically fix 6 of these issues.
Run Psalm again with
--alter --issues=InvalidNullableReturnType,InvalidFalsableReturnType,MissingParamType --dry-run
to see what it can fix.
------------------------------
Checks took 5.08 seconds and used 237.624MB of memory
Psalm was able to infer types for 90.8057% of the codebase
Hmm maybe it was a cache-issue. To find out if it actually works you can run psalm with --debug
or add an intentional issue. What I did is to just create a PHP file with the following content:
<?php $fail->fail();
Psalm should find at least one issue with that.
Otherwise you can use the --debug
flag and maybe grep for the files psalm analyzes:
$ composer psalm -- --no-cache --debug 2>&1 | grep Analyzing
Is working fine now, using that last debug line I am able to see the files being analyzed. Thank you a lot both of you @vstm @orklah
Thanks @vstm !
I have upgraded my Psalm to the latest 4.18 and now it scans the
vendor
directory when it should not as per thepsalm.xml
(see below) file configuration.Issues found:
The error reads as below:
Below is some helpful information to try to fix this in the case is a bug:
PHP Information:
psalm.xml
composer.json