Enable phpstan - #1336
Conversation
d7415
left a comment
There was a problem hiding this comment.
Looks good to me at a glance. I'd be tempted to leave it enabled so that we see any progress, but I can see how that would look ugly in PRs, especially for externals who aren't expecting red icons!
There was a problem hiding this comment.
Il agree, but I would enable it in CI, even for PRs. I mean, we should mention in the docs that you should run the .make phpstan before submitting the PR, then the contributors can make sure that the code looks good, or we can provide simple help with suggestions or fix issues ourselves
The problem with this is that until it looks good for Lychee itself, a lot of that will show up for the person doing the PR. unless phpstan can accept a diff somehow. |
|
When I approved this, tests were passing ;) |
|
You're right. We need to fix all the issues phpstan reports, then we can enable it. |
what do you think I am working on ? 😆 I can already tell that @nagmat84 is going to hate me for the conflicts. :') |
|
I don't know enough about PhpStan, but I would assume that you can enable/disable/configure individual checks. I haven't had a look at the PR yet, I am only following the discussion. But before you start and take the effort to change a lot of files, we should maybe review the rule set and discuss which rules we want and which not? (Unless PhpStan does not allow configuration.) |
|
Yeah, looks like you can disable checks, files or checks in certain files. @ildyria's already done some of that. |
Yeah I didn't feel like changing some of the files. :) |
|
See first post. |
|
I am considering nuking the |
|
I replaced all, but one Overall, I believe it was worth the effort, because I actually discovered some bugs. For example, when we convert an EXIF date to a I left one $extension = pathinfo($filename, PATHINFO_EXTENSION);
// Special cases
// https://github.com/electerious/Lychee/issues/482
list($extension) = explode(':', $extension, 2);
if (!empty($extension)) {
$extension = '.' . $extension;
}
return $extension;This code is too wicked for me. The problem is not the |
Given the comment, I am pretty sure I didn't touch that code and it is from Electerious (another fellow german BTW). |
Yes, it is. It also refers to an issue from Electerious which is now a dead link. Luckily, this method is gone after we have merged my PR for file streams. So this is only a temporary problem. |
Co-authored-by: qwerty287 <80460567+qwerty287@users.noreply.github.com>
|
Unless I am wrong, this should finally be ready for merge. 😅 |
|
I am not entirely sure with 100% certainty, because I have lost track of all the remarks which I have written and whether all of them have actually been addressed. However, I am fine with merging it now and if anything pops up, we have to deal with it in a follow-up PR. PS: IMHO, Github is really bad at handling big PRs with a long history of comments. A clever strategy would fold all comments with resolved discussion and keep the unresolved discussion unfolded. But Github only seems to apply a static pattern. This means, show the first n comments, hide the next n comments, show n comments again, etc., irrespective of whether those comments are all resolved or still contain an unresolved remark. :-( |
nagmat84
left a comment
There was a problem hiding this comment.
Approval out of despair 😀 See #1336 (comment)
Yeah, the number of times I needed to click to get to the "New changes since you last viewed" link just now was mind-boggling... |
kamil4
left a comment
There was a problem hiding this comment.
I left a few non-critical comments.
I feel that given the size of this PR, we should each test it on our devel instances before it gets merged. Has any of you done it? I did not (because I would prefer to wait until we are satisfied with it).
| if (empty($photo->iso) && !empty($info->iso)) { | ||
| if ( | ||
| ($photo->iso === null || $photo->iso === '') && | ||
| $info->iso !== null && | ||
| $info->iso !== '' | ||
| ) { |
There was a problem hiding this comment.
Places like this make me wonder if we really need to test for both null and empty string everywhere, but I realize that it may not be worth it to figure it out in every single spot...
There was a problem hiding this comment.
I am convinced that a comparison for null should suffice, because we convert all empty strings to null anyway in the middleware. But I deliberately did it this way, because I thought that someone might ask the exact opposite question if I had done it the other way around.
Co-authored-by: Kamil Iskra <kamil.01482@iskra.name>
Just to be nice...
In order to run it just do:
make phpstan(and cry)The rules so far are:
return types, types assigned to properties
Also the following:
https://github.com/phpstan/phpstan-strict-rules
if,elseif, ternary operator, after!, and on both sides of&&and||.+and numeric operands in-/*///**/%.$var++,$var--,++$varand--$var.$strictparameter for better type safety, it must be set totrue:in_array(3rd parameter)array_search(3rd parameter)array_keys(3rd parameter; only if the 2nd parameter$search_valueis provided)base64_decode(2nd parameter)whileloop condition andforloop initial assignment cannot be used after the loop.switchcondition andcasevalue must match. PHP compares them loosely by default and that can lead to unexpected results.Disallowempty()- it's a very loose comparison (see manual), it's recommended to use more strict one.Disallow short ternary operator (?:) - implies weak comparison, it's recommended to use null coalesce operator (??) or ternary operator with strict condition.$$foo,$this->$method()etc.)instanceof, type-checkingis_*functions and strict comparisons===/!==. These checks can be turned off by settingcheckAlwaysTrueInstanceof/checkAlwaysTrueCheckTypeFunctionCall/checkAlwaysTrueStrictComparisonto false.Contravariance for parameter types and covariance for return types in inherited methods (also known as Liskov substitution principle - LSP)$ls = `ls -la`)$thisdirectly instead of using$thisvariable indirectlyFruthermore:
\Safe\functions when available.