When you run JSHint, the only thing you need to put on the command line is: jshint
. No additional arguments are required to check JS files under the current directory, and it automatically looks for a .jshintrc
file for its configuration. For years now when I’ve wanted to similarly run PHP_CodeSniffer to check the adherence of some PHP code against coding standards, I’ve been running phpcs
via:
phpcs --standard=phpcs.ruleset.xml -s --extensions=php .
There are here four additional arguments compared to what JSHint requires. The -s
arg makes PHPCS show sniff codes in all reports (e.g. Squiz.Commenting.FileComment.SpacingAfterComment
), something that is very helpful for figuring out which sniff is specifically being violated (so that it can potentially be excluded/suppressed in the project’s ruleset). The phpcs.ruleset.xml file here includes the WordPress-Core standard among other rules and configuration for the project. This file was named as such because originally PHP_CodeSniffer’s naming for ruleset files was an ambiguous “ruleset.xml
”, and so it was first named in wp-dev-lib with the “phpcs.
” prefix to make the filename more specific. The file was also then added to the plugin scaffolding command in WP-CLI. But recently Gary Jones pointed out:
what’s the reason for the naming as
phpcs.ruleset.xml
, instead ofphpcs.xml.dist
, as per the exact file in PHPCS, and in the documentation?
It turns out that in v2.2 PHP_CodeSniffer renamed the default ruleset file from ruleset.xml
to phpcs.xml
, and then in v2.5 it also added support for a phpcs.xml.dist
fallback ruleset file, which aligns with PHPUnit’s default configuration files phpunit.xml
and phpunit.xml.dist
.
With the use of this PHPCS-recognized default ruleset file, this simplifies the above phpcs
command down to:
phpcs -s --extensions=php .
Note that PhpStorm does not yet support auto-discovery of the phpcs.xml[.dist]
files like it can for .eslintrc
for ESLint or .jshintrc
for JSHint. I’ve filed an issue to implement support for it. Once this lands in PhpStorm, it will greatly improve the experience of using the PHP_CodeSniffer inspection in the IDE when the opened project consists of an entire WordPress install with multiple themes and plugins each of which may have different PHPCS rulesets.
But wait, there’s more!
A couple days ago I was reviewing a pull request on Gutenberg which also sought to make it easier to invoke PHP_CodeSniffer on the project. We discovered that PHP_CodeSniffer allows you to define default command line args in the ruleset file. Thus the need to pass the --extensions=php -s
args each time can be eliminated by amending the ruleset with:
<arg name="extensions" value="php"/> <arg value="s"/>
And this further simplifies the command to:
phpcs .
But the command to run phpcs
can be even shorter. The current directory “.
” arg is being passed above because PHP_CodeSniffer will default to look at STDIN
if no paths are passed in the command. This is different from JSHint which will assume you want to look for JS files in the current directory, and JSHint instead uses the common CLI idiom “-
” to read from STDIN
(though strangely ESLint does not also follow this convention). But, in the above Gutenberg PR, James Nylen noted use of the <file>
to whitelist files and directories to check, and when this is in the ruleset then no paths need to be passed as args to phpcs
. Well, the ruleset also has <exclude-pattern>
defined then all that is really needed is for the ruleset to contain just “whitelist” one path, the current directory:
<file>.</file> <exclude-pattern>*/node_modules/*</exclude-pattern> <exclude-pattern>*/vendor/*</exclude-pattern>
And with that, all you need to run PHPCS is just:
phpcs
Support for these improvements has now been merged into wp-dev-lib. Additionally, I’ve opened a pull request for WP-CLI so that newly scaffolded projects can incorporate these improvements as well. I hope these changes improve your experience using PHP_CodeSniffer in your workflow.
I always think that it’s a good idea to use these with your IDE. So, that it can take you to the lines with the issue without having to search for it. With command line, it makes the task at hand quite tedious — just for PHPCS. How do you use it, Weston?
@ahmad Yes, absolutely. PHPCS should indeed be set up to run automatically in the IDE, as it should also be set up to run in the
pre-commit
hook and in CI builds. I use PhpStorm and wp-dev-lib for those use cases. But sometimes I just need to run PHPCS from the command line. For example, wp-dev-lib by default has aCHECK_SCOPE=patches
configuration which restricts reporting to just the lines changed in a commit or pull request. This is really useful when adding PHPCS to a preexisting project to avoid having thousands of errors screaming at you; I’ve proposed this for adding PHPCS to core in #34694. But if you do want to get a report on all of the PHPCS issues that should eventually get fixed in the project, you need to run PHPCS from the command line.Here’s what I’ve used to generate a report of all the PHPCS sniffs being violated in a codebase sorted by frequency:
phpcs -s --extensions=php --report=emacs . | ack -o '(?<=\()\w+(\.\w+)+(?=\)$)' | sort | uniq -c | sort -nr
Well, that command was quite helpful.
May I suggest you also add colors argument?
Thanks for the suggestion. I’ve followed up here: https://github.com/WordPress/gutenberg/pull/1685#issuecomment-312780011