|
14 | 14 | use PHP_CodeSniffer\Exceptions\RuntimeException; |
15 | 15 | use PHP_CodeSniffer\Sniffs\DeprecatedSniff; |
16 | 16 | use PHP_CodeSniffer\Util\Common; |
| 17 | +use PHP_CodeSniffer\Util\MessageCollector; |
17 | 18 | use PHP_CodeSniffer\Util\Standards; |
18 | 19 | use RecursiveDirectoryIterator; |
19 | 20 | use RecursiveIteratorIterator; |
@@ -138,21 +139,36 @@ class Ruleset |
138 | 139 | */ |
139 | 140 | private $deprecatedSniffs = []; |
140 | 141 |
|
| 142 | + /** |
| 143 | + * Message collector object. |
| 144 | + * |
| 145 | + * User-facing messages should be collected via this object for display once the ruleset processing has finished. |
| 146 | + * |
| 147 | + * The following type of errors should *NOT* be collected, but should still throw their own `RuntimeException`: |
| 148 | + * - Errors which could cause other (uncollectable) errors further into the ruleset processing, like a missing autoload file. |
| 149 | + * - Errors which are directly aimed at and only intended for sniff developers or integrators |
| 150 | + * (in contrast to ruleset maintainers or end-users). |
| 151 | + * |
| 152 | + * @var \PHP_CodeSniffer\Util\MessageCollector |
| 153 | + */ |
| 154 | + private $msgCache; |
| 155 | + |
141 | 156 |
|
142 | 157 | /** |
143 | 158 | * Initialise the ruleset that the run will use. |
144 | 159 | * |
145 | 160 | * @param \PHP_CodeSniffer\Config $config The config data for the run. |
146 | 161 | * |
147 | 162 | * @return void |
148 | | - * @throws \PHP_CodeSniffer\Exceptions\RuntimeException If no sniffs were registered. |
| 163 | + * @throws \PHP_CodeSniffer\Exceptions\RuntimeException If blocking errors were encountered when processing the ruleset. |
149 | 164 | */ |
150 | 165 | public function __construct(Config $config) |
151 | 166 | { |
152 | | - $this->config = $config; |
153 | | - $restrictions = $config->sniffs; |
154 | | - $exclusions = $config->exclude; |
155 | | - $sniffs = []; |
| 167 | + $this->config = $config; |
| 168 | + $restrictions = $config->sniffs; |
| 169 | + $exclusions = $config->exclude; |
| 170 | + $sniffs = []; |
| 171 | + $this->msgCache = new MessageCollector(); |
156 | 172 |
|
157 | 173 | $standardPaths = []; |
158 | 174 | foreach ($config->standards as $standard) { |
@@ -249,6 +265,8 @@ public function __construct(Config $config) |
249 | 265 | throw new RuntimeException('ERROR: No sniffs were registered'); |
250 | 266 | } |
251 | 267 |
|
| 268 | + $this->displayCachedMessages(); |
| 269 | + |
252 | 270 | }//end __construct() |
253 | 271 |
|
254 | 272 |
|
@@ -480,6 +498,35 @@ public function showSniffDeprecations() |
480 | 498 | }//end showSniffDeprecations() |
481 | 499 |
|
482 | 500 |
|
| 501 | + /** |
| 502 | + * Print any notices encountered while processing the ruleset(s). |
| 503 | + * |
| 504 | + * Note: these messages aren't shown at the time they are encountered to avoid "one error hiding behind another". |
| 505 | + * This way the (end-)user gets to see all of them in one go. |
| 506 | + * |
| 507 | + * @return void |
| 508 | + * |
| 509 | + * @throws \PHP_CodeSniffer\Exceptions\RuntimeException If blocking errors were encountered. |
| 510 | + */ |
| 511 | + private function displayCachedMessages() |
| 512 | + { |
| 513 | + // Don't show deprecations/notices/warnings in quiet mode, in explain mode |
| 514 | + // or when the documentation is being shown. |
| 515 | + // Documentation and explain will call the Ruleset multiple times which |
| 516 | + // would lead to duplicate display of the messages. |
| 517 | + if ($this->msgCache->containsBlockingErrors() === false |
| 518 | + && ($this->config->quiet === true |
| 519 | + || $this->config->explain === true |
| 520 | + || $this->config->generator !== null) |
| 521 | + ) { |
| 522 | + return; |
| 523 | + } |
| 524 | + |
| 525 | + $this->msgCache->display(); |
| 526 | + |
| 527 | + }//end displayCachedMessages() |
| 528 | + |
| 529 | + |
483 | 530 | /** |
484 | 531 | * Processes a single ruleset and returns a list of the sniffs it represents. |
485 | 532 | * |
|
0 commit comments