annotate vendor/squizlabs/php_codesniffer/CodeSniffer/Reporting.php @ 0:c75dbcec494b

Initial commit from drush-created site
author Chris Cannam
date Thu, 05 Jul 2018 14:24:15 +0000
parents
children
rev   line source
Chris@0 1 <?php
Chris@0 2 /**
Chris@0 3 * A class to manage reporting.
Chris@0 4 *
Chris@0 5 * PHP version 5
Chris@0 6 *
Chris@0 7 * @category PHP
Chris@0 8 * @package PHP_CodeSniffer
Chris@0 9 * @author Gabriele Santini <gsantini@sqli.com>
Chris@0 10 * @author Greg Sherwood <gsherwood@squiz.net>
Chris@0 11 * @copyright 2009-2014 SQLI <www.sqli.com>
Chris@0 12 * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
Chris@0 13 * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
Chris@0 14 * @link http://pear.php.net/package/PHP_CodeSniffer
Chris@0 15 */
Chris@0 16
Chris@0 17 /**
Chris@0 18 * A class to manage reporting.
Chris@0 19 *
Chris@0 20 * @category PHP
Chris@0 21 * @package PHP_CodeSniffer
Chris@0 22 * @author Gabriele Santini <gsantini@sqli.com>
Chris@0 23 * @author Greg Sherwood <gsherwood@squiz.net>
Chris@0 24 * @copyright 2009-2014 SQLI <www.sqli.com>
Chris@0 25 * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
Chris@0 26 * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
Chris@0 27 * @version Release: @package_version@
Chris@0 28 * @link http://pear.php.net/package/PHP_CodeSniffer
Chris@0 29 */
Chris@0 30 class PHP_CodeSniffer_Reporting
Chris@0 31 {
Chris@0 32
Chris@0 33 /**
Chris@0 34 * Total number of files that contain errors or warnings.
Chris@0 35 *
Chris@0 36 * @var int
Chris@0 37 */
Chris@0 38 public $totalFiles = 0;
Chris@0 39
Chris@0 40 /**
Chris@0 41 * Total number of errors found during the run.
Chris@0 42 *
Chris@0 43 * @var int
Chris@0 44 */
Chris@0 45 public $totalErrors = 0;
Chris@0 46
Chris@0 47 /**
Chris@0 48 * Total number of warnings found during the run.
Chris@0 49 *
Chris@0 50 * @var int
Chris@0 51 */
Chris@0 52 public $totalWarnings = 0;
Chris@0 53
Chris@0 54 /**
Chris@0 55 * Total number of errors/warnings that can be fixed.
Chris@0 56 *
Chris@0 57 * @var int
Chris@0 58 */
Chris@0 59 public $totalFixable = 0;
Chris@0 60
Chris@0 61 /**
Chris@0 62 * When the PHPCS run started.
Chris@0 63 *
Chris@0 64 * @var float
Chris@0 65 */
Chris@0 66 public static $startTime = 0;
Chris@0 67
Chris@0 68 /**
Chris@0 69 * A list of reports that have written partial report output.
Chris@0 70 *
Chris@0 71 * @var array
Chris@0 72 */
Chris@0 73 private $_cachedReports = array();
Chris@0 74
Chris@0 75 /**
Chris@0 76 * A cache of report objects.
Chris@0 77 *
Chris@0 78 * @var array
Chris@0 79 */
Chris@0 80 private $_reports = array();
Chris@0 81
Chris@0 82 /**
Chris@0 83 * A cache of opened tmp files.
Chris@0 84 *
Chris@0 85 * @var array
Chris@0 86 */
Chris@0 87 private $_tmpFiles = array();
Chris@0 88
Chris@0 89
Chris@0 90 /**
Chris@0 91 * Produce the appropriate report object based on $type parameter.
Chris@0 92 *
Chris@0 93 * @param string $type The type of the report.
Chris@0 94 *
Chris@0 95 * @return PHP_CodeSniffer_Report
Chris@0 96 * @throws PHP_CodeSniffer_Exception If report is not available.
Chris@0 97 */
Chris@0 98 public function factory($type)
Chris@0 99 {
Chris@0 100 $type = ucfirst($type);
Chris@0 101 if (isset($this->_reports[$type]) === true) {
Chris@0 102 return $this->_reports[$type];
Chris@0 103 }
Chris@0 104
Chris@0 105 if (strpos($type, '.') !== false) {
Chris@0 106 // This is a path to a custom report class.
Chris@0 107 $filename = realpath($type);
Chris@0 108 if ($filename === false) {
Chris@0 109 echo 'ERROR: Custom report "'.$type.'" not found'.PHP_EOL;
Chris@0 110 exit(2);
Chris@0 111 }
Chris@0 112
Chris@0 113 $reportClassName = 'PHP_CodeSniffer_Reports_'.basename($filename);
Chris@0 114 $reportClassName = substr($reportClassName, 0, strpos($reportClassName, '.'));
Chris@0 115 include_once $filename;
Chris@0 116 } else {
Chris@0 117 $filename = $type.'.php';
Chris@0 118 $reportClassName = 'PHP_CodeSniffer_Reports_'.$type;
Chris@0 119 if (class_exists($reportClassName, true) === false) {
Chris@0 120 echo 'ERROR: Report type "'.$type.'" not found'.PHP_EOL;
Chris@0 121 exit(2);
Chris@0 122 }
Chris@0 123 }//end if
Chris@0 124
Chris@0 125 $reportClass = new $reportClassName();
Chris@0 126 if (false === ($reportClass instanceof PHP_CodeSniffer_Report)) {
Chris@0 127 throw new PHP_CodeSniffer_Exception('Class "'.$reportClassName.'" must implement the "PHP_CodeSniffer_Report" interface.');
Chris@0 128 }
Chris@0 129
Chris@0 130 $this->_reports[$type] = $reportClass;
Chris@0 131 return $this->_reports[$type];
Chris@0 132
Chris@0 133 }//end factory()
Chris@0 134
Chris@0 135
Chris@0 136 /**
Chris@0 137 * Actually generates the report.
Chris@0 138 *
Chris@0 139 * @param PHP_CodeSniffer_File $phpcsFile The file that has been processed.
Chris@0 140 * @param array $cliValues An array of command line arguments.
Chris@0 141 *
Chris@0 142 * @return void
Chris@0 143 */
Chris@0 144 public function cacheFileReport(PHP_CodeSniffer_File $phpcsFile, array $cliValues)
Chris@0 145 {
Chris@0 146 if (isset($cliValues['reports']) === false) {
Chris@0 147 // This happens during unit testing, or any time someone just wants
Chris@0 148 // the error data and not the printed report.
Chris@0 149 return;
Chris@0 150 }
Chris@0 151
Chris@0 152 $reportData = $this->prepareFileReport($phpcsFile);
Chris@0 153 $errorsShown = false;
Chris@0 154
Chris@0 155 foreach ($cliValues['reports'] as $report => $output) {
Chris@0 156 $reportClass = $this->factory($report);
Chris@0 157 $report = get_class($reportClass);
Chris@0 158
Chris@0 159 ob_start();
Chris@0 160 $result = $reportClass->generateFileReport($reportData, $phpcsFile, $cliValues['showSources'], $cliValues['reportWidth']);
Chris@0 161 if ($result === true) {
Chris@0 162 $errorsShown = true;
Chris@0 163 }
Chris@0 164
Chris@0 165 $generatedReport = ob_get_contents();
Chris@0 166 ob_end_clean();
Chris@0 167
Chris@0 168 if ($output === null && $cliValues['reportFile'] !== null) {
Chris@0 169 $output = $cliValues['reportFile'];
Chris@0 170 }
Chris@0 171
Chris@0 172 if ($output === null) {
Chris@0 173 // Using a temp file.
Chris@0 174 if (isset($this->_tmpFiles[$report]) === false) {
Chris@0 175 if (function_exists('sys_get_temp_dir') === true) {
Chris@0 176 // This is needed for HHVM support, but only available from 5.2.1.
Chris@0 177 $this->_tmpFiles[$report] = fopen(tempnam(sys_get_temp_dir(), 'phpcs'), 'w');
Chris@0 178 } else {
Chris@0 179 $this->_tmpFiles[$report] = tmpfile();
Chris@0 180 }
Chris@0 181 }
Chris@0 182
Chris@0 183 fwrite($this->_tmpFiles[$report], $generatedReport);
Chris@0 184 } else {
Chris@0 185 $flags = FILE_APPEND;
Chris@0 186 if (isset($this->_cachedReports[$report]) === false) {
Chris@0 187 $this->_cachedReports[$report] = true;
Chris@0 188 $flags = null;
Chris@0 189 }
Chris@0 190
Chris@0 191 file_put_contents($output, $generatedReport, $flags);
Chris@0 192 }//end if
Chris@0 193 }//end foreach
Chris@0 194
Chris@0 195 if ($errorsShown === true) {
Chris@0 196 $this->totalFiles++;
Chris@0 197 $this->totalErrors += $reportData['errors'];
Chris@0 198 $this->totalWarnings += $reportData['warnings'];
Chris@0 199 $this->totalFixable += $reportData['fixable'];
Chris@0 200 }
Chris@0 201
Chris@0 202 }//end cacheFileReport()
Chris@0 203
Chris@0 204
Chris@0 205 /**
Chris@0 206 * Generates and prints a final report.
Chris@0 207 *
Chris@0 208 * Returns an array with the number of errors and the number of
Chris@0 209 * warnings, in the form ['errors' => int, 'warnings' => int].
Chris@0 210 *
Chris@0 211 * @param string $report Report type.
Chris@0 212 * @param boolean $showSources Show sources?
Chris@0 213 * @param array $cliValues An array of command line arguments.
Chris@0 214 * @param string $reportFile Report file to generate.
Chris@0 215 * @param integer $reportWidth Report max width.
Chris@0 216 *
Chris@0 217 * @return int[]
Chris@0 218 */
Chris@0 219 public function printReport(
Chris@0 220 $report,
Chris@0 221 $showSources,
Chris@0 222 array $cliValues,
Chris@0 223 $reportFile='',
Chris@0 224 $reportWidth=80
Chris@0 225 ) {
Chris@0 226 $reportClass = $this->factory($report);
Chris@0 227 $report = get_class($reportClass);
Chris@0 228
Chris@0 229 if ($reportFile !== null) {
Chris@0 230 $filename = $reportFile;
Chris@0 231 $toScreen = false;
Chris@0 232
Chris@0 233 if (file_exists($filename) === true
Chris@0 234 && isset($this->_cachedReports[$report]) === true
Chris@0 235 ) {
Chris@0 236 $reportCache = file_get_contents($filename);
Chris@0 237 } else {
Chris@0 238 $reportCache = '';
Chris@0 239 }
Chris@0 240 } else {
Chris@0 241 if (isset($this->_tmpFiles[$report]) === true) {
Chris@0 242 $data = stream_get_meta_data($this->_tmpFiles[$report]);
Chris@0 243 $filename = $data['uri'];
Chris@0 244 $reportCache = file_get_contents($filename);
Chris@0 245 fclose($this->_tmpFiles[$report]);
Chris@0 246 } else {
Chris@0 247 $reportCache = '';
Chris@0 248 $filename = null;
Chris@0 249 }
Chris@0 250
Chris@0 251 $toScreen = true;
Chris@0 252 }//end if
Chris@0 253
Chris@0 254 ob_start();
Chris@0 255 $reportClass->generate(
Chris@0 256 $reportCache,
Chris@0 257 $this->totalFiles,
Chris@0 258 $this->totalErrors,
Chris@0 259 $this->totalWarnings,
Chris@0 260 $this->totalFixable,
Chris@0 261 $showSources,
Chris@0 262 $reportWidth,
Chris@0 263 $toScreen
Chris@0 264 );
Chris@0 265 $generatedReport = ob_get_contents();
Chris@0 266 ob_end_clean();
Chris@0 267
Chris@0 268 if ($cliValues['colors'] !== true || $reportFile !== null) {
Chris@0 269 $generatedReport = preg_replace('`\033\[[0-9]+m`', '', $generatedReport);
Chris@0 270 }
Chris@0 271
Chris@0 272 if ($reportFile !== null) {
Chris@0 273 if (PHP_CODESNIFFER_VERBOSITY > 0) {
Chris@0 274 echo $generatedReport;
Chris@0 275 }
Chris@0 276
Chris@0 277 file_put_contents($reportFile, $generatedReport.PHP_EOL);
Chris@0 278 } else {
Chris@0 279 echo $generatedReport;
Chris@0 280 if ($filename !== null && file_exists($filename) === true) {
Chris@0 281 unlink($filename);
Chris@0 282 }
Chris@0 283 }
Chris@0 284
Chris@0 285 return array(
Chris@0 286 'errors' => $this->totalErrors,
Chris@0 287 'warnings' => $this->totalWarnings,
Chris@0 288 );
Chris@0 289
Chris@0 290 }//end printReport()
Chris@0 291
Chris@0 292
Chris@0 293 /**
Chris@0 294 * Pre-process and package violations for all files.
Chris@0 295 *
Chris@0 296 * Used by error reports to get a packaged list of all errors in each file.
Chris@0 297 *
Chris@0 298 * @param PHP_CodeSniffer_File $phpcsFile The file that has been processed.
Chris@0 299 *
Chris@0 300 * @return array
Chris@0 301 */
Chris@0 302 public function prepareFileReport(PHP_CodeSniffer_File $phpcsFile)
Chris@0 303 {
Chris@0 304 $report = array(
Chris@0 305 'filename' => $phpcsFile->getFilename(),
Chris@0 306 'errors' => $phpcsFile->getErrorCount(),
Chris@0 307 'warnings' => $phpcsFile->getWarningCount(),
Chris@0 308 'fixable' => $phpcsFile->getFixableCount(),
Chris@0 309 'messages' => array(),
Chris@0 310 );
Chris@0 311
Chris@0 312 if ($report['errors'] === 0 && $report['warnings'] === 0) {
Chris@0 313 // Prefect score!
Chris@0 314 return $report;
Chris@0 315 }
Chris@0 316
Chris@0 317 $errors = array();
Chris@0 318
Chris@0 319 // Merge errors and warnings.
Chris@0 320 foreach ($phpcsFile->getErrors() as $line => $lineErrors) {
Chris@0 321 if (is_array($lineErrors) === false) {
Chris@0 322 continue;
Chris@0 323 }
Chris@0 324
Chris@0 325 foreach ($lineErrors as $column => $colErrors) {
Chris@0 326 $newErrors = array();
Chris@0 327 foreach ($colErrors as $data) {
Chris@0 328 $newErrors[] = array(
Chris@0 329 'message' => $data['message'],
Chris@0 330 'source' => $data['source'],
Chris@0 331 'severity' => $data['severity'],
Chris@0 332 'fixable' => $data['fixable'],
Chris@0 333 'type' => 'ERROR',
Chris@0 334 );
Chris@0 335 }//end foreach
Chris@0 336
Chris@0 337 $errors[$line][$column] = $newErrors;
Chris@0 338 }//end foreach
Chris@0 339
Chris@0 340 ksort($errors[$line]);
Chris@0 341 }//end foreach
Chris@0 342
Chris@0 343 foreach ($phpcsFile->getWarnings() as $line => $lineWarnings) {
Chris@0 344 if (is_array($lineWarnings) === false) {
Chris@0 345 continue;
Chris@0 346 }
Chris@0 347
Chris@0 348 foreach ($lineWarnings as $column => $colWarnings) {
Chris@0 349 $newWarnings = array();
Chris@0 350 foreach ($colWarnings as $data) {
Chris@0 351 $newWarnings[] = array(
Chris@0 352 'message' => $data['message'],
Chris@0 353 'source' => $data['source'],
Chris@0 354 'severity' => $data['severity'],
Chris@0 355 'fixable' => $data['fixable'],
Chris@0 356 'type' => 'WARNING',
Chris@0 357 );
Chris@0 358 }//end foreach
Chris@0 359
Chris@0 360 if (isset($errors[$line]) === false) {
Chris@0 361 $errors[$line] = array();
Chris@0 362 }
Chris@0 363
Chris@0 364 if (isset($errors[$line][$column]) === true) {
Chris@0 365 $errors[$line][$column] = array_merge(
Chris@0 366 $newWarnings,
Chris@0 367 $errors[$line][$column]
Chris@0 368 );
Chris@0 369 } else {
Chris@0 370 $errors[$line][$column] = $newWarnings;
Chris@0 371 }
Chris@0 372 }//end foreach
Chris@0 373
Chris@0 374 ksort($errors[$line]);
Chris@0 375 }//end foreach
Chris@0 376
Chris@0 377 ksort($errors);
Chris@0 378 $report['messages'] = $errors;
Chris@0 379 return $report;
Chris@0 380
Chris@0 381 }//end prepareFileReport()
Chris@0 382
Chris@0 383
Chris@0 384 /**
Chris@0 385 * Start recording time for the run.
Chris@0 386 *
Chris@0 387 * @return void
Chris@0 388 */
Chris@0 389 public static function startTiming()
Chris@0 390 {
Chris@0 391
Chris@0 392 self::$startTime = microtime(true);
Chris@0 393
Chris@0 394 }//end startTiming()
Chris@0 395
Chris@0 396
Chris@0 397 /**
Chris@0 398 * Print information about the run.
Chris@0 399 *
Chris@0 400 * @return void
Chris@0 401 */
Chris@0 402 public static function printRunTime()
Chris@0 403 {
Chris@0 404 $time = ((microtime(true) - self::$startTime) * 1000);
Chris@0 405
Chris@0 406 if ($time > 60000) {
Chris@0 407 $mins = floor($time / 60000);
Chris@0 408 $secs = round((($time % 60000) / 1000), 2);
Chris@0 409 $time = $mins.' mins';
Chris@0 410 if ($secs !== 0) {
Chris@0 411 $time .= ", $secs secs";
Chris@0 412 }
Chris@0 413 } else if ($time > 1000) {
Chris@0 414 $time = round(($time / 1000), 2).' secs';
Chris@0 415 } else {
Chris@0 416 $time = round($time).'ms';
Chris@0 417 }
Chris@0 418
Chris@0 419 $mem = round((memory_get_peak_usage(true) / (1024 * 1024)), 2).'Mb';
Chris@0 420 echo "Time: $time; Memory: $mem".PHP_EOL.PHP_EOL;
Chris@0 421
Chris@0 422 }//end printRunTime()
Chris@0 423
Chris@0 424
Chris@0 425 }//end class