Conforming to coding standards with linters

By:

on

July 15, 2015

At the the DrupalNorth code sprint, I spent some time chatting about code linters, and how to use them to ensure your code conforms to coding standards. So, I thought I'd share the process that works for me.

If you find a better process, please blog about it and post a link in the comments!

This tutorial assumes:

You write or modify code in a language like PHP, JavaScript, CSS, Bash, etc.

What is a linter?

Simply put, a linter is a static analysis tool that you can run to ensure that your code is free from syntax and/or style errors.

Types of linters

To help me prioritize fixing linter messages, I usually classify linters into two types:

Linters that check for syntax errors, and,

Linters that check for coding standards violations.

I consider linters that check for syntax errors manditory, since I can't really think of a time when I would want code which contains syntax errors (in PHP and JavaScript, syntax errors cause unrecoverable fatal errors if the file containing the code is ever parsed (i.e.: white screen of death, JavaScript engine halting)). I will not commit code unless these types of linters give the okay.

I consider linters that check for coding standards violations strongly recommended (as they affect the maintainability of your code), but technically optional (because code that doesn't conform to standards still works). I try to avoid committing code that doesn't pass these linters; but there are some circumstances when that is unavoidable (e.g.: if I have to commit a contributed module, or if it's a hotfix and there's a plan to make the code more-maintainable later).

Checking for syntax errors

Many interpreted languages and shells have a syntax-checker built into them, for example:

php -l $file will check a PHP script for syntax errors,

bash -n $file will check a BASH shell script for syntax errors,

ruby -c $file will check a Ruby script for syntax errors,

perl -c $file will check a Perl script for syntax errors,

zsh -n $file will check a ZSH shell script for syntax errors, and,

fish -n $file will check a Fish shell script for syntax errors.

I wasn't able to find any built in syntax linters for JavaScript, Python, and PowerShell, but please leave a comment if you know of one.

Since Drupal's coding standards differ slightly from other communities, all of these tools need to be configured slightly before you can use them. I'll explain how to install and configure all of these below.

Setting a default coding standard

It is possible to set a default coding standard (i.e.: so you can just run phpcs $file), but:

You still have to run

phpcs --standard=DrupalPractice $file

to check that the file conforms to best practices, and,

If you ever have to work on non-Drupal projects, you'll have to explicitly state:

phpcs --standard=PEAR $file

for php's default functionality.

Instead of setting a default, you could create an alias in your shell. For example, if you use Bash, adding...

alias drupalcs='phpcs --standard=Drupal'

... to your .bash_profile or .bashrc will let you run...

drupalcs $file

... instead of...

phpcs --standard=Drupal $file

If you use another shell, this is left as an exercise to the reader.

Fix coding standards violations with the PHP Code Beautifier (phpcbf)

PHP CodeSniffer also ships with a command called phpcbf (PHP Code Beautifier), which can fix some coding standards violations automatically. For example, to convert a file to the Drupal coding standards, run:

A note on the history of Drupal coding standards checkers

In the past, most of us used the Coder module to check that our work conformed to the Drupal coding standards and documentation standards. However, the Coder module relied on parsing PHP, JavaScript, etc. code using regular expressions, which were hard to understand, write, and maintain, and couldn't catch all cases (because almost all programming languages are parsed with tokenizers and context-free grammars).

As the Drupal Community developed our own CSS coding standards and JavaScript coding standards, we needed a way to automatically check those too. Rather than writing our own parsers, we decided to "get off the island" and use what the wider web development community was using.

Stay tuned

Next week, I will blog about automatically running linters when you commit code, which can be pretty useful.