Appearance
Code quality tools
We are using some tools to monitor our code quality and to enforce follow to our coding standards. All of them are installed to our project (usually as dev dependencies) or available in our Docker container with an idea to make developer’s life easier.
Our CI already has a good setup to run these tools automatically on some events. This document will answer to how and when to run these tools locally.
Use local PHP version to run them faster
If you have PHP installed locally, you can run these tools faster than in Docker. Docker can use only a limited number of your CPU cores, while locally installed PHP can use all of them.
Static analysis
Psalm
Psalm is our main PHP static analyser. Runs on CI on every push if there are any changes in PHP files.
To run it locally (faster), use
sh
composer psalmto run on Docker (pls use aliases):
sh
docker compose exec app composer psalmWhen to run locally: on major changes in PHP files before pushing to the main branch (e.g., method signature changes, new methods, etc.)
Other commands:
composer psalm:baseline:updateto update the baseline file by removing already solved issues.composer psalm:baseline:regenerateto completely regenerate a baseline file. Usually needed when you want to add a lot of suppressions for Psalm’s reports. Please always review changes in the baseline file before committing them.
Psalm supports a lot of docblock annotations that may help analysis a lot:
Advanced
Psalm is configured to send stats on every release to Google Spreadsheets:PHPStan
PHPStan is a static analysis tool very similar to Psalm. Sometimes it can find issues that Psalm cannot find (and vice versa); that’s why we use both of them. Unlike Psalm, CI runs PHPStan only on new PRs and Releases (to minimize price we pay for GitHub actions).
Commands:
composer phpstanto install/update and run.composer phpstan:runto run it.composer phpstan:baseline:regenerateto completely regenerate baseline file. PHPStan doesn’t have an option to remove only solved issues from baseline; this is the only easy way to clean up baseline file from them.
PHPStan automatically uses config stored in the repo.
When to run locally: similar to Psalm: on important API or PHP types changes.
Rector
Rector is a CLI tool written in PHP. It can instantly upgrade old PHP code and handle automated refactorings.
We use it in 2 different cases:
- On CI to automate some code optimisations
- On code migration: e.g., on updating PHP, Laravel or PHPUnit versions
Commands:
composer rectorto run it on our codebase using config stored un the repo. It will automatically optimize codebase. After running this command, you need to run coding style fixers as Rector knows nothing about our coding styles.
When to run locally: on PHP or Laravel upgrades; on mass code changes (e.g. a big PR)
Coding style checks
We use 2 tools to check and fix our coding style. And there is a single command to run them all:
sh
composer cscs stands for coding style.
When to run locally: CI will run it automatically on every push and commit changes to your branch. Thus, run it manually only if you want to avoid extra commits.
Normally, you just need to remember this command, but in this guide we'll describe each tool separately in details.
PHP CS Fixer
It’s less advanced than PHP Code Sniffer but has 2 important benefits:
- it can fix all issues automatically
- it’s a way faster when cache is available
How to run:
sh
composer php-cs-fixerWhen to run locally: almost never: it’s CI’s job to fix coding style issues.
PHP Code Sniffer
We have some code-standard rules/conventions based on PER-CS 2.0 rules. PHP Code Sniffer is a tool that checks our code for code-standard violations - here is a config (which is based on our shared config https://github.com/InteractionDesignFoundation/coding-standard).
Advanced usage
sh
# check all project
phpcs
# check only one file
phpcs app/Models/Billing/Invoice.php
# check directory
phpcs app/Models/Billingoutput example (with error):
text
FILE: /database/migrations/2015_10_08_021947_make_member_id_nullable_on_notifier_logs.php
---------------------------------------------------------------------------------------------------------------
FOUND 1 ERROR AFFECTING 1 LINE
---------------------------------------------------------------------------------------------------------------
6 | ERROR | Each class must be in a namespace of at least one level (a top-level vendor name)
---------------------------------------------------------------------------------------------------------------
Time: 6.34 secs; Memory: 24MbPHP Code Beautifier
Some errors can be fixed automatically by PHP Code Beautifier that ships with PHP Code Sniffer. This tool has almost the same command line options and arguments, but you can simply use it without them:
sh
# fix all files in project
phpcbf
# fix only one file
phpcbf app/Models/Billing/Invoice.php
# fix files in directory
phpcbf app/Models/BillingOfficial documentation: PHP_CodeSniffer wiki
There is a composer command that runs both phpcbf and php-cs-fixer:
sh
composer cs:fixThere are 2 types of issues that PHP Code Sniffer can find:
- automatically fixable
- not automatically fixable
Our CI script will always try to fix issues automatically. If it can’t fix them, it will fail the build.
When to run locally: when CI can’t fix issues automatically.
Deptrac
Deptrac helps keep application architecture clean by dividing it into architectural layers over classes and specifying which rules should apply to them.
Examples:
- forbid using
Requestin aModel; - forbid using Controllers in Console Commands.
How to run:
sh
# install deptrac and run it:
composer deptrac
# or just run if you already downloaded it recently:
composer deptrac:runWhen to run locally: if you are not sure about interlayer changes you made.