comparison vendor/squizlabs/php_codesniffer/src/Reports/VersionControl.php @ 17:129ea1e6d783

Update, including to Drupal core 8.6.10
author Chris Cannam
date Thu, 28 Feb 2019 13:21:36 +0000
parents
children
comparison
equal deleted inserted replaced
16:c2387f117808 17:129ea1e6d783
1 <?php
2 /**
3 * Version control report base class for PHP_CodeSniffer.
4 *
5 * @author Ben Selby <benmatselby@gmail.com>
6 * @author Greg Sherwood <gsherwood@squiz.net>
7 * @copyright 2006-2015 Squiz Pty Ltd (ABN 77 084 670 600)
8 * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
9 */
10
11 namespace PHP_CodeSniffer\Reports;
12
13 use PHP_CodeSniffer\Files\File;
14 use PHP_CodeSniffer\Util\Timing;
15
16 abstract class VersionControl implements Report
17 {
18
19 /**
20 * The name of the report we want in the output.
21 *
22 * @var string
23 */
24 protected $reportName = 'VERSION CONTROL';
25
26
27 /**
28 * Generate a partial report for a single processed file.
29 *
30 * Function should return TRUE if it printed or stored data about the file
31 * and FALSE if it ignored the file. Returning TRUE indicates that the file and
32 * its data should be counted in the grand totals.
33 *
34 * @param array $report Prepared report data.
35 * @param \PHP_CodeSniffer\File $phpcsFile The file being reported on.
36 * @param bool $showSources Show sources?
37 * @param int $width Maximum allowed line width.
38 *
39 * @return bool
40 */
41 public function generateFileReport($report, File $phpcsFile, $showSources=false, $width=80)
42 {
43 $blames = $this->getBlameContent($report['filename']);
44
45 $authorCache = [];
46 $praiseCache = [];
47 $sourceCache = [];
48
49 foreach ($report['messages'] as $line => $lineErrors) {
50 $author = 'Unknown';
51 if (isset($blames[($line - 1)]) === true) {
52 $blameAuthor = $this->getAuthor($blames[($line - 1)]);
53 if ($blameAuthor !== false) {
54 $author = $blameAuthor;
55 }
56 }
57
58 if (isset($authorCache[$author]) === false) {
59 $authorCache[$author] = 0;
60 $praiseCache[$author] = [
61 'good' => 0,
62 'bad' => 0,
63 ];
64 }
65
66 $praiseCache[$author]['bad']++;
67
68 foreach ($lineErrors as $column => $colErrors) {
69 foreach ($colErrors as $error) {
70 $authorCache[$author]++;
71
72 if ($showSources === true) {
73 $source = $error['source'];
74 if (isset($sourceCache[$author][$source]) === false) {
75 $sourceCache[$author][$source] = [
76 'count' => 1,
77 'fixable' => $error['fixable'],
78 ];
79 } else {
80 $sourceCache[$author][$source]['count']++;
81 }
82 }
83 }
84 }
85
86 unset($blames[($line - 1)]);
87 }//end foreach
88
89 // Now go through and give the authors some credit for
90 // all the lines that do not have errors.
91 foreach ($blames as $line) {
92 $author = $this->getAuthor($line);
93 if ($author === false) {
94 $author = 'Unknown';
95 }
96
97 if (isset($authorCache[$author]) === false) {
98 // This author doesn't have any errors.
99 if (PHP_CODESNIFFER_VERBOSITY === 0) {
100 continue;
101 }
102
103 $authorCache[$author] = 0;
104 $praiseCache[$author] = [
105 'good' => 0,
106 'bad' => 0,
107 ];
108 }
109
110 $praiseCache[$author]['good']++;
111 }//end foreach
112
113 foreach ($authorCache as $author => $errors) {
114 echo "AUTHOR>>$author>>$errors".PHP_EOL;
115 }
116
117 foreach ($praiseCache as $author => $praise) {
118 echo "PRAISE>>$author>>".$praise['good'].'>>'.$praise['bad'].PHP_EOL;
119 }
120
121 foreach ($sourceCache as $author => $sources) {
122 foreach ($sources as $source => $sourceData) {
123 $count = $sourceData['count'];
124 $fixable = (int) $sourceData['fixable'];
125 echo "SOURCE>>$author>>$source>>$count>>$fixable".PHP_EOL;
126 }
127 }
128
129 return true;
130
131 }//end generateFileReport()
132
133
134 /**
135 * Prints the author of all errors and warnings, as given by "version control blame".
136 *
137 * @param string $cachedData Any partial report data that was returned from
138 * generateFileReport during the run.
139 * @param int $totalFiles Total number of files processed during the run.
140 * @param int $totalErrors Total number of errors found during the run.
141 * @param int $totalWarnings Total number of warnings found during the run.
142 * @param int $totalFixable Total number of problems that can be fixed.
143 * @param bool $showSources Show sources?
144 * @param int $width Maximum allowed line width.
145 * @param bool $interactive Are we running in interactive mode?
146 * @param bool $toScreen Is the report being printed to screen?
147 *
148 * @return void
149 */
150 public function generate(
151 $cachedData,
152 $totalFiles,
153 $totalErrors,
154 $totalWarnings,
155 $totalFixable,
156 $showSources=false,
157 $width=80,
158 $interactive=false,
159 $toScreen=true
160 ) {
161 $errorsShown = ($totalErrors + $totalWarnings);
162 if ($errorsShown === 0) {
163 // Nothing to show.
164 return;
165 }
166
167 $lines = explode(PHP_EOL, $cachedData);
168 array_pop($lines);
169
170 if (empty($lines) === true) {
171 return;
172 }
173
174 $authorCache = [];
175 $praiseCache = [];
176 $sourceCache = [];
177
178 foreach ($lines as $line) {
179 $parts = explode('>>', $line);
180 switch ($parts[0]) {
181 case 'AUTHOR':
182 if (isset($authorCache[$parts[1]]) === false) {
183 $authorCache[$parts[1]] = $parts[2];
184 } else {
185 $authorCache[$parts[1]] += $parts[2];
186 }
187 break;
188 case 'PRAISE':
189 if (isset($praiseCache[$parts[1]]) === false) {
190 $praiseCache[$parts[1]] = [
191 'good' => $parts[2],
192 'bad' => $parts[3],
193 ];
194 } else {
195 $praiseCache[$parts[1]]['good'] += $parts[2];
196 $praiseCache[$parts[1]]['bad'] += $parts[3];
197 }
198 break;
199 case 'SOURCE':
200 if (isset($praiseCache[$parts[1]]) === false) {
201 $praiseCache[$parts[1]] = [];
202 }
203
204 if (isset($sourceCache[$parts[1]][$parts[2]]) === false) {
205 $sourceCache[$parts[1]][$parts[2]] = [
206 'count' => $parts[3],
207 'fixable' => (bool) $parts[4],
208 ];
209 } else {
210 $sourceCache[$parts[1]][$parts[2]]['count'] += $parts[3];
211 }
212 break;
213 default:
214 break;
215 }//end switch
216 }//end foreach
217
218 // Make sure the report width isn't too big.
219 $maxLength = 0;
220 foreach ($authorCache as $author => $count) {
221 $maxLength = max($maxLength, strlen($author));
222 if ($showSources === true && isset($sourceCache[$author]) === true) {
223 foreach ($sourceCache[$author] as $source => $sourceData) {
224 if ($source === 'count') {
225 continue;
226 }
227
228 $maxLength = max($maxLength, (strlen($source) + 9));
229 }
230 }
231 }
232
233 $width = min($width, ($maxLength + 30));
234 $width = max($width, 70);
235 arsort($authorCache);
236
237 echo PHP_EOL."\033[1m".'PHP CODE SNIFFER '.$this->reportName.' BLAME SUMMARY'."\033[0m".PHP_EOL;
238 echo str_repeat('-', $width).PHP_EOL."\033[1m";
239 if ($showSources === true) {
240 echo 'AUTHOR SOURCE'.str_repeat(' ', ($width - 43)).'(Author %) (Overall %) COUNT'.PHP_EOL;
241 echo str_repeat('-', $width).PHP_EOL;
242 } else {
243 echo 'AUTHOR'.str_repeat(' ', ($width - 34)).'(Author %) (Overall %) COUNT'.PHP_EOL;
244 echo str_repeat('-', $width).PHP_EOL;
245 }
246
247 echo "\033[0m";
248
249 if ($showSources === true) {
250 $maxSniffWidth = ($width - 15);
251
252 if ($totalFixable > 0) {
253 $maxSniffWidth -= 4;
254 }
255 }
256
257 $fixableSources = 0;
258
259 foreach ($authorCache as $author => $count) {
260 if ($praiseCache[$author]['good'] === 0) {
261 $percent = 0;
262 } else {
263 $total = ($praiseCache[$author]['bad'] + $praiseCache[$author]['good']);
264 $percent = round(($praiseCache[$author]['bad'] / $total * 100), 2);
265 }
266
267 $overallPercent = '('.round((($count / $errorsShown) * 100), 2).')';
268 $authorPercent = '('.$percent.')';
269 $line = str_repeat(' ', (6 - strlen($count))).$count;
270 $line = str_repeat(' ', (12 - strlen($overallPercent))).$overallPercent.$line;
271 $line = str_repeat(' ', (11 - strlen($authorPercent))).$authorPercent.$line;
272 $line = $author.str_repeat(' ', ($width - strlen($author) - strlen($line))).$line;
273
274 if ($showSources === true) {
275 $line = "\033[1m$line\033[0m";
276 }
277
278 echo $line.PHP_EOL;
279
280 if ($showSources === true && isset($sourceCache[$author]) === true) {
281 $errors = $sourceCache[$author];
282 asort($errors);
283 $errors = array_reverse($errors);
284
285 foreach ($errors as $source => $sourceData) {
286 if ($source === 'count') {
287 continue;
288 }
289
290 $count = $sourceData['count'];
291
292 $srcLength = strlen($source);
293 if ($srcLength > $maxSniffWidth) {
294 $source = substr($source, 0, $maxSniffWidth);
295 }
296
297 $line = str_repeat(' ', (5 - strlen($count))).$count;
298
299 echo ' ';
300 if ($totalFixable > 0) {
301 echo '[';
302 if ($sourceData['fixable'] === true) {
303 echo 'x';
304 $fixableSources++;
305 } else {
306 echo ' ';
307 }
308
309 echo '] ';
310 }
311
312 echo $source;
313 if ($totalFixable > 0) {
314 echo str_repeat(' ', ($width - 18 - strlen($source)));
315 } else {
316 echo str_repeat(' ', ($width - 14 - strlen($source)));
317 }
318
319 echo $line.PHP_EOL;
320 }//end foreach
321 }//end if
322 }//end foreach
323
324 echo str_repeat('-', $width).PHP_EOL;
325 echo "\033[1m".'A TOTAL OF '.$errorsShown.' SNIFF VIOLATION';
326 if ($errorsShown !== 1) {
327 echo 'S';
328 }
329
330 echo ' WERE COMMITTED BY '.count($authorCache).' AUTHOR';
331 if (count($authorCache) !== 1) {
332 echo 'S';
333 }
334
335 echo "\033[0m";
336
337 if ($totalFixable > 0) {
338 if ($showSources === true) {
339 echo PHP_EOL.str_repeat('-', $width).PHP_EOL;
340 echo "\033[1mPHPCBF CAN FIX THE $fixableSources MARKED SOURCES AUTOMATICALLY ($totalFixable VIOLATIONS IN TOTAL)\033[0m";
341 } else {
342 echo PHP_EOL.str_repeat('-', $width).PHP_EOL;
343 echo "\033[1mPHPCBF CAN FIX $totalFixable OF THESE SNIFF VIOLATIONS AUTOMATICALLY\033[0m";
344 }
345 }
346
347 echo PHP_EOL.str_repeat('-', $width).PHP_EOL.PHP_EOL;
348
349 if ($toScreen === true && $interactive === false) {
350 Timing::printRunTime();
351 }
352
353 }//end generate()
354
355
356 /**
357 * Extract the author from a blame line.
358 *
359 * @param string $line Line to parse.
360 *
361 * @return mixed string or false if impossible to recover.
362 */
363 abstract protected function getAuthor($line);
364
365
366 /**
367 * Gets the blame output.
368 *
369 * @param string $filename File to blame.
370 *
371 * @return array
372 */
373 abstract protected function getBlameContent($filename);
374
375
376 }//end class