Code Review Module - Coder

Coder is the code review module. The name coder is a double entendre, "coder" being someone who writes code, and "code-r" short for "code review".

User Reference

To be filled in...

Review and Rule Developer References

Reviews

A review is a set of rules designed to accomplish a task. There is a code standards review, a review for upgrading from 4.7.x->5.x, another review for upgrading from 5.x->6.x, there's the beginnings of a security review and a performance review. Each review has an array of rules. The reviews are shown on the UI pages and can be found in the includes directory.

Options

  • #title
  • #link - link to drupal.org page about the review
  • #rules - rule definition (see below)
  • #severity - default severity (minor, normal, critical) for all rules in the review. severity controls the color and icons displayed. this value can be over-riden by individual rules.

Rules

A rule is a single specific pattern to find. Rules can use the following #type:

  • regex - look for a particular pattern
  • grep - looks for a particular string, meant to be faster when regex is not needed
  • grep_invert - look for a particular string that does not exist
  • callback - do anything you want

More about regex rules

Thus, to find all _submit functions you could use

    array(
      '#type' => 'regex',
      '#value' => '_submit\s*\(',
    ),

This example regex looks for _submit followed by optional spaces, and a required left parenthesis. If you wanted to be more specific, since the _submit handler has very specific arguments that are changing, you could look for:

      '#value' => '_submit\s*\(\$form_id,',

Remember, coder is just a helpful tool. It's not going to catch every use-case (people who use different variable names), but a simple rule like this will find all 5.x submit handlers and warn you to upgrade it. If you wanted to be more generic, you could write a rule that looked for two arguments instead of 3, but the regex for that is a little harder.

You can also restrict your regex searches within a function. So, if you wanted to warn about the recent menu changes:

    array(
      '#type' => 'regex',
      '#function' => '_menu$',
      '#value' => '\$items\[\]\s*=|if\s*\(\$may_cache\)',
    ),

This rule looks for $items[] = or if ($maycache).

Quoted strings are replaced with '' in the php source (the default, but see below). Thus if you wanted to make sure that the above had a string array index (such as $items['something'] =, you could have written (BTW, this is a bogus example just to show quoted strings):

    array(
      '#type' => 'regex',
      '#value' => '\$items\[\'\'\]\s*=',
    ),

Rule warnings

Finding code patterns is only half the problem. You also need to write a warning. There are two warning options,

  1. #warning
  2. #warning_callback

So, using the first example above, we should add a warning

      '#value' => '_submit\s*\(\$form_id,',
      '#warning' => t('hook_submit() parameters have changed'),

Notice that this warning uses t for text processing. Since this function takes processing time, and since the rules files are read a lot, there also exists a warning_callback that should be used in most cases. So, the above really should be:

      '#value' => '_submit\s*\(\$form_id,',
      '#warning_callback' => '_coder_6x_fapi_submit_warning',
...
  functions _coder_6x_fapi_submit_warning() {
    return t('!hook_submit() parameters have changed',
      array(
        '!hook_submit' => theme('drupalapi', 'hook_submit'),
      )
    );
  }

Warning Callbacks

Warning callbacks support either a text string or an array. If an array is returned, it should contain:

  • #warning - this is the same as the simple text string (or #warning in the rule)
  • #description - a more detailed description. if supplied, the user can click on the down-arrow icon and receive more information about this warning
  • #link - link to more Detailed documentation, usually on d.o.

Available source options

Usually, you're just looking for something in the php. But coder supports these #source options:

  • php - this is the default
  • html - anything not inside <?php ... ?>, but also looks for html tags inside quotes.
  • all - any line in the source. this is sometimes needed to override the default quote and/or comment handling.
  • quote - anything inside a single (') or double-quote (")
  • doublequote - anything inside a double-quote (")
  • comment - anything inside a comment, including the leading and trailing comment

So, for example, if you want to look for the string "hello world" (inside a doublequote), you can use the following:

    array(
      '#type' => 'regex',
      '#value' => 'hello world',
      '#source' => 'doublequote',
    ),

It should be noted that there isn't a 'comment' option and there probably should be. The only way to search for comments is to use '#source' option 'all'. Otherwise, all comments are stripped.

Other rules options

  • #case-sensitive - pattern matching ignores case by default. Use this to for case sensitive matching. This is needed for camelCase and capitalization rules.
  • #not - to make pattern matching rules simpler, use this to exclude matched values
  • #severity - severity (minor, normal, critical) controls the color and icons displayed. values defined here over-ride values set in the review
 
 

Drupal is a registered trademark of Dries Buytaert.