PHP/Drupal Code Quality Quick Wins, Part 2: Validating Code Standards

The Drupal project has coding standards, available at https://drupal.org/coding-standards, based on the PEAR coding standards (http://pear.php.net/manual/en/standards.php).

These code standards are a set of guidelines that cover file organisation, internal documentation, naming conventions, whitespace/indentation settings, line length, line wrapping, concatenation styles, etc. The general aim is to have a more uniform code base throughout the project, to make working with someone else’s code easier, to reduce bugs and to allow for certain automated processes such as documentation generation and patch testing.

The easiest way to start producing code that lives up to the standards is by simply having PHP_CodeSniffer (http://pear.php.net/package/PHP_CodeSniffer/docs), also often referred to as phpcs, report on the state of your code and learn from the remarks.

Phpcs simply parses any given code and basically validates it against a given set of rules. By default phpcs validates against the PEAR standard, but additional standards can be added. In our case, we will download Drupal’s coder.module (http://drupal.org/project/coder) to a central location (/opt/coder for example). Amongst other things, this module contains Drupal Code Standards integration support for phpcs, so we just need to make phpcs aware of the existence of this integration code and we’re ready to go.

Installation

# Install phpcs with PEAR.
$ pear config-set auto_discover 1
$ pear install PHP_CodeSniffer
 
# Install Drupal’s coder module.
$ cd /opt/; drush dl coder
 
# Make phpcs aware of our ‘Drupal’ code standard.
$ phpcs --config-set installed_paths /path/to/coder/coder_sniffer
 
# Optional: make the ‘Drupal’ code standard default.
# phpcs --config-set default_standard Drupal

Usage

$ phpcs —standard=drupal example.php
$ phpcs —standard=drupal —extensions=“php, module, install, inc, test” /path/to/my/code/example.php

Example output:

--------------------------------------------------------------------------------
FOUND 11 ERROR(S) AND 1 WARNING(S) AFFECTING 8 LINE(S)
--------------------------------------------------------------------------------
  2 | ERROR   | Missing file doc comment
  8 | ERROR   | Spaces must be used to indent lines; tabs are not allowed
  8 | ERROR   | Line indented incorrectly; expected 2 spaces, found 1
 10 | ERROR   | Missing function doc comment
 19 | WARNING | Line exceeds 80 characters; contains 102 characters
 19 | ERROR   | Inline comments must start with a capital letter
 19 | ERROR   | Inline comments must end in full-stops, exclamation marks, or
     |         	      | question marks
 20 | ERROR   | Missing function doc comment
 24 | ERROR   | Inline comments must start with a capital letter
 26 | ERROR   | Missing function doc comment
 26 | ERROR   | Visibility must be declared on method "tearDown"
 29 | ERROR   | Missing function doc comment
--------------------------------------------------------------------------------

Retro-actively checking a big-ish module can generate dozens if not hundreds of warnings. Don’t be discouraged: cleaning up your code is totally worth it. Trust me on this one.

IDE integration

Being able to run linters and tools like phpcs from the command line is pretty nice, but sometimes having to switch between your editor and the command line is too much of an interruption for some. Luckily, because these tools are open sourced, and open source people are awesome human beings, support and integration for these tools exists for most browsers.

Here’s a quick overview of how different IDEs integrate phpcs:

Sublime Text 2 and 3:
http://www.soulbroken.co.uk/code/sublimephpcs/

PhpStorm:
http://www.jetbrains.com/phpstorm/webhelp/using-php-code-sniffer-tool.html

Eclipse:
http://www.phpsrc.org/projects/pti-php-codesniffer/wiki/

Netbeans:
http://popthestash.com/2013/04/11/install-code-sniffer-extension-in-netb...

Have fun.

PHP/Drupal Code Quality Quick Wins, Part 2: Validating Code Standards

The Drupal project has coding standards, available at https://drupal.org/coding-standards, based on the PEAR coding standards (http://pear.php.net/manual/en/standards.php).

These code standards are a set of guidelines that cover file organisation, internal documentation, naming conventions, whitespace/indentation settings, line length, line wrapping, concatenation styles, etc. The general aim is to have a more uniform code base throughout the project, to make working with someone else’s code easier, to reduce bugs and to allow for certain automated processes such as documentation generation and patch testing.

The easiest way to start producing code that lives up to the standards is by simply having PHP_CodeSniffer (http://pear.php.net/package/PHP_CodeSniffer/docs), also often referred to as phpcs, report on the state of your code and learn from the remarks.

Phpcs simply parses any given code and basically validates it against a given set of rules. By default phpcs validates against the PEAR standard, but additional standards can be added. In our case, we will download Drupal’s coder.module (http://drupal.org/project/coder) to a central location (/opt/coder for example). Amongst other things, this module contains Drupal Code Standards integration support for phpcs, so we just need to make phpcs aware of the existence of this integration code and we’re ready to go.

Installation

# Install phpcs with PEAR.
$ pear config-set auto_discover 1
$ pear install PHP_CodeSniffer
 
# Install Drupal’s coder module.
$ cd /opt/; drush dl coder
 
# Make phpcs aware of our ‘Drupal’ code standard.
$ phpcs --config-set installed_paths /path/to/coder/coder_sniffer
 
# Optional: make the ‘Drupal’ code standard default.
# phpcs --config-set default_standard Drupal

Usage

$ phpcs —standard=drupal example.php
$ phpcs —standard=drupal —extensions=“php, module, install, inc, test” /path/to/my/code/example.php

Example output:

--------------------------------------------------------------------------------
FOUND 11 ERROR(S) AND 1 WARNING(S) AFFECTING 8 LINE(S)
--------------------------------------------------------------------------------
  2 | ERROR   | Missing file doc comment
  8 | ERROR   | Spaces must be used to indent lines; tabs are not allowed
  8 | ERROR   | Line indented incorrectly; expected 2 spaces, found 1
 10 | ERROR   | Missing function doc comment
 19 | WARNING | Line exceeds 80 characters; contains 102 characters
 19 | ERROR   | Inline comments must start with a capital letter
 19 | ERROR   | Inline comments must end in full-stops, exclamation marks, or
     |         	      | question marks
 20 | ERROR   | Missing function doc comment
 24 | ERROR   | Inline comments must start with a capital letter
 26 | ERROR   | Missing function doc comment
 26 | ERROR   | Visibility must be declared on method "tearDown"
 29 | ERROR   | Missing function doc comment
--------------------------------------------------------------------------------

Retro-actively checking a big-ish module can generate dozens if not hundreds of warnings. Don’t be discouraged: cleaning up your code is totally worth it. Trust me on this one.

IDE integration

Being able to run linters and tools like phpcs from the command line is pretty nice, but sometimes having to switch between your editor and the command line is too much of an interruption for some. Luckily, because these tools are open sourced, and open source people are awesome human beings, support and integration for these tools exists for most browsers.

Here’s a quick overview of how different IDEs integrate phpcs:

Sublime Text 2 and 3:
http://www.soulbroken.co.uk/code/sublimephpcs/

PhpStorm:
http://www.jetbrains.com/phpstorm/webhelp/using-php-code-sniffer-tool.html

Eclipse:
http://www.phpsrc.org/projects/pti-php-codesniffer/wiki/

Netbeans:
http://popthestash.com/2013/04/11/install-code-sniffer-extension-in-netb...

Have fun.

PHP/Drupal Code Quality Quick Wins, Part 1: Linting

In this first part we’re looking at a few tools that are very easy to set up and use, yet can make a dramatic impact in the quality and coherence of your team’s codebase.

From validating syntax to detecting dead code to graphing dependency chains and measuring cyclometric complexity, static analysis tools help you analyse code without actually executing it.

For ages we kept saying “we’ve got no time to waste on trying to figure out this stuff, we have bugs to fix”. We kept chasing after elusive bugs, weird regressions (once-solved bugs that suddenly pop up again) and new breakages and we "never had time” to start improving the core of our development process.

Once we actually took the time, we discovered it’s pretty easy to get started. If you come from a workflow with zero attention to code analysis, testing and automated integration, there are some very easy and interesting quick wins out there.

We’ll try to cover several approaches, flows and tools in the weeks and months to come. We’ll likely discover new tools and new ways of improving our internal way of doing things, and we’ll share those as we encounter them - they may in some form be useful to you and your team as well.

On to the linting

In a nutshell, linters check checks if your source code is syntactically valid; it does not necessarily have any opinions about your coding style or about the soundness of your architecture. PHP's built-in linter is such a basic sanity-checking tool. Other tools such as jshint and jslint can be more opinionated.

Though this is a very simplistic check, you’d be amazed of how useful it can be to integrate automatic linting in your commit, test and deployment process.

1. PHP linting

Installation:
Linting comes built-in with php-cli, the command line version of PHP, so if you’ve got that up and running you’re ready to start linting.

Example file:

<?php
foo()
$a = 1;
// etc.

Usage:

# Example 1: Lint a single php file.
$ php -l example.php

Example output:

PHP Parse error: parse error in example.php on line 2

When the linter encounters an error, the return code (a.k.a. exit status) will be non-zero, which means you can easily integrate php -l in scripts that perform certain actions (like deploying code) based on whether or not the linter encountered errors.

# Example 2: Lint all php files in a directory.
$ php -l .

2. JavaScript linting

Though there are several javascript linters out there, JSHint (http://jshint.com/install/) is nowadays the most popular one. As of Drupal 8 requires all core and contrib JavaScript changes to pass JSHint checks, so it's a pretty good idea to add JSHint to your linting toolchain today.

If you want to validate JavaScript code in the context of a D8 project, you don't need to do anything specific: D8 core now contains the two required JSHint configuration files (https://drupal.org/node/1955232):

  • .jshintrc: some Drupal-specific rules
  • .jshintignore: which files JSHint should ignore

If you're working on a D7 project and want to validate your custom JavaScript code according to the D8 standards, just grab the 2 config files and put them in your D7 project's root.

The most convenient way to use JSHint is to run it from the command line. For this you'll need to install nodejs (http://nodejs.org/download/) and use its package manager npm to install jshint. Installing nodejs for this may seem like overkill, but there's an incredible array of interesting stuff available in nodejs land :)

# Install JSHint.
$ npm install -g jshint

Usage:

# Example 1: Lint a single js file.
$ jshint example.js
# Example 2: Lint all of D8's core js.
$ cd /path/to/example.com
$ jshint core
# Example 3: Lint all of a D8 project's js (core+contrib).
$ cd /path/to/example.com
$ jshint .

More info:

3. CSS linting

The standard ruleset used by CSS Lint (http://csslint.net) is pretty sane, though it does have some conflicts with the proposed Drupal CSS code standards (discussed here: https://drupal.org/node/1886770).

At the time of writing (March 2014) there doesn't seem to be a specific Drupal CSS ruleset available for CSS Lint, though efforts are underway to create a .csslintrc config file, similar to .jshintrc. For now, the standard CSS Lint ruleset is already a huge help.

# Install CSS Lint.
$ npm install -g csslint
 
Usage:
# Example 1: Lint a single css file.
$ csslint example.css
 
# Example 2: Lint all css files in a directory.
$ csslint .</p>

More info:

4. SASS/SCSS linting

If you're a front-end developer chances are you're using something like SASS (http://sass-lang.com) or Compass (http://compass-style.org) to infuse to your css files with variables, loops, extensions and more. The CSS extensions defined by sass can become tricky, so it makes sense to bring a specialized linter into play… enter scss-lint (https://github.com/causes/scss-lint):

# If you haven't already, install the SASS gem.
$ gem install sass
 
# Install scss-lint.
$ gem install scss-lint
 
Usage:
#Example 1: Lint a single scss file.
# scss-lint example.css
 
#Example 2: Lint all scss files in a directory.
# scss-lint .

Note: scss-lint has built-in support for the Compass framework; you just need to explicitly specify you want to enable the compass linter. Check out the docs (https://github.com/causes/scss-lint/blob/master/lib/scss_lint/linter/com...) to see how.

More info:

Conclusion

Linting tools help you validate source code. Command-line linters can be run ad-hoc and integrated into IDEs and build scripts. Setting them up and running them is pretty straightfoward and can have huge benefits for your team's code quality.

Look out for follow-up articles where we'll go into validating custom Drupal code and enforcing our code validations with git pre-commit hooks.

PHP/Drupal Code Quality Quick Wins, Part 1: Linting

In this first part we’re looking at a few tools that are very easy to set up and use, yet can make a dramatic impact in the quality and coherence of your team’s codebase.

From validating syntax to detecting dead code to graphing dependency chains and measuring cyclometric complexity, static analysis tools help you analyse code without actually executing it.

For ages we kept saying “we’ve got no time to waste on trying to figure out this stuff, we have bugs to fix”. We kept chasing after elusive bugs, weird regressions (once-solved bugs that suddenly pop up again) and new breakages and we "never had time” to start improving the core of our development process.

Once we actually took the time, we discovered it’s pretty easy to get started. If you come from a workflow with zero attention to code analysis, testing and automated integration, there are some very easy and interesting quick wins out there.

We’ll try to cover several approaches, flows and tools in the weeks and months to come. We’ll likely discover new tools and new ways of improving our internal way of doing things, and we’ll share those as we encounter them - they may in some form be useful to you and your team as well.

On to the linting

In a nutshell, linters check checks if your source code is syntactically valid; it does not necessarily have any opinions about your coding style or about the soundness of your architecture. PHP's built-in linter is such a basic sanity-checking tool. Other tools such as jshint and jslint can be more opinionated.

Though this is a very simplistic check, you’d be amazed of how useful it can be to integrate automatic linting in your commit, test and deployment process.

1. PHP linting

Installation:
Linting comes built-in with php-cli, the command line version of PHP, so if you’ve got that up and running you’re ready to start linting.

Example file:

<?php
foo()
$a = 1;
// etc.

Usage:

# Example 1: Lint a single php file.
$ php -l example.php

Example output:

PHP Parse error: parse error in example.php on line 2

When the linter encounters an error, the return code (a.k.a. exit status) will be non-zero, which means you can easily integrate php -l in scripts that perform certain actions (like deploying code) based on whether or not the linter encountered errors.

# Example 2: Lint all php files in a directory.
$ php -l .

2. JavaScript linting

Though there are several javascript linters out there, JSHint (http://jshint.com/install/) is nowadays the most popular one. As of Drupal 8 requires all core and contrib JavaScript changes to pass JSHint checks, so it's a pretty good idea to add JSHint to your linting toolchain today.

If you want to validate JavaScript code in the context of a D8 project, you don't need to do anything specific: D8 core now contains the two required JSHint configuration files (https://drupal.org/node/1955232):

  • .jshintrc: some Drupal-specific rules
  • .jshintignore: which files JSHint should ignore

If you're working on a D7 project and want to validate your custom JavaScript code according to the D8 standards, just grab the 2 config files and put them in your D7 project's root.

The most convenient way to use JSHint is to run it from the command line. For this you'll need to install nodejs (http://nodejs.org/download/) and use its package manager npm to install jshint. Installing nodejs for this may seem like overkill, but there's an incredible array of interesting stuff available in nodejs land :)

# Install JSHint.
$ npm install -g jshint

Usage:

# Example 1: Lint a single js file.
$ jshint example.js
# Example 2: Lint all of D8's core js.
$ cd /path/to/example.com
$ jshint core
# Example 3: Lint all of a D8 project's js (core+contrib).
$ cd /path/to/example.com
$ jshint .

More info:

3. CSS linting

The standard ruleset used by CSS Lint (http://csslint.net) is pretty sane, though it does have some conflicts with the proposed Drupal CSS code standards (discussed here: https://drupal.org/node/1886770).

At the time of writing (March 2014) there doesn't seem to be a specific Drupal CSS ruleset available for CSS Lint, though efforts are underway to create a .csslintrc config file, similar to .jshintrc. For now, the standard CSS Lint ruleset is already a huge help.

# Install CSS Lint.
$ npm install -g csslint
 
Usage:
# Example 1: Lint a single css file.
$ csslint example.css
 
# Example 2: Lint all css files in a directory.
$ csslint .</p>

More info:

4. SASS/SCSS linting

If you're a front-end developer chances are you're using something like SASS (http://sass-lang.com) or Compass (http://compass-style.org) to infuse to your css files with variables, loops, extensions and more. The CSS extensions defined by sass can become tricky, so it makes sense to bring a specialized linter into play… enter scss-lint (https://github.com/causes/scss-lint):

# If you haven't already, install the SASS gem.
$ gem install sass
 
# Install scss-lint.
$ gem install scss-lint
 
Usage:
#Example 1: Lint a single scss file.
# scss-lint example.css
 
#Example 2: Lint all scss files in a directory.
# scss-lint .

Note: scss-lint has built-in support for the Compass framework; you just need to explicitly specify you want to enable the compass linter. Check out the docs (https://github.com/causes/scss-lint/blob/master/lib/scss_lint/linter/com...) to see how.

More info:

Conclusion

Linting tools help you validate source code. Command-line linters can be run ad-hoc and integrated into IDEs and build scripts. Setting them up and running them is pretty straightfoward and can have huge benefits for your team's code quality.

Look out for follow-up articles where we'll go into validating custom Drupal code and enforcing our code validations with git pre-commit hooks.