/** * Get a list of folders to ignores. * @return array of paths. */ function local_codesniffer_get_ignores() { global $CFG; $paths = array(); $thirdparty = simplexml_load_file($CFG->libdir . '/thirdpartylibs.xml'); foreach ($thirdparty->xpath('/libraries/library/location') as $lib) { $paths[] = preg_quote(local_codechecker_clean_path('/lib/' . $lib)); } $paths[] = preg_quote(local_codechecker_clean_path('/local/codechecker' . DIRECTORY_SEPARATOR . 'pear')); return $paths; }
* @package local_codechecker * @copyright 2011 The Open University * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ define('CLI_SCRIPT', true); require dirname(__FILE__) . '/../../config.php'; require_once $CFG->libdir . '/clilib.php'; require_once $CFG->dirroot . '/local/codechecker/locallib.php'; // Get the command-line options. list($options, $unrecognized) = cli_get_params(array('help' => false, 'interactive' => false), array('h' => 'help', 'i' => 'interactive')); if (count($unrecognized) != 1) { $options['help'] = true; } else { $path = clean_param(reset($unrecognized), PARAM_PATH); } if ($options['help']) { echo get_string('clihelp', 'local_codechecker'), "\n"; die; } $interactive = false; if ($options['interactive']) { $interactive = true; } raise_memory_limit(MEMORY_HUGE); $standard = $CFG->dirroot . str_replace('/', DIRECTORY_SEPARATOR, '/local/codechecker/moodle'); $cli = new local_codechecker_codesniffer_cli(); $phpcs = new PHP_CodeSniffer(1, 0, 'utf-8', $interactive); $phpcs->setCli($cli); $phpcs->setIgnorePatterns(local_codesniffer_get_ignores()); $phpcs->process(local_codechecker_clean_path($CFG->dirroot . '/' . trim($path, '/')), local_codechecker_clean_path($standard)); $phpcs->reporting->printReport('full', false, $cli->getCommandLineValues(), null);
if ($path) { $fullpath = $CFG->dirroot . '/' . trim($path, '/'); if (!is_file($fullpath) && !is_dir($fullpath)) { $fullpath = null; } } $output = $PAGE->get_renderer('local_codechecker'); echo $OUTPUT->header(); if ($path) { if ($fullpath) { $phpcs = new PHP_CodeSniffer(); $phpcs->setCli(new local_codechecker_codesniffer_cli()); $phpcs->setIgnorePatterns(local_codesniffer_get_ignores()); $phpcs->process(local_codechecker_clean_path($fullpath), local_codechecker_clean_path($CFG->dirroot . '/local/codechecker/moodle')); $problems = $phpcs->getFilesErrors(); local_codechecker_check_other_files(local_codechecker_clean_path($fullpath), $problems); ksort($problems); $errors = 0; $warnings = 0; foreach ($problems as $file => $info) { $errors += $info['numErrors']; $warnings += $info['numWarnings']; } if ($errors + $warnings > 0) { $summary = get_string('numerrorswarnings', 'local_codechecker', array('numErrors' => $errors, 'numWarnings' => $warnings)); } else { $summary = ''; } echo $output->report($problems, $phpcs, $summary); } else { echo $output->invald_path_message($path);
/** * Get a list of folders to ignores. * * @param string $extraignorelist optional comma separated list of substring matching paths to ignore. * @return array of paths. */ function local_codesniffer_get_ignores($extraignorelist = '') { global $CFG; $files = array(); // XML files to be processed. $paths = array(); // Absolute paths to be excluded. $files['core'] = $CFG->libdir . DIRECTORY_SEPARATOR . '/thirdpartylibs.xml'; // This one always exists. // With MDL-42148, for 2.6 and upwards, the general 'thirdpartylibs.xml' file // has been split so any plugin with dependencies can have its own. In order to // keep master compatibility with older branches we are doing some // conditional coding here. if (file_exists($CFG->dirroot . '/' . $CFG->admin . '/' . 'thirdpartylibs.php')) { // New behavior, distributed XML files, let's look for them. $plugintypes = core_component::get_plugin_types(); foreach ($plugintypes as $type => $ignored) { $plugins = core_component::get_plugin_list_with_file($type, 'thirdpartylibs.xml', false); foreach ($plugins as $plugin => $path) { $files[$type . '_' . $plugin] = $path; } } } // Let's extract all the paths from the XML files. foreach ($files as $file) { $base = realpath(dirname($file)); $thirdparty = simplexml_load_file($file); foreach ($thirdparty->xpath('/libraries/library/location') as $location) { $location = substr($base, strlen($CFG->dirroot)) . '/' . $location; // This was happening since ages ago, leading to incorrect excluded // paths like: "/lib/theme/bootstrapbase/less/bootstrap", so we try // reducing it. Note this does not affect 2.6 and up, where all // locations are relative to their xml file so this problem cannot happen. if (!file_exists(dirname($CFG->dirroot . DIRECTORY_SEPARATOR . $location))) { // Only if it starts with '/lib'. if (strpos($location, DIRECTORY_SEPARATOR . 'lib') === 0) { $candidate = substr($location, strlen(DIRECTORY_SEPARATOR . 'lib')); // Only modify the original location if the candidate exists. if (file_exists(dirname($CFG->dirroot . DIRECTORY_SEPARATOR . $candidate))) { $location = $candidate; } } } // Accept only correct paths from XML files. if (file_exists(dirname($CFG->dirroot . DIRECTORY_SEPARATOR . $location))) { $paths[] = preg_quote(local_codechecker_clean_path($location)); } else { debugging("Processing {$file} for exclussions, incorrect {$location} path found. Please fix it"); } } } // Manually add our own pear stuff to be excluded. $paths[] = preg_quote(local_codechecker_clean_path('/local/codechecker' . DIRECTORY_SEPARATOR . 'pear')); // Changed in PHP_CodeSniffer 1.4.4 and upwards, so we apply the // same here: Paths go to keys and mark all them as 'absolute'. $finalpaths = array(); foreach ($paths as $pattern) { $finalpaths[$pattern] = 'absolute'; } // Let's add any substring matching path passed in $extraignorelist. if ($extraignorelist) { $extraignorearr = explode(',', $extraignorelist); foreach ($extraignorearr as $extraignore) { $extrapath = trim($extraignore); $finalpaths[$extrapath] = 'absolute'; } } return $finalpaths; }
$output = $PAGE->get_renderer('local_codechecker'); echo $OUTPUT->header(); if ($path) { if ($fullpath) { $reportfile = make_temp_directory('phpcs') . '/phpcs_' . random_string(10) . '.xml'; $phpcs = new PHP_CodeSniffer(); $cli = new local_codechecker_codesniffer_cli(); $cli->setReport('local_codechecker'); // Using own custom xml format for easier handling later. $cli->setReportFile($reportfile); // Send the report to dataroot temp. $phpcs->setCli($cli); $phpcs->setIgnorePatterns(local_codesniffer_get_ignores($exclude)); $phpcs->process(local_codechecker_clean_path($fullpath), local_codechecker_clean_path($CFG->dirroot . '/local/codechecker/moodle')); // Save the xml report file to dataroot/temp. $phpcs->reporting->printReport('local_codechecker', false, $reportfile); // Load the XML file to proceed with the rest of checks. $xml = simplexml_load_file($reportfile); // Look for other problems, not handled by codesniffer. local_codechecker_check_other_files(local_codechecker_clean_path($fullpath), $xml); list($numerrors, $numwarnings) = local_codechecker_count_problems($xml); // Output the results report. echo $output->report($xml, $numerrors, $numwarnings); // And clean the report temp file. @unlink($reportfile); } else { echo $output->invald_path_message($path); } } $mform->display(); echo $OUTPUT->footer();