Continuous integration/PHP CodeSniffer

From MediaWiki.org
Jump to: navigation, search

Draft to implement MediaWiki coding conventions using the PHP_CodeSniffer tool.

PHP_CodeSniffer is a style check tool for PHP. It is highly modular: each rule is an independent class; to write a standard you would create a ruleset.xml that includes the class you want to check your code against. Each module can thus reuse other modules' rules as well as implement its own rules.

Installing[edit | edit source]

First you want to install PHP_CodeSniffer using pear, the tool will be then made available as phpcs.

$ pear install PHP_CodeSniffer
<snip>
$ phpcs --version
PHP_CodeSniffer version 1.4.3 (stable) by Squiz Pty Ltd. (http://www.squiz.com.au)
$

You will want to grab the MediaWiki standard for PHP_CodeSniffer, it is available in the WMF git repository mediawiki/tools/codesniffer.git/:

To load the MediaWiki standard, you will have to pass the full path to the phpcs command:

$ phpcs --standard=/path/to/mediawiki/tools/codesniffer/MediaWiki

You will want to make an alias for it:

$ alias phpcsmw='phpcs --standard=/path/to/mediawiki/tools/codesniffer/MediaWiki'

Using[edit | edit source]

cd /path/to/mediawiki
phpcsmw -s -v .
Useful options
-v verbose mode (show the files being parsed)
-p gives you some progress (output E/. for each file kind of like PHPUnit)
-s shows the sniff name in the report, really useful


To get a nice report for a directory:

phpcsmw -v -s includes/api --report-summary

Where:

-v show the progress
-s report the snif name
--report-summary build a report per file and, since -s was given, per sniff.


If you want to actually fix errors, you will want to stop after each file and eventually recheck your changes. PHP_CodeSniffer comes with an interactive mode (with -a) which does exactly that:

$ phpcsmw -v -a .
Registering sniffs in MediaWiki standard... DONE (36 sniffs registered)
Creating file list... DONE (91 files in queue)
Changing into directory /srv/trunk/includes/api
Processing ApiBase.php [13888 tokens in 1663 lines]... DONE in 1 second (7 errors, 0 warnings)

FILE: /srv/trunk/includes/api/ApiBase.php
--------------------------------------------------------------------------------
FOUND 7 ERROR(S) AFFECTING 7 LINE(S)
--------------------------------------------------------------------------------
   69 | ERROR | There must not be more than one property declared per statement
  108 | ERROR | The abstract declaration must precede the visibility
      |       | declaration
  657 | ERROR | Expected 1 space after comma in function call; 2 found
  812 | ERROR | A cast statement must be followed by a single space
 1367 | ERROR | A cast statement must be followed by a single space
 1540 | ERROR | There must not be more than one property declared per statement
 1596 | ERROR | There must not be more than one property declared per statement
--------------------------------------------------------------------------------

<ENTER> to recheck, [s] to skip or [q] to quit : 

Fix the errors, press enter and you get a new run :-] Rinse until everything is fine.

getting details[edit | edit source]

One can list the available coding standards using phpcs -i. As of version 1.4.3, that does not show a standard loaded using --standard like our phpcsmw alias. Anyway, a list of standards would be:

$ phpcsmw -i
The installed coding standards are MySource, PEAR, PHPCS, PSR1, PSR2, Squiz and Zend
$

To list the rule for a standard, pass the '-e' option:

$ phpcsmw --standard=PSR1 -e

The PSR1 standard contains 7 sniffs

Generic (4 sniffs)
------------------
  Generic.Files.ByteOrderMark
  Generic.NamingConventions.CamelCapsFunctionName
  Generic.NamingConventions.UpperCaseConstantName
  Generic.PHP.DisallowShortOpenTag

PSR1 (2 sniffs)
---------------
  PSR1.Classes.ClassDeclaration
  PSR1.Files.SideEffects

Squiz (1 sniffs)
----------------
  Squiz.Classes.ValidClassName

Below each section is a list of sniffs which are really a PHP class which can then be reused by a module. That is exactly what we are doing for our MediaWiki module, instead of reinventing the wheel, we include sniffs from other modules.

See also[edit | edit source]