-
Notifications
You must be signed in to change notification settings - Fork 26
Create a WP_CLI_CS standard for PHP_CodeSniffer
#44
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Create a WP_CLI_CS standard for PHP_CodeSniffer
#44
Conversation
3ec61d5 to
b9574af
Compare
|
FYI: the build won't pass (yet) as - per discussion in #34 - the custom ruleset for this repo hasn't been adjusted yet to use the |
|
PR has been updated based on feedback. |
e9009d8 to
b4aa1fb
Compare
|
@schlessera I saw your approval: to get this merged with a passing build, I'd have to either adjust or remove the custom ruleset for this repo. The ruleset as is, isn't testing anything anyway. Now you've seen the direction this is going in, what would be your preference ? |
|
@schlessera ☝️ ? |
3aa91b9 to
42301b4
Compare
|
I've force pushed an updated version of this branch (as discussed on Slack). The significant changes are:
|
42301b4 to
5cdf332
Compare
|
OK, so to get this PR passing, the ruleset in the root of this repo will need to be adjusted and the code of this repo will need to pass the CS check. Currently there are 105 issues still remaining which need to be fixing, whitelisted or exclusion via configuration. This is the detailed list: |
5cdf332 to
e273e89
Compare
|
I went through all the issues and made multiple pull requests. Here is the list of remaining issues I cannot simply fix: |
|
Thank you for that!
I have made the necessary updates to the repo ruleset and added whitelist comments where relevant (in my local version of this PR branch). Once your PRs have been merged, I will rebase this PR and add the additional commits with which the build should now pass (tested locally & confirmed). |
PHPCS 3.1.0 introduced the ability to use dot prefixed configuration files. In PHPCS 3.1.1 the loading order of these got normalized. So, in effect PHP will search for configuration files in this order: 1. `.phpcs.xml` 2. `phpcs.xml` 3. `.phpcs.xml.dist` 4. `phpcs.xml.dist` This is just a minor tweak so the same order of preference is used in this script to list the possible config files. Refs; * https://github.com/squizlabs/PHP_CodeSniffer/releases/3.1.0 * https://github.com/squizlabs/PHP_CodeSniffer/releases/3.1.1
* `.distignore`: no need to distribute the phpcs/phpunit config files.
* `.gitignore`: Allow devs to overwrite config files for PHPUnit and PHPCS
- The `.dist` files should be committed. However, for their personal use, devs can overrule those files with versions without `.dist`.
Those personal versions should never be committed.
As a side-note: for PHPCS, having a personal version while still using the original `.dist` file is made very easy, as you can just import the `.dist` file as a starting point, like so:
```xml
<?xml version="1.0"?>
<ruleset name="WP-CLI">
<rule ref="./phpcs.xml.dist"/>
</ruleset>
```
e273e89 to
fa58e00
Compare
f9aadba to
186abba
Compare
A PHPCS standard is in principle the same as a custom ruleset with these differences:
Custom ruleset | External PHPCS standard
--- | ---
File: `[.]phpcs.xml[.dist]` | File: `ruleset.xml`
Can be included in other rulesets using the path to the file (which can get complicated) | Can be included in other rulesets by name
Can only use existing sniffs | Can add new sniffs native to the standard (not currently used)
Aside from that, one has to keep in mind that all paths used in a ruleset are interpreted _relative to the ruleset_.
As an external standard can be installed both globally as well as local to a project, it is better not to have any specifics involving file paths in an external standard, but to use a custom ruleset, which generally lives in the project root, for this instead.
So, this commit introduces a `WPCliCS` standard to the `wp-cli-tests` project which is a dependency for all WP-CLI projects, making this standard easily available to them all.
As the `dealerdirect/phpcodesniffer-composer-installer` plugin is a `require`ment for this project (and therefore all WP-CLI projects), this new `WPCliCS` standard will automatically be recognized and installed via the plugin.
No extra actions needed 😎
To see it in action, just run a `composer install`/`composer update` and then run `vendor/bin/phpcs -i` and `WPCliCS` should now be listed as one of the installed standards.
About the ruleset itself, there are a couple of things to take note of:
* Based on the information received in 34 - WP won't always be (fully) loaded when code from the WP-CLI commands is run, IMO it will be better to include the `PHPCompatibility` standard (stricter) than the `PHPCompatibilityWP` standard, as the polyfills which the `PHPCompatibilityWP` standard accounts for will not necessarily always be available.
Includes adjusting the `composer.json` requirement to match.
* As not all project have the same minimum PHP version, the `testVersion` config setting is not set in the standard, but should be set in the custom ruleset of each project.
While it _is_ possible since PHP 3.3.0 to overrule a `config` setting from the command-line, overruling it from a custom ruleset is still not possible, so it is better to set it in the custom ruleset in the first place.
* While the PHPCompatibility sniffs should be limited to `.php` files, the other sniffs shouldn't necessarily be limited to this, so instead of setting `<arg name="extensions" value="php"/>`, I'm using an `<include-pattern>` for the `PHPCompatibility` sniffs only.
- Side-note: By default, PHPCS will scan files with the following file extensions: `.php`, `.inc` (interpreted as PHP), `.js` and `.css`. As most WP-CLI projects don't include `.js` or `.css` files (or `.inc` files for that matter), there is rarely a need to set limit the `extensions` from within a project ruleset.
- Similarly, any directories which don't contain any of the above mentioned file types, don't need to be excluded via a `<exclude-pattern>` either, as PHPCS won't find any files to scan anyway.
- Also, take note of the syntax used in the `<include-pattern>`. Both `<include-pattern>`s as well as `<exclude-pattern>`s are basically PHP PCRE regular expressions, with one caveat: any `*` in the pattern will automatically be replaced by `.*`.
This also means that characters which have special meaning in a PCRE regex, like the `.` have to be escaped properly!
* In the base ruleset in the `wp-cli-tests` root (and in `wp-cli`), the `WordPress-Core` ruleset was included.
While this is all well and good, the `WordPress-Extra` ruleset contains many additional sniffs for code quality as well as some sniffs for modern PHP code style, which is not yet covered in the Core code style handbook.
As the WP-CLI projects use PHP 5.4 as a minimum, using the `WordPress-Extra` ruleset is IMO the better choice. Even though there are some exceptions to the rules which need to be made, the majority of the additional sniffs contained within the `Extra` ruleset will be valuable to scan against.
* A standard should be widely applicable and should not contain `<exclude>` exceptions which are solely for one project.
This means that the `exclude`s which were used so far have largely been removed.
Regarding the remaining (and new) `exclude`s:
- The exclusion of the `array_column` detection is valid as the polyfill is shipped with `wp-cli` and therefore available to all WP-CLI projects.
- The `Generic.PHP.Syntax` sniff basically does a `php -l` on a file. As linting the files is already done in a separate Travis job for all projects, this sniff is not needed.
- The `WordPress.File.FileName` sniff conflicts with PSR-4, which is used for the autoloading of the WP-CLI files, so this is a legitimate exclusion.
- The `WordPress.PHP.DiscouragedPHPFunctions` and `WordPress.WP.AlternativeFunctions` contain some recommendations which are not all that applicable for project running as cli, so the most typically problematic ones have been excluded.
The same applies to the `Generic.PHP.BacktickOperator` sniff.
Further exclusions can be made, if and when, needed from individual project-based rulesets.
- Along the same lines, the `WordPress.PHP.DevelopmentFunctions` discourages the use of typical PHP dev related functions. As WP-CLI is a developers tool, I believe it is legitimate to use these functions in this context.
- Lastly, variable output send to the command-line should probably use some form of escaping, but the output escaping functions the `WordPress.Security.EscapeOutput` sniff checks for are _HTML_output escaping functions, which are not applicable in this context.
In the future, this standard could be extended with a custom sniff for output escaping for the command line.
Similarly, a custom sniff to verify that arbitrary arguments passed to shell commands are escaped properly using `escapeshellcmd()` or `escapeshellarg()` should also be considered.
* I've added configuration for one particular sniff: `WordPress.NamingConventions.PrefixAllGlobals`.
Even though the WP environment will not always be (fully) loaded, it oftentimes will be. In that case, naming conflicts between plugins and WP-CLI projects for names in the global namespace can occur.
To that end, all WP-CLI code should be either namespaced or prefixed.
As the sniff will just be silent if there is no configuration present, I've added the most generic configuration possible to still demand prefixes.
Individual projects can overrule and/or - as of PHPCS 3.4.0 - add to this configuration from their own project ruleset.
* While I've added the PHPCS schema tags to the ruleset, the schema will not be able to validate correctly, unless PHPCS 3.3.2+ is used.
PHPCS 3.3.0 introduced a new syntax for array elements to the rulesets, but the schema wasn't updated for this new syntax until PHPCS 3.3.2.
This basically cleans out the existing example ruleset and replaces it with a ruleset specifically aimed at the code in this repository. The file is completely documented in-line.
Includes minor documentation fix.
186abba to
8ada83a
Compare
WPCliCS standard for PHP_CodeSnifferWP_CLI_CS standard for PHP_CodeSniffer
Create a `WP_CLI_CS` standard for PHP_CodeSniffer
A PHPCS standard is in principle the same as a custom ruleset with these differences:
[.]phpcs.xml[.dist]ruleset.xmlAside from that, one has to keep in mind that all paths used in a ruleset are interpreted relative to the ruleset.
As an external standard can be installed both globally as well as local to a project, it is better not to have any specifics involving file paths in an external standard, but to use a custom ruleset, which generally lives in the project root, for this instead.
So, this PR introduces a
WPCliCSstandard to thewp-cli-testsproject which is a dependency for all WP-CLI projects, making this standard easily available to them all.As the
dealerdirect/phpcodesniffer-composer-installerplugin is arequirement for this project (and therefore all WP-CLI projects), this newWPCliCSstandard will automatically be recognized and installed via the plugin.No extra actions needed 😎
To see it in action, just run a
composer install/composer updateand then runvendor/bin/phpcs -iandWPCliCSshould now be listed as one of the installed standards.About the ruleset itself, there are a couple of things to take note of:
PHPCompatibilitystandard (stricter) than thePHPCompatibilityWPstandard, as the polyfills which thePHPCompatibilityWPstandard accounts for will not necessarily always be available.Includes adjusting the
composer.jsonrequirement to match.testVersionconfig setting is not set in the standard, but should be set in the custom ruleset of each project.While it is possible since PHP 3.3.0 to overrule a
configsetting from the command-line, overruling it from a custom ruleset is still not possible, so it is better to set it in the custom ruleset in the first place..phpfiles, the other sniffs shouldn't necessarily be limited to this, so instead of setting<arg name="extensions" value="php"/>, I'm using an<include-pattern>for thePHPCompatibilitysniffs only..php,.inc(interpreted as PHP),.jsand.css. As most WP-CLI projects don't include.jsor.cssfiles (or.incfiles for that matter), there is rarely a need to set limit theextensionsfrom within a project ruleset.<exclude-pattern>either, as PHPCS won't find any files to scan anyway.<include-pattern>. Both<include-pattern>s as well as<exclude-pattern>s are basically PHP PCRE regular expressions, with one caveat: any*in the pattern will automatically be replaced by.*.This also means that characters which have special meaning in a PCRE regex, like the
.have to be escaped properly!wp-cli-testsroot (and inwp-cli), theWordPress-Coreruleset was included.While this is all well and good, the
WordPress-Extraruleset contains many additional sniffs for code quality as well as some sniffs for modern PHP code style, which is not yet covered in the Core code style handbook.As the WP-CLI projects use PHP 5.4 as a minimum, using the
WordPress-Extraruleset is IMO the better choice. Even though there are some exceptions to the rules which need to be made, the majority of the additional sniffs contained within theExtraruleset will be valuable to scan against.<exclude>exceptions which are solely for one project.This means that the
excludes which were used so far have largely been removed.Regarding the remaining (and new)
excludes:array_columndetection is valid as the polyfill is shipped withwp-cliand therefore available to all WP-CLI projects.Generic.PHP.Syntaxsniff basically does aphp -lon a file. As linting the files is already done in a separate Travis job for all projects, this sniff is not needed.WordPress.File.FileNamesniff conflicts with PSR-4, which is used for the autoloading of the WP-CLI files, so this is a legitimate exclusion.WordPress.PHP.DiscouragedPHPFunctionsandWordPress.WP.AlternativeFunctionscontain some recommendations which are not all that applicable for project running as cli, so the most typically problematic ones have been excluded.The same applies to the
Generic.PHP.BacktickOperatorsniff.Further exclusions can be made, if and when, needed from individual project-based rulesets.
WordPress.PHP.DevelopmentFunctionsdiscourages the use of typical PHP dev related functions. As WP-CLI is a developers tool, I believe it is legitimate to use these functions in this context.WordPress.Security.EscapeOutputsniff checks for are _HTML_output escaping functions, which are not applicable in this context.In the future, this standard could be extended with a custom sniff for output escaping for the command line.
Similarly, a custom sniff to verify that arbitrary arguments passed to shell commands are escaped properly using
escapeshellcmd()orescapeshellarg()should also be considered.WordPress.NamingConventions.PrefixAllGlobals.Even though the WP environment will not always be (fully) loaded, it oftentimes will be. In that case, naming conflicts between plugins and WP-CLI projects for names in the global namespace can occur.
To that end, all WP-CLI code should be either namespaced or prefixed.
As the sniff will just be silent if there is no configuration present, I've added the most generic configuration possible to still demand prefixes.
Individual projects can overrule and/or - as of PHPCS 3.4.0 - add to this configuration from their own project ruleset.
PHPCS 3.3.0 introduced a new syntax for array elements to the rulesets, but the schema wasn't updated for this new syntax until PHPCS 3.3.2.
Fixes #34
Other Changes
bin/run-phpcs-tests: list config files in PHPCS precedence order
PHPCS 3.1.0 introduced the ability to use dot prefixed configuration files.
In PHPCS 3.1.1 the loading order of these got normalized.
So, in effect PHP will search for configuration files in this order:
.phpcs.xmlphpcs.xml.phpcs.xml.distphpcs.xml.distThis is just a minor tweak so the same order of preference is used in this script to list the possible config files.
Refs;
Composer: temporarily require PHPCS
Strictly speaking PHPCS is not a requirement of this project, but a requirement of its dependencies WPCS + PHPCompatibility.
However, WPCS currently supports PHPCS
^2.9 || ^3.1and PHPCompatibility still supports PHPCS all the way back to 2.3.For the WP-CLI projects, it is preferred that these use a more recent PHPCS version.
Aside from the fact that this means that a lot of sniffs will be more accurate, this will also allow for using, for instance:
basepathsetting for cleaner result reports. (PHPCS 3.0+)parallelsetting for multi-threaded scanning. (PHPCS 3.0+)Once WPCS 2.0 comes out, which is expected to have a PHPCS
^3.3.1minimum requirement, the requirement in the composer file in this package can be removed.Refs:
.gitignore/.distignore: ignore phpcs/phpunit config files
.distignore: no need to distribute the phpcs/phpunit config files..gitignore: Allow devs to overwrite config files for PHPUnit and PHPCS.distfiles should be committed. However, for their personal use, devs can overrule those files with versions without.dist.Those personal versions should never be committed.
As a side-note: for PHPCS, having a personal version while still using the original
.distfile is made very easy, as you can just import the.distfile as a starting point, like so:README/USING: add instructions on how projects can use the base ruleset