coder_review.drush.inc in Coder 7
Same filename and directory in other branches
Command line utility for coder_review.
File
coder_review/coder_review.drush.incView source
<?php
/**
* @file
* Command line utility for coder_review.
*/
/**
* Implements hook_drush_help().
*/
function coder_review_drush_help($section) {
switch ($section) {
case 'drush:coder-review':
return dt("usage: drush coder-review [options] [severity] [review] [what]" . "\n options:" . "\n summary - display summary information only, no warning output" . "\n no-empty - hide results that are empty" . "\n xml - output results as xml" . "\n checkstyle - output results in Checkstyle xml format" . "\n severity: show warnings at or above severity level" . "\n major|minor|critical" . "\n review: one or more reviews" . "\n upgrade7x|comment|i18n|security|sql|style" . "\n * style is the default" . "\n what:" . "\n all - review all modules and themes" . "\n * this is the default if nothing is explicitly specified" . "\n active - review all active modules and themes" . "\n core - review all of core, modules, themes, and includes" . "\n contrib - review all non-core modules" . "\n default - review 'default' modules and themes, as defined by settings" . "\n <name> - review specified module or theme name, i.e. taxonomy" . "\n no-<name> - exclude named modules and themes, i.e. no-taxonomy" . "\n combine with active|core|contrib|all|default" . "\n <patch-url> - URL to patch file" . "\n <file-path> - path to file or multiple files, relative to Drupal installation");
}
}
/**
* Implements hook_drush_command().
*/
function coder_review_drush_command() {
$items['coder-review'] = array(
'callback' => 'coder_review_drush_review',
'description' => dt('Run code reviews'),
'drupal dependencies' => array(
'coder_review',
),
'bootstrap' => DRUSH_BOOTSTRAP_DRUSH,
'aliases' => array(
'coder',
'review',
'lint',
),
);
return $items;
}
function _coder_review_set_form_modules(&$settings) {
if (isset($settings['coder_modules'])) {
foreach ($settings['coder_modules'] as $key => $value) {
if ($value == 1) {
$settings['coder_modules-' . $key] = 1;
}
}
unset($settings['coder_modules']);
}
}
/**
* Do the actual review.
*/
function coder_review_drush_review() {
_coder_review_drush_set_option('drush');
// Check for drush style options.
foreach (array(
'summary',
'no-empty',
'xml',
'checkstyle',
) as $option) {
if (drush_get_option($option)) {
_coder_review_drush_set_option($arg);
}
}
$severity = drush_get_option('severity', '');
foreach (array(
'major',
'minor',
'critical',
) as $option) {
if (drush_get_option($option)) {
$severity_name = $option;
}
}
foreach (array(
'active',
'core',
'contrib',
'all',
'default',
) as $option) {
if (drush_get_option($option)) {
$settings = _coder_review_get_default_settings($option);
$settings['coder_includes'] = TRUE;
}
}
// Process command line arguments.
$args = func_get_args();
$reviews = array();
$modules = array();
$output = array();
$settings = _coder_review_get_default_settings();
if (count($args)) {
$avail_reviews = _coder_review_reviews();
foreach ($args as $arg) {
switch ($arg) {
case 'summary':
case 'no-empty':
case 'xml':
case 'checkstyle':
_coder_review_drush_set_option($arg);
break;
case 'active':
case 'core':
case 'contrib':
case 'all':
case 'default':
$settings = _coder_review_get_default_settings($arg);
$settings['coder_includes'] = TRUE;
break;
case 'major':
case 'minor':
case 'critical':
$severity_name = $arg;
break;
default:
if (isset($avail_reviews[$arg])) {
$reviews[$arg] = $arg;
}
elseif (drupal_substr($arg, 0, 3) == 'no-') {
_coder_review_set_form_modules($settings);
unset($settings['coder_modules-' . drupal_substr($arg, 3)]);
}
elseif (strpos($arg, '*') !== FALSE || strpos($arg, '%') !== FALSE) {
$result = db_query('SELECT name FROM {system} WHERE name LIKE :name', array(
':name' => str_replace('*', '%', $arg),
));
foreach ($result as $system) {
$settings['coder_modules-' . $system->name] = 1;
$match = TRUE;
}
if (!isset($match)) {
_coder_review_drush_print(dt('no matches found for @name', array(
'@name' => $arg,
)));
return;
}
unset($settings['coder_active_modules']);
unset($settings['coder_core']);
unset($settings['coder_all']);
unset($settings['coder_modules']);
$settings['coder_includes'] = TRUE;
}
else {
$root = drupal_realpath('.');
if (_coder_review_drush_is_patch_arg($arg, $root)) {
$settings['coder_patches'] = 1;
$settings['coder_patch_link'] = $arg;
}
else {
$path = preg_replace(",^{$root}/,", '', $_SERVER['OLDPWD'] . '/' . $arg);
if (file_exists($path)) {
$settings['coder_files'] = 1;
if (empty($settings['coder_file_list'])) {
$settings['coder_file_list'] = '';
}
if (is_dir($path)) {
$ext = variable_get('coder_review_php_ext', array(
'inc',
'php',
'install',
'test',
));
$settings['coder_file_list'] .= implode("\n", array_keys(drupal_system_listing('/\\.(' . implode('|', $ext) . ')$/', $path, 'filepath', 0)));
}
else {
$settings['coder_file_list'] .= $path . "\n";
}
}
else {
$settings['coder_modules-' . $arg] = 1;
$settings['coder_includes'] = TRUE;
}
}
unset($settings['coder_active_modules']);
unset($settings['coder_core']);
unset($settings['coder_all']);
unset($settings['coder_modules']);
}
break;
}
}
if (_coder_review_drush_is_option('checkstyle')) {
_coder_review_drush_xml_output_header('checkstyle');
}
elseif (_coder_review_drush_is_option('xml')) {
_coder_review_drush_xml_output_header('xml');
}
if (!empty($severity_name)) {
if (_coder_review_drush_is_option('xml')) {
_coder_review_drush_xml_output_severity($severity_name);
}
$output[] = dt('Severity @severity_name', array(
'@severity_name' => $severity_name,
));
$settings['coder_severity'] = _coder_review_severity($severity_name);
}
if (count($reviews)) {
if (_coder_review_drush_is_option('xml') && !_coder_review_drush_is_option('checkstyle')) {
_coder_review_drush_xml_output_reviews($reviews, $avail_reviews);
}
else {
foreach ($reviews as $review) {
$output[] = $avail_reviews[$review]['#title'];
}
}
$settings['coder_reviews'] = $reviews;
}
if (count($output) && !_coder_review_drush_is_option('summary') && !_coder_review_drush_is_option('xml') && !_coder_review_drush_is_option('checkstyle')) {
_coder_review_drush_print(implode(', ', $output) . "\n");
}
}
_coder_review_set_form_modules($settings);
$settings['op'] = 'drush';
$form_state['storage'] = $settings;
coder_review_page_form(array(), $form_state);
if (_coder_review_drush_is_option('checkstyle')) {
_coder_review_drush_xml_output_footer('checkstyle');
}
elseif (_coder_review_drush_is_option('xml')) {
_coder_review_drush_xml_output_footer('xml');
}
}
/**
* Handle patch reviews.
*/
function _coder_review_drush_is_patch_arg(&$arg, $root) {
if (drupal_substr($arg, 0, 7) == 'http://') {
return TRUE;
}
if (preg_match('/\\.(patch|diff|tmp)$/', $arg)) {
if (isset($_SERVER['OLDPWD'])) {
$path = preg_replace(",^{$root}/,", '', $_SERVER['OLDPWD'] . '/' . $arg);
if (is_file($path)) {
$arg = $path;
return TRUE;
}
}
}
}
/**
* Theme printing of results and filenames.
*/
function theme_drush_coder_review($variables) {
$name = $variables['name'];
$filename = $variables['filename'];
$results = $variables['results'];
if (!_coder_review_drush_is_option('summary') && !empty($results) && (count($results) && !isset($results[0]) || !_coder_review_drush_is_option('no-empty'))) {
if (_coder_review_drush_is_option('checkstyle') || _coder_review_drush_is_option('xml')) {
_coder_review_drush_xml_output_results($filename, $results);
}
else {
_coder_review_drush_print($filename . ":\n " . implode("\n ", $results) . "\n");
}
}
}
/**
* Theme warning message, including source snippet.
*/
function theme_drush_coder_review_warning($variables) {
$warning = $variables['warning'];
$severity_name = $variables['severity_name'];
$lineno = isset($variables['lineno']) ? $variables['lineno'] : 0;
$line = isset($variables['line']) ? $variables['line'] : '';
$checkstyle_levels = array(
'minor' => 'info',
'normal' => 'warning',
'critical' => 'error',
);
if (_coder_review_drush_is_option('xml') || _coder_review_drush_is_option('checkstyle')) {
$attr = array(
'line' => $lineno,
'column' => 0,
'severity' => $severity_name,
'message' => $warning,
'source' => $line,
);
if (_coder_review_drush_is_option('checkstyle')) {
$attr['severity'] = $checkstyle_levels[$severity_name];
}
$output = '<error ' . drupal_attributes($attr) . ' />';
return $output;
}
else {
$output = $lineno ? '+' . $lineno . ': ' : '';
$output .= '[' . $severity_name . '] ';
$output .= is_array($warning) ? $warning['#warning'] : $warning;
return _coder_review_drush_output($output);
}
}
/**
* Handle printing of drupal_set_message() messages.
*/
function coder_review_print_drush_messages() {
foreach (drupal_get_messages() as $type => $messages) {
$output = _coder_review_drush_output(implode("\n ", $messages));
if (_coder_review_drush_is_option('xml') && !_coder_review_drush_is_option('checkstyle')) {
_coder_review_drush_print('<status type="' . $type . '">' . $output . '</status>');
}
elseif (!_coder_review_drush_is_option('checkstyle')) {
_coder_review_drush_print(dt(drupal_ucfirst($type) . ' Messages') . ":\n " . $output . "\n");
}
}
}
/**
* Strip HTML tags from drush output.
*/
function _coder_review_drush_output($output) {
return html_entity_decode(strip_tags($output));
}
/**
* Helper function to set a command line option.
*/
function _coder_review_drush_set_option($option) {
global $_coder_drush_options;
if (!isset($_coder_drush_options)) {
$_coder_drush_options = array();
}
$_coder_drush_options[$option] = TRUE;
}
/**
* Helper function to determine if an option is set.
*/
function _coder_review_drush_is_option($option) {
global $_coder_drush_options;
return isset($_coder_drush_options[$option]);
}
/**
* Switch between print and pipe print output.
*/
function _coder_review_drush_print($message) {
if (drush_get_context('DRUSH_PIPE')) {
drush_print_pipe($message);
}
else {
drush_print($message);
}
}
/**
* XML output functions.
*/
/**
* XML: output appropriate header tag.
*/
function _coder_review_drush_xml_output_header($type = 'xml') {
// Put in an extra concatenation so syntax highlighting in vim doesn't break.
_coder_review_drush_print('<?xml version="1.0" encoding="UTF-8"?' . '>');
switch ($type) {
case 'checkstyle':
_coder_review_drush_print('<checkstyle version="1.3.0RC1">');
break;
case 'xml':
default:
_coder_review_drush_print('<coderreview version="1.1">');
break;
}
}
/**
* XML: output appropriate footer tag.
*/
function _coder_review_drush_xml_output_footer($type = 'xml') {
switch ($type) {
case 'checkstyle':
_coder_review_drush_print('</checkstyle>');
break;
case 'xml':
default:
_coder_review_drush_print('</coderreview>');
break;
}
}
/**
* XML: output severity level if provided.
*/
function _coder_review_drush_xml_output_severity($severity_name) {
_coder_review_drush_print('<severity>' . $severity_name . '</severity>');
}
/**
* XML: output list of chosen reviews.
*/
function _coder_review_drush_xml_output_reviews($reviews, $avail_reviews) {
_coder_review_drush_print('<reviews>');
foreach ($reviews as $review) {
_coder_review_drush_print('<review>' . $avail_reviews[$review]['#title'] . '</review>');
}
_coder_review_drush_print('</reviews>');
}
/**
* XML: output filename and its results (if any).
*/
function _coder_review_drush_xml_output_results($filename, $results) {
if (empty($results) || count($results) == 1 && isset($results[0])) {
_coder_review_drush_print('<file name = "' . $filename . '" />');
}
else {
_coder_review_drush_print('<file name = "' . $filename . '">' . "\n" . implode("\n ", $results) . "\n" . '</file>');
}
}
Functions
Name | Description |
---|---|
coder_review_drush_command | Implements hook_drush_command(). |
coder_review_drush_help | Implements hook_drush_help(). |
coder_review_drush_review | Do the actual review. |
coder_review_print_drush_messages | Handle printing of drupal_set_message() messages. |
theme_drush_coder_review | Theme printing of results and filenames. |
theme_drush_coder_review_warning | Theme warning message, including source snippet. |
_coder_review_drush_is_option | Helper function to determine if an option is set. |
_coder_review_drush_is_patch_arg | Handle patch reviews. |
_coder_review_drush_output | Strip HTML tags from drush output. |
_coder_review_drush_print | Switch between print and pipe print output. |
_coder_review_drush_set_option | Helper function to set a command line option. |
_coder_review_drush_xml_output_footer | XML: output appropriate footer tag. |
_coder_review_drush_xml_output_header | XML: output appropriate header tag. |
_coder_review_drush_xml_output_results | XML: output filename and its results (if any). |
_coder_review_drush_xml_output_reviews | XML: output list of chosen reviews. |
_coder_review_drush_xml_output_severity | XML: output severity level if provided. |
_coder_review_set_form_modules |