20th June 2013

Drupal Cyclomatic Complexity

John Ennew
Technical Director

We are sometimes asked when signing contracts to adhere to some arbitrary numeric qualification for quality code. The intent is sensible but the specific measures can often be irrelevant to Drupal or fail to address quality meaningfully. For example no function should be longer than 10 lines.

As professional Software Engineers, we want to be able to demonstrate compliance and adherence to best practice without need for what can be arbitrary metrics on the quality of code. The obvious is that our code meets the Drupal Coding Standards which can be measured by clean output from the Coder module. However, the need for concise code that meets the objective of separation of concerns – that no function should be longer than 10 lines is trying to address – is not sufficiently covered by coder at present. What is needed is a more useful measurement which does not constrain developers and meets the needs of the clients.

Cyclomatic Complexity puts a numeric value on the complexity of a function by calculating the number of possible routes through the function. We should be striving to make small and understandable blocks of code, a function which is overly complex would be difficult for a new developer to pick up or even for the original developer to remember what they were doing when they revisit it months later.

Another test for a function becoming complex is its nesting levels. This is the number of indentations in the code caused by switching such as if statements or foreach loops. Deep and complex nesting makes understanding the flow through the function difficult. A check in the coding standards which measure complexity, with the tools to support it (via the Drupal PHPCS plugin provided by the Coder module) would alert developers that their code needs refactoring. This would usually involve refactoring functions into smaller, more manageable chunks in which the purpose of the smaller functions is smaller but more clearly defined. This can also help with code reviews where another developer is able to look at each function briefly and in isolation and understand its purpose. To run the coder code review using drush with the Drupal PHPCS standards you use the following syntax to check the node module for example: drush coder node --sniffer

Show me an example!

The PHP Coding Standards put an upper limit on cyclomatic complexity at 10 and which is reasonable in our experience. Perhaps unsurprisingly, the Drupal 7 core comment module has some functions which fall short of these metrics. The function comment_node_view has a cyclomatic complexity of 15, so 5 above the threshold. Functions of this sort are ripe for refactoring and this test immediately indicates this. comment_save() and comment_form() also score above 10. The PHP Coding Standards put an upper limit of nesting levels of 5. On this metric, comment_node_view has a nesting depth of 6, meaning 6 levels of indentation due to code blocks, which again indicates a function which needs some refactoring to make it easier to read.

Let's make this happen!

If this is something that interests you, if you have an opinion on the limits of the metric or you hate the idea completely then add your voice to the conversation here: http://drupal.org/node/1960996 or test the patch for Coder here: http://drupal.org/node/1934594#comment-7171972