Index: coder.module =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/coder/coder.module,v retrieving revision 1.88.2.32 diff -u -p -r1.88.2.32 coder.module --- coder.module 29 Mar 2008 23:55:19 -0000 1.88.2.32 +++ coder.module 8 May 2008 10:47:41 -0000 @@ -130,6 +130,13 @@ function coder_menu() { 'type' => MENU_LOCAL_TASK, 'weight' => 1, ); + $items['coder/patches'] = array( + 'title' => t('Patches'), + 'page callback' => 'coder_page', + 'access arguments' => array('view code review'), + 'type' => MENU_LOCAL_TASK, + 'weight' => 2, + ); $items['admin/settings/coder'] = array( 'title' => t('Code review'), 'description' => t('Select code review plugins and modules'), @@ -236,153 +243,211 @@ function _coder_settings_form($settings, '#default_value' => $settings['coder_severity'], ); - // Get the modules and theme. - $sql = 'SELECT name, filename, type, status FROM {system} WHERE type=\'module\' OR type=\'theme\' ORDER BY weight ASC, filename ASC'; - $result = db_query($sql); - $system_modules = array(); - $system_themes = array(); - while ($system = db_fetch_object($result)) { - $display_name = $system->name; - if ($system->status) { - $display_name .= t(' (active)'); - $system_active[$system->name] = $system->name; - } - if (_coder_is_drupal_core($system)) { - $display_name .= t(' (core)'); - $system_core[$system->name] = $system->name; - } - if ($system->type == 'module') { - $system_modules[$system->name] = $system->name; - } - else { - $system_themes[$system->name] = $system->name; + if ($settings['coder_patches']) { + // Display what to review options. + $form['coder_what'] = array( + '#type' => 'fieldset', + '#title' => t('What to review'), + '#collapsible' => true, + '#collapsed' => false, + ); + $form['coder_what']['coder_patch_text'] = array( + '#type' => 'textarea', + '#title' => t('Patch to review'), + '#rows' => 10, + '#weight' => -1, + '#default_value' => isset($settings['coder_patch_text']) ? $settings['coder_patch_text'] : '', + ); + $form['coder_patches'] = array( + '#type' => 'value', + '#value' => 1, + ); + + $in_patch = 0; + $patch_part = 1; + $patch = ''; + $patches = array(); + $lines = preg_split("/[\r\n|\n]/", $settings['coder_patch_text']); + foreach ($lines as $line) { + if ($line == '') { + continue; + } + if (preg_match("/^\+\+\+\s+([\w\.\-\/]+\s)/", $line, $matches)) { + $filename = $matches[1]; + } + else if (preg_match("/^(@@\s+\-\d+,\d+\s+\+\d+,\d+\s+@@)/", $line, $matches)) { + $patch_line_numbers = $matches[1]; + $patch_part = 1; + } + else if (preg_match("/^\+[^\+]+/", $line)) { + $patch .= ltrim($line, '+') ."\n"; + $in_patch = 1; + } + else { + if ($in_patch) { + $part = ''; + if ($patch_part > 1) { + $part = t(' (part @num)', array('@num' => $patch_part)); + } + $patches[$filename .": ". $patch_line_numbers . $part] = $patch; + $system[$filename .": ". $patch_line_numbers . $part] = $filename; + $patch = ''; + $patch_part++; + } + $in_patch = 0; + } } - $system_links[$system->name] = l($display_name, "coder/$system->name"); - $files[$system->name] = $system->filename; + $files = $patches; } - asort($system_links); + else { + // Get the modules and theme. + $sql = 'SELECT name, filename, type, status FROM {system} WHERE type=\'module\' OR type=\'theme\' ORDER BY weight ASC, filename ASC'; + $result = db_query($sql); + $system_modules = array(); + $system_themes = array(); + while ($system = db_fetch_object($result)) { + $display_name = $system->name; + if ($system->status) { + $display_name .= t(' (active)'); + $system_active[$system->name] = $system->name; + } + if (_coder_is_drupal_core($system)) { + $display_name .= t(' (core)'); + $system_core[$system->name] = $system->name; + } + if ($system->type == 'module') { + $system_modules[$system->name] = $system->name; + } + else { + $system_themes[$system->name] = $system->name; + } + $system_links[$system->name] = l($display_name, "coder/$system->name"); + $files[$system->name] = $system->filename; + } + asort($system_links); - // Display what to review options. - $form['coder_what'] = array( - '#type' => 'fieldset', - '#title' => t('What to review'), - '#collapsible' => true, - '#collapsed' => false, - ); - // NOTE: Should rename var. - $form['coder_what']['coder_active_modules'] = array( - '#type' => 'checkbox', - '#default_value' => isset($settings['coder_active_modules']) ? $settings['coder_active_modules'] : 0, - '#title' => t('active modules and themes'), - ); - $form['coder_what']['coder_core'] = array( - '#type' => 'checkbox', - '#default_value' => isset($settings['coder_core']) ? $settings['coder_core'] : 0, - '#title' => t('core files (php, modules, and includes)'), - ); - $form['coder_what']['coder_includes'] = array( - '#type' => 'checkbox', - '#default_value' => isset($settings['coder_includes']) ? $settings['coder_includes'] : 0, - '#title' => t('include files (.inc and .php files)'), - ); - if (arg(0) == 'admin') { - $form['coder_what']['coder_cache'] = array( + // Display what to review options. + $form['coder_what'] = array( + '#type' => 'fieldset', + '#title' => t('What to review'), + '#collapsible' => true, + '#collapsed' => false, + ); + // NOTE: Should rename var. + $form['coder_what']['coder_active_modules'] = array( '#type' => 'checkbox', - '#default_value' => isset($settings['coder_cache']) ? $settings['coder_cache'] : 0, - '#title' => t('use the coder cache'), + '#default_value' => isset($settings['coder_active_modules']) ? $settings['coder_active_modules'] : 0, + '#title' => t('active modules and themes'), ); - } + $form['coder_what']['coder_core'] = array( + '#type' => 'checkbox', + '#default_value' => isset($settings['coder_core']) ? $settings['coder_core'] : 0, + '#title' => t('core files (php, modules, and includes)'), + ); + $form['coder_what']['coder_includes'] = array( + '#type' => 'checkbox', + '#default_value' => isset($settings['coder_includes']) ? $settings['coder_includes'] : 0, + '#title' => t('include files (.inc and .php files)'), + ); + if (arg(0) == 'admin') { + $form['coder_what']['coder_cache'] = array( + '#type' => 'checkbox', + '#default_value' => isset($settings['coder_cache']) ? $settings['coder_cache'] : 0, + '#title' => t('use the coder cache'), + ); + } - // Display the modules in a fieldset. - $form['coder_what']['coder_modules'] = array( - '#type' => 'fieldset', - '#title' => t('Select Specific Modules'), - '#collapsible' => true, - '#collapsed' => true, - 'checkboxes' => array( - '#theme' => 'cols', - '#cols' => 2, - ), - ); - if (isset($settings['coder_all'])) { - $modules = $system_modules; - } - elseif (isset($settings['coder_active_modules']) && $settings['coder_active_modules']) { - if (isset($settings['coder_core']) && $settings['coder_core']) { - $modules = array_intersect($system_active, $system_core); - $modules = array_intersect($modules, $system_modules); + // Display the modules in a fieldset. + $form['coder_what']['coder_modules'] = array( + '#type' => 'fieldset', + '#title' => t('Select Specific Modules'), + '#collapsible' => true, + '#collapsed' => true, + 'checkboxes' => array( + '#theme' => 'cols', + '#cols' => 2, + ), + ); + if (isset($settings['coder_all'])) { + $modules = $system_modules; } - else { - $modules = array_intersect($system_active, $system_modules); + elseif (isset($settings['coder_active_modules']) && $settings['coder_active_modules']) { + if (isset($settings['coder_core']) && $settings['coder_core']) { + $modules = array_intersect($system_active, $system_core); + $modules = array_intersect($modules, $system_modules); + } + else { + $modules = array_intersect($system_active, $system_modules); + } } - } - elseif (isset($settings['coder_core']) && $settings['coder_core']) { - $modules = array_intersect($system_core, $system_modules); - } - elseif (isset($settings['coder_active_modules']) && $settings['coder_active_modules']) { - $modules = array_intersect($system_active, $system_modules); - } - else { - $modules = isset($settings['coder_modules']) && is_array($settings['coder_modules']) ? $settings['coder_modules'] : array(); - } - - // Display the themes in a fieldset. - $form['coder_what']['coder_themes'] = array( - '#type' => 'fieldset', - '#title' => t('Select Specific Themes'), - '#collapsible' => true, - '#collapsed' => true, - 'checkboxes' => array( - '#theme' => 'cols', - ), - ); - if (isset($settings['coder_all'])) { - $themes = $system_themes; - } - elseif (isset($settings['coder_active_modules']) && $settings['coder_active_modules']) { - if (isset($settings['coder_core']) && $settings['coder_core']) { - $themes = array_intersect($system_active, $system_core); - $themes = array_intersect($themes, $system_themes); + elseif (isset($settings['coder_core']) && $settings['coder_core']) { + $modules = array_intersect($system_core, $system_modules); + } + elseif (isset($settings['coder_active_modules']) && $settings['coder_active_modules']) { + $modules = array_intersect($system_active, $system_modules); } else { - $themes = array_intersect($system_active, $system_themes); + $modules = isset($settings['coder_modules']) && is_array($settings['coder_modules']) ? $settings['coder_modules'] : array(); } - } - elseif (isset($settings['coder_core']) && $settings['coder_core']) { - $themes = array_intersect($system_core, $system_themes); - } - elseif (isset($settings['coder_active_modules']) && $settings['coder_active_modules']) { - $themes = array_intersect($system_active, $system_themes); - } - else { - $themes = isset($settings['coder_themes']) && is_array($settings['coder_themes']) ? $settings['coder_themes'] : array(); - } - foreach ($system_links as $name => $link) { - $classes = array(); - if (in_array($name, $system_active)) { - $classes[] = 'coder-active'; + // Display the themes in a fieldset. + $form['coder_what']['coder_themes'] = array( + '#type' => 'fieldset', + '#title' => t('Select Specific Themes'), + '#collapsible' => true, + '#collapsed' => true, + 'checkboxes' => array( + '#theme' => 'cols', + ), + ); + if (isset($settings['coder_all'])) { + $themes = $system_themes; + } + elseif (isset($settings['coder_active_modules']) && $settings['coder_active_modules']) { + if (isset($settings['coder_core']) && $settings['coder_core']) { + $themes = array_intersect($system_active, $system_core); + $themes = array_intersect($themes, $system_themes); + } + else { + $themes = array_intersect($system_active, $system_themes); + } } - if (in_array($name, $system_core)) { - $classes[] = 'coder-core'; + elseif (isset($settings['coder_core']) && $settings['coder_core']) { + $themes = array_intersect($system_core, $system_themes); } - if (in_array($name, $system_themes)) { - $type = 'theme'; - $default_value = isset($themes[$name]); + elseif (isset($settings['coder_active_modules']) && $settings['coder_active_modules']) { + $themes = array_intersect($system_active, $system_themes); } else { - $type = 'module'; - $default_value = isset($modules[$name]); + $themes = isset($settings['coder_themes']) && is_array($settings['coder_themes']) ? $settings['coder_themes'] : array(); + } + + foreach ($system_links as $name => $link) { + $classes = array(); + if (in_array($name, $system_active)) { + $classes[] = 'coder-active'; + } + if (in_array($name, $system_core)) { + $classes[] = 'coder-core'; + } + if (in_array($name, $system_themes)) { + $type = 'theme'; + $default_value = isset($themes[$name]); + } + else { + $type = 'module'; + $default_value = isset($modules[$name]); + } + $form['coder_what']["coder_${type}s"]['checkboxes']["coder_${type}s-$name"] = array( + '#type' => 'checkbox', + '#title' => $link, + '#default_value' => $default_value, + '#attributes' => array('class' => implode(' ', $classes)), + ); } - $form['coder_what']["coder_${type}s"]['checkboxes']["coder_${type}s-$name"] = array( - '#type' => 'checkbox', - '#title' => $link, - '#default_value' => $default_value, - '#attributes' => array('class' => implode(' ', $classes)), - ); - } - $system = array_merge($modules, $themes); + $system = array_merge($modules, $themes); + } return $form; } @@ -516,6 +581,10 @@ function _coder_get_default_settings($ar $settings['coder_all'] = 1; break; + case 'patches': + $settings['coder_patches'] = 1; + break; + case 'default': $settings['coder_active_modules'] = variable_get('coder_active_modules', 1); $settings['coder_core'] = variable_get('coder_core', 0); @@ -611,6 +680,7 @@ function coder_page_form($form_state) { // Used to avoid duplicate includes. $dups = array(); $stats = array(); + $patch = ''; foreach ($system as $name => $checked) { if ($checked) { // Process this one file. @@ -619,10 +689,15 @@ function coder_page_form($form_state) { drupal_set_message(t('Code Review file for %module not found', array('%module' => $name))); continue; } + if ($settings['coder_patches']) { + $patch = $filename; + $filename = $name; + } $coder_args = array( '#reviews' => $reviews, '#severity' => $settings['coder_severity'], '#filename' => $filename, + '#patch' => $patch, ); $results = do_coder_reviews($coder_args); $stats[$filename] = $results['#stats']; @@ -679,8 +754,13 @@ function coder_page_form($form_state) { $summary['files'] ++; } $display = array(); - $display[] = t('Coder found @count projects', array('@count' => count($stats))); - $display[] = t('@count files', array('@count' => $summary['files'])); + if ($settings['coder_patches']) { + $display[] = t('Coder found @count patches', array('@count' => count($stats))); + } + else { + $display[] = t('Coder found @count projects', array('@count' => count($stats))); + $display[] = t('@count files', array('@count' => $summary['files'])); + } foreach (array('critical', 'normal', 'minor') as $severity_name) { if ($summary[$severity_name] > 0) { $display[] = t('@count %severity_name warnings', array('@count' => $summary[$severity_name], '%severity_name' => $severity_name)); @@ -792,6 +872,7 @@ function _coder_modified() { * - '#reviews' => array list of reviews to perform, see _coder_reviews(); * - '#severity' => integer magic number, see constants SEVERITY_*; * - '#filename' => string filename to check, + * - '#patch' => string patch lines to check, * @return * Array of results, in form: * - '#stats' => Array with error counts for all severities, in form @@ -800,7 +881,7 @@ function _coder_modified() { * - integer ID => HTML error for display. */ function do_coder_reviews($coder_args) { - if ($use_cache = variable_get('coder_cache', 1)) { + if ($use_cache = variable_get('coder_cache', 1) && empty($coder_args['#patch'])) { // Load the cached results if they exist. $cache_key = 'coder:'. implode(':', array_keys($coder_args['#reviews'])) . $coder_args['#severity'] .':'. $coder_args['#filename']; $cache_mtime = filemtime(realpath($coder_args['#filename'])); @@ -867,15 +948,22 @@ function do_coder_reviews($coder_args) { */ function _coder_read_and_parse_file(&$coder_args) { // Get the path to the module file. - if ($filepath = realpath($coder_args['#filename'])) { - // Read the file. - $content = file_get_contents($filepath) ."\n"; + if (!empty($coder_args['#patch']) || $filepath = realpath($coder_args['#filename'])) { + $in_php = 0; + $in_allphp = 0; + + if (empty($coder_args['#patch'])) { + $content = file_get_contents($filepath) ."\n"; + } + else { + $content = $coder_args['#patch']; + $in_php = 1; + $in_allphp = 1; + } $content_length = drupal_strlen($content); $in_comment = 0; $beginning_of_line = 0; - $in_php = 0; - $in_allphp = 0; $in_quote_html = 0; $in_backslash = 0; $in_quote = 0;