|
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;
|
@@ -131,21 +132,36 @@ class Ruleset
|
131 | 132 | */
|
132 | 133 | private $deprecatedSniffs = [];
|
133 | 134 |
|
| 135 | + /** |
| 136 | + * Message collector object. |
| 137 | + * |
| 138 | + * User-facing messages should be collected via this object for display once the ruleset processing has finished. |
| 139 | + * |
| 140 | + * The following type of errors should *NOT* be collected, but should still throw their own `RuntimeException`: |
| 141 | + * - Errors which could cause other (uncollectable) errors further into the ruleset processing, like a missing autoload file. |
| 142 | + * - Errors which are directly aimed at and only intended for sniff developers or integrators |
| 143 | + * (in contrast to ruleset maintainers or end-users). |
| 144 | + * |
| 145 | + * @var \PHP_CodeSniffer\Util\MessageCollector |
| 146 | + */ |
| 147 | + private $msgCache; |
| 148 | + |
134 | 149 |
|
135 | 150 | /**
|
136 | 151 | * Initialise the ruleset that the run will use.
|
137 | 152 | *
|
138 | 153 | * @param \PHP_CodeSniffer\Config $config The config data for the run.
|
139 | 154 | *
|
140 | 155 | * @return void
|
141 |
| - * @throws \PHP_CodeSniffer\Exceptions\RuntimeException If no sniffs were registered. |
| 156 | + * @throws \PHP_CodeSniffer\Exceptions\RuntimeException If blocking errors were encountered when processing the ruleset. |
142 | 157 | */
|
143 | 158 | public function __construct(Config $config)
|
144 | 159 | {
|
145 |
| - $this->config = $config; |
146 |
| - $restrictions = $config->sniffs; |
147 |
| - $exclusions = $config->exclude; |
148 |
| - $sniffs = []; |
| 160 | + $this->config = $config; |
| 161 | + $restrictions = $config->sniffs; |
| 162 | + $exclusions = $config->exclude; |
| 163 | + $sniffs = []; |
| 164 | + $this->msgCache = new MessageCollector(); |
149 | 165 |
|
150 | 166 | $standardPaths = [];
|
151 | 167 | foreach ($config->standards as $standard) {
|
@@ -242,6 +258,8 @@ public function __construct(Config $config)
|
242 | 258 | throw new RuntimeException('ERROR: No sniffs were registered');
|
243 | 259 | }
|
244 | 260 |
|
| 261 | + $this->displayCachedMessages(); |
| 262 | + |
245 | 263 | }//end __construct()
|
246 | 264 |
|
247 | 265 |
|
@@ -461,6 +479,35 @@ public function showSniffDeprecations()
|
461 | 479 | }//end showSniffDeprecations()
|
462 | 480 |
|
463 | 481 |
|
| 482 | + /** |
| 483 | + * Print any notices encountered while processing the ruleset(s). |
| 484 | + * |
| 485 | + * Note: these messages aren't shown at the time they are encountered to avoid "one error hiding behind another". |
| 486 | + * This way the (end-)user gets to see all of them in one go. |
| 487 | + * |
| 488 | + * @return void |
| 489 | + * |
| 490 | + * @throws \PHP_CodeSniffer\Exceptions\RuntimeException If blocking errors were encountered. |
| 491 | + */ |
| 492 | + private function displayCachedMessages() |
| 493 | + { |
| 494 | + // Don't show deprecations/notices/warnings in quiet mode, in explain mode |
| 495 | + // or when the documentation is being shown. |
| 496 | + // Documentation and explain will call the Ruleset multiple times which |
| 497 | + // would lead to duplicate display of the messages. |
| 498 | + if ($this->msgCache->containsBlockingErrors() === false |
| 499 | + && ($this->config->quiet === true |
| 500 | + || $this->config->explain === true |
| 501 | + || $this->config->generator !== null) |
| 502 | + ) { |
| 503 | + return; |
| 504 | + } |
| 505 | + |
| 506 | + $this->msgCache->display(); |
| 507 | + |
| 508 | + }//end displayCachedMessages() |
| 509 | + |
| 510 | + |
464 | 511 | /**
|
465 | 512 | * Processes a single ruleset and returns a list of the sniffs it represents.
|
466 | 513 | *
|
|
0 commit comments