Skip to content

Commit 5940e1b

Browse files
freddenjrfnl
authored andcommitted
Improve error message for an invalid sniff code (#344)
.. when using the `--sniffs=...` or `--exclude=...` CLI flags. Instead of piecemealing the errors, all errors for the complete argument will now be shown in one go.
1 parent 9f9a879 commit 5940e1b

File tree

2 files changed

+251
-60
lines changed

2 files changed

+251
-60
lines changed

src/Config.php

+89-20
Original file line numberDiff line numberDiff line change
@@ -883,32 +883,14 @@ public function processLongArgument($arg, $pos)
883883
break;
884884
}
885885

886-
$sniffs = explode(',', substr($arg, 7));
887-
foreach ($sniffs as $sniff) {
888-
if (substr_count($sniff, '.') !== 2) {
889-
$error = 'ERROR: The specified sniff code "'.$sniff.'" is invalid'.PHP_EOL.PHP_EOL;
890-
$error .= $this->printShortUsage(true);
891-
throw new DeepExitException($error, 3);
892-
}
893-
}
894-
895-
$this->sniffs = $sniffs;
886+
$this->sniffs = $this->parseSniffCodes(substr($arg, 7), 'sniffs');
896887
$this->overriddenDefaults['sniffs'] = true;
897888
} else if (substr($arg, 0, 8) === 'exclude=') {
898889
if (isset($this->overriddenDefaults['exclude']) === true) {
899890
break;
900891
}
901892

902-
$sniffs = explode(',', substr($arg, 8));
903-
foreach ($sniffs as $sniff) {
904-
if (substr_count($sniff, '.') !== 2) {
905-
$error = 'ERROR: The specified sniff code "'.$sniff.'" is invalid'.PHP_EOL.PHP_EOL;
906-
$error .= $this->printShortUsage(true);
907-
throw new DeepExitException($error, 3);
908-
}
909-
}
910-
911-
$this->exclude = $sniffs;
893+
$this->exclude = $this->parseSniffCodes(substr($arg, 8), 'exclude');
912894
$this->overriddenDefaults['exclude'] = true;
913895
} else if (defined('PHP_CODESNIFFER_IN_TESTS') === false
914896
&& substr($arg, 0, 6) === 'cache='
@@ -1257,6 +1239,93 @@ public function processLongArgument($arg, $pos)
12571239
}//end processLongArgument()
12581240

12591241

1242+
/**
1243+
* Parse supplied string into a list of validated sniff codes.
1244+
*
1245+
* @param string $input Comma-separated string of sniff codes.
1246+
* @param string $argument The name of the argument which is being processed.
1247+
*
1248+
* @return array<string>
1249+
* @throws DeepExitException When any of the provided codes are not valid as sniff codes.
1250+
*/
1251+
private function parseSniffCodes($input, $argument)
1252+
{
1253+
$errors = [];
1254+
$sniffs = [];
1255+
1256+
$possibleSniffs = array_filter(explode(',', $input));
1257+
1258+
if ($possibleSniffs === []) {
1259+
$errors[] = 'No codes specified / empty argument';
1260+
}
1261+
1262+
foreach ($possibleSniffs as $sniff) {
1263+
$sniff = trim($sniff);
1264+
1265+
$partCount = substr_count($sniff, '.');
1266+
if ($partCount === 2) {
1267+
// Correct number of parts.
1268+
$sniffs[] = $sniff;
1269+
continue;
1270+
}
1271+
1272+
if ($partCount === 0) {
1273+
$errors[] = 'Standard codes are not supported: '.$sniff;
1274+
} else if ($partCount === 1) {
1275+
$errors[] = 'Category codes are not supported: '.$sniff;
1276+
} else if ($partCount === 3) {
1277+
$errors[] = 'Message codes are not supported: '.$sniff;
1278+
} else {
1279+
$errors[] = 'Too many parts: '.$sniff;
1280+
}
1281+
1282+
if ($partCount > 2) {
1283+
$parts = explode('.', $sniff, 4);
1284+
$sniffs[] = $parts[0].'.'.$parts[1].'.'.$parts[2];
1285+
}
1286+
}//end foreach
1287+
1288+
$sniffs = array_reduce(
1289+
$sniffs,
1290+
static function ($carry, $item) {
1291+
$lower = strtolower($item);
1292+
1293+
foreach ($carry as $found) {
1294+
if ($lower === strtolower($found)) {
1295+
// This sniff is already in our list.
1296+
return $carry;
1297+
}
1298+
}
1299+
1300+
$carry[] = $item;
1301+
1302+
return $carry;
1303+
},
1304+
[]
1305+
);
1306+
1307+
if ($errors !== []) {
1308+
$error = 'ERROR: The --'.$argument.' option only supports sniff codes.'.PHP_EOL;
1309+
$error .= 'Sniff codes are in the form "Standard.Category.Sniff".'.PHP_EOL;
1310+
$error .= PHP_EOL;
1311+
$error .= 'The following problems were detected:'.PHP_EOL;
1312+
$error .= '* '.implode(PHP_EOL.'* ', $errors).PHP_EOL;
1313+
1314+
if ($sniffs !== []) {
1315+
$error .= PHP_EOL;
1316+
$error .= 'Perhaps try --'.$argument.'="'.implode(',', $sniffs).'" instead.'.PHP_EOL;
1317+
}
1318+
1319+
$error .= PHP_EOL;
1320+
$error .= $this->printShortUsage(true);
1321+
throw new DeepExitException(ltrim($error), 3);
1322+
}
1323+
1324+
return $sniffs;
1325+
1326+
}//end parseSniffCodes()
1327+
1328+
12601329
/**
12611330
* Processes an unknown command line argument.
12621331
*

0 commit comments

Comments
 (0)