Last updated December 4, 2011. Created by LeeHunter on May 15, 2007.
Edited by Dane Powell, superbaloo, slothario, douggreen. Log in to edit this page.
Coder is the code review module. The name coder has a double meaning: a "coder" is obviously someone who writes code, and "code-r" is 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,
- #warning
- #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
- allphp - similar to php option, but also includes full quotes
- 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
- #never - never match lines that also contain this regex (uses #source = all)
- #severity - severity (minor, normal, critical) controls the color and icons displayed. values defined here over-ride values set in the review
- #filename - apply this rule to files whose filename matches a regex
- #filename-not - apply this rule to files whose filename does not match a regex
Ignore warnings
If coder review returns warnings, you may ignore them. This requires the patch at http://drupal.org/node/1360744.
- First, implement hook_coder_ignore() :
<?php
/**
* Implements hook_coder_ignore().
*/
function my_module_coder_ignore() {
return array(
'path' => drupal_get_path('module', 'my_module'),
'line prefix' => drupal_get_path('module', 'my_module'),
);
}
?>
This hook defines the path to the file my_module.coder_ignores.txt. - Then create file my_module.coder_ignores.txt in the root of your module if you use the hook defines in point 1 or anywhere else, feel free to adapt the hook response.
The my_module.coder_ignores.txt should look like this :
; Comments goes after semi-colons
; The file should be formatted this way :
; file:line:warning-type
; ex :
my_module.module:10:security
; This line ignores security warning on line 10 of file my_module.module
; Other options for warning-type are sql, comment, etc...
Comments
coder ignores file does not use warning-level but review type
Above is written:
However, it seems like it's not the warning level (which I interpret as the level of the error that is mentioned in the report, e.g. [normal], [critical], ...) that needs to be specified, but instead you need to use the type of review to which the rules that failed belongs to (e.g. security, style, sql, i18n etc.)
No real examples for ignores?
I'm struggling to find examples of working coder ignore files. The core one is clearly an exception (IIRC, coder doesn't implement hook_coder_ignore for it).
I really wish someone would add an example to the Examples project.
Meanwhile, can someone point me towards a module implementing hook_coder_ignore?