Tests / Build Scripts: Configure PHPStan levels 1-6 [Exploratory]#7619
Tests / Build Scripts: Configure PHPStan levels 1-6 [Exploratory]#7619justlevine wants to merge 122 commits intoWordPress:trunkfrom
Conversation
|
Hi @justlevine! 👋 Thank you for your contribution to WordPress! 💖 It looks like this is your first pull request to No one monitors this repository for new pull requests. Pull requests must be attached to a Trac ticket to be considered for inclusion in WordPress Core. To attach a pull request to a Trac ticket, please include the ticket's full URL in your pull request description. Pull requests are never merged on GitHub. The WordPress codebase continues to be managed through the SVN repository that this GitHub repository mirrors. Please feel free to open pull requests to work on any contribution you are making. More information about how GitHub pull requests can be used to contribute to WordPress can be found in the Core Handbook. Please include automated tests. Including tests in your pull request is one way to help your patch be considered faster. To learn about WordPress' test suites, visit the Automated Testing page in the handbook. If you have not had a chance, please review the Contribute with Code page in the WordPress Core Handbook. The Developer Hub also documents the various coding standards that are followed:
Thank you, |
|
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the Core Committers: Use this line as a base for the props when committing in SVN: To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
Test using WordPress PlaygroundThe changes in this pull request can previewed and tested using a WordPress Playground instance. WordPress Playground is an experimental project that creates a full WordPress instance entirely within the browser. Some things to be aware of
For more details about these limitations and more, check out the Limitations page in the WordPress Playground documentation. |
94cf5e4 to
3ed2a8f
Compare
3ed2a8f to
1aae38c
Compare
1aae38c to
a3005aa
Compare
34897c4 to
e8d563b
Compare
Co-authored-by: Weston Ruter <westonruter@gmail.com>
…into tests/phpstan/level-0
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
…vor of local baseline
Co-authored-by: Jonathan Desrosiers <359867+desrosj@users.noreply.github.com>
Co-authored-by: John Blackbourn <johnbillion@git.wordpress.org>
Co-authored-by: John Blackbourn <john@johnblackbourn.com>
Co-authored-by: John Blackbourn <john@johnblackbourn.com>
|
Re-opening because only level 0 was committed. |
| - tests/phpstan/baseline/level-2.php | ||
| - tests/phpstan/baseline/level-3.php | ||
| - tests/phpstan/baseline/level-4.php | ||
| - tests/phpstan/baseline/level-5.php |
There was a problem hiding this comment.
@justlevine How were these generated? It seems level-2.php omits the errors from level 1? And level-3.php omits the errors from level 2, and so on? When I run composer phpstan -- --level=3 --generate-baseline=tests/phpstan/baseline/level-3.php it includes errors from levels 1-3.
There was a problem hiding this comment.
Yeah you need to do it level by level. I've been doing it manually but hold on ai should be able to bash it for us.
There was a problem hiding this comment.
We should make a script that does that for us and register it as a new composer command. That will be super useful going forward.
There was a problem hiding this comment.
written by zai-coding-plan/glm-5, reviewed by openai/gpt-5.2-codex (both in opencode), tested by github-copilot/gpt-5-mini (Vscode)
"lightly reviewed" (aka skimmed for nothing crazy) by myself, and manually tested in wsl2 ubuntu24.04
Keep in mind that it iterates levels, so doing npm run test/phpstan/generate-baselines.sh --all will take a few minutes, since there's no caches. More in the update doc. NOT MEANT FOR CORE MERGE just a fun tool
There was a problem hiding this comment.
We should have something merged into core for for future reuse.
Also, I think writing it in PHP would be more compatible across systems when it is used.
| bash tests/phpstan/generate-baselines.sh --summary-only # to only output the summary of results for the existing baselines, without regenerating them. | ||
|
|
||
| ``` | ||
| To change the max level, update the `MAX_LEVEL` variable at the top of the script, alongside any changes to the root `phpstan.neon.dist` file to add the new level. |
There was a problem hiding this comment.
Couldn't the MAX_LEVEL be read from the PHPStan config?
There was a problem hiding this comment.
Yup, cool idea. feel free to throw some tokens at it if you want or maybe i will next time
| ## Triage - using `generate-baselines.sh` | ||
|
|
||
| > [!IMPORTANT] | ||
| > This tool is internal to the branch and is not intended for wordpress-core. Use at your own discretion. |
There was a problem hiding this comment.
What does this mean? Internal to the branch? How is this not for core?
There was a problem hiding this comment.
Core only has a baseline.php. This whole level-by-level triage is specific to these exploration/remediation branches to make it easier to see the impacts of each level and triage.
There was a problem hiding this comment.
IOW once PHPStan level 1 is enforced by core, it doesnt matter if a new error we want to baseline is level 1 or level 0, it's just core "Tech debt" that we're baselining.
There was a problem hiding this comment.
I was thinking we'd commit those baselines to core, even up to level 8. Then contributors who want to work on level 8 can do so via their local phpstan.neon. Maybe that doesn't make sense.
But let's say we do bump to level 6 now, it would be great to have level-specific baselines to help us as we start to fix the issues incrementally until we reach a point where there are no errors left in a level-specific baseline.
There was a problem hiding this comment.
But let's say we do bump to level 6 now,
in that case sure, though I'd recommend a real review of the script first. I feel the likelihood of that getting approved is very low though.
There was a problem hiding this comment.
Getting what approved? Level 6? I don't think it will be difficult to do that, if we have the baseline. It means new code will begin to have level 6 issues reported, and we can start fixing the issues and removing them from the baseline(s) concurrently.
There was a problem hiding this comment.
I hope you're right, but I'd assume there's some chicken-egg work at foot based on the discussions and feedback from folks before merge.
Commiters (assumedly) want to know the impact of the particular level/ruleset before we enforce the requirements on new code. And there's also the level-specific prepwork that needs to be done so that every new PR isn't generating "noise" (more of the same error types that need to be baselined).
So yeah I do assume for new-enforcement on new code we'll need to bump level by level, so we can point and say e.g. "these are the new violations that are getting checked, these are (currently) ignored etc" and that the codebase is in a place where we can enforce it and those baselines remain stable.
we can start fixing the issues and removing them from the baseline(s) concurrently.
So this was the scenario I was originally trying to address in my reply. Levels are just shorthand convenience groupings for getting things into a codebase. Once inside the codebase tho, it doesn't matter for remediation if the violation is from a level 1 rule or a level 9, its tech debt that needs to be remediated, so having to maintain multiple lists that nerd to be non-natively generated feels like undesired friction for core.
I do see value in tools like https://github.com/staabm/phpstan-baseline-analysis to help us pull out and do rule-based triage of the baselines, but that too doesn't seem like something that should be merged into core.
(maybe I have the wrong POV: but I see a difference between committing an evergreen tool/flow versus one thats only a comparative short term triage tool. Like I wouldn't commit a script that e.g. generates all the PHPUnit tests that aren't compatible with v11.5+, or one that generates a report of any non php8.0 compatible code, since one those triage tasks are done the script no longer has value)
Trac ticket: https://core.trac.wordpress.org/ticket/61175
This PR adds a PHPStan configuration along with error baselines through Level 6.
The hope is the limited scope will make this easier to review/merge, with actual code remediations occuring in future (or even parallel) PRs.
Usage
Run PHPStan
Create a local
phpstan.neonfor remediating errorsphpstan.neon.disttophpstan.neon.parameters.levelto the desired level, and filter out the errors by adding them to theparameters.ignoreErrorslist.composer run analyse.Remediating errors using the error baselines
While
parameters.ignoreErrorsis used to filter out "unsupported" errors, error baselines are used to suppress preexisting tech debt.This allows for the PR to be merged as is to enforce the rules on new code, while allowing contributors to remediate the existing errors at their own pace. This is in the spirit of 'Avoid unnecessary refactoring'.
To remediate a baselined error, remove the error from the
tests/phpstan/baseline/level-{%N}file and run PHPStan again.Triaging errors and regenerating baselines
If an error is found to be a false positive (or otherwise not worth fixing), it should be added to the
parameters.ignoreErrorslist in thephpstan.neon.distfile. When this happens, the baseline file suppressing the error will cause PHPStan to fail.To avoid manual remediation, the baseline files can be regenerated by following the following steps:
Identify the baseline level that contains the error. (Search for the error in
tests/phpstan/baseline).Change the
parameters.levelinphpstan.neonto the level identified in step 1.Comment out the
includesfor that level and all levels above it.Run the following command:
# Replace {%N} with the level identified in step 1 vendor/bin/phpstan analyse --generate-baseline tests/phpstan/baseline/level-{%N}.phpPrior Art
This is based off the work done in #853 with some notable differences:
Latest
trunkand PHPStan (1.12.7) - as of writing.No changes to WordPress core codebase.
This is to limit the scope of the PR and hopefuly prevent it from going stale.
The
phpstan.neon.distfile wraps thetests/phpstan/base.neonconfig that holds the codebase configuration (what to scan/skip, etc), with the top-level file holding the "rules".This makes it easier for contributors to remediate errors by creating a local
phpstan.neonfile.Removed many of the
parameters.ignoreErrorsin favor of error baselines (one per each PHPStan level).See
Remediating errors using the error baselinessection above.The
tests/phpstan/bootstrap.phpfile has been reorganized to mirror the order that the constants are defined in the WP lifecycle.This will hopefully make it easier to maintain in the future.
Added inline annotations to the various configs.
Additional Notes
ignoreErrors) - Level 9+ is primarily aboutmixedtypes - that can be handled incrementally in a future PR that contains the necessary code remediations.Next Steps
ignoreErrors.AI Disclosure
tests/phpstan/generate-baseline.shwas generated and reviewed as described here. It is a tool for generating these level-by-level baselines, and not meant for core.This Pull Request is for code review only. Please keep all other discussion in the Trac ticket. Do not merge this Pull Request. See GitHub Pull Requests for Code Review in the Core Handbook for more details.