Skip to content

Improve error message for an invalid sniff code #344

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
4d5b0c4
Improve error message for an invalid sniff code
fredden Feb 16, 2024
8dd0102
Update src/Config.php
fredden Jan 10, 2025
995522f
Update src/Config.php
fredden Jan 10, 2025
792cf66
Report all errors, even if duplicates
fredden Jan 10, 2025
4ed5733
Filter out empty values sooner
fredden Jan 10, 2025
9850de4
Complain if nothing (or only commas) specified
fredden Jan 10, 2025
95d5955
Ignore case when removing duplicates from final list
fredden Jan 10, 2025
5c48598
Add missing `@covers` annotation
fredden Jan 10, 2025
d36d44a
Update src/Config.php
fredden Jan 10, 2025
c2aec40
Remove invalid assumption regarding valid characters
fredden Jan 10, 2025
d5f5fe0
Update test to reflect change via GitHub
fredden Jan 10, 2025
994bb1c
Update test: treat empty values as errors
fredden Jan 10, 2025
af962dc
Merge remote-tracking branch 'upstream/master' into feature/improve-s…
fredden Jan 10, 2025
0dcd4ef
Remove unused variable
fredden Jan 10, 2025
bccdffc
Update docblocks to match reality
fredden Jan 10, 2025
3421e00
Apply whitespace changes from phpcbf
fredden Jan 10, 2025
99753e8
Add more tests
fredden Jan 10, 2025
d1bfb0a
Apply whitespace changes from phpcbf
fredden Jan 10, 2025
b270da2
Move method further up the file
fredden Jan 23, 2025
d0e1cf8
Correct param type for $errors
fredden Jan 23, 2025
b127df4
Use phpstan-style return types
fredden Jan 23, 2025
5b5208b
Remove word 'sniffs' from method names
fredden Jan 23, 2025
f87a5e1
Use a different syntax for special comments
fredden Feb 11, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
109 changes: 89 additions & 20 deletions src/Config.php
Original file line number Diff line number Diff line change
Expand Up @@ -885,32 +885,14 @@ public function processLongArgument($arg, $pos)
break;
}

$sniffs = explode(',', substr($arg, 7));
foreach ($sniffs as $sniff) {
if (substr_count($sniff, '.') !== 2) {
$error = 'ERROR: The specified sniff code "'.$sniff.'" is invalid'.PHP_EOL.PHP_EOL;
$error .= $this->printShortUsage(true);
throw new DeepExitException($error, 3);
}
}

$this->sniffs = $sniffs;
$this->sniffs = $this->parseSniffCodes(substr($arg, 7), 'sniffs');
self::$overriddenDefaults['sniffs'] = true;
} else if (substr($arg, 0, 8) === 'exclude=') {
if (isset(self::$overriddenDefaults['exclude']) === true) {
break;
}

$sniffs = explode(',', substr($arg, 8));
foreach ($sniffs as $sniff) {
if (substr_count($sniff, '.') !== 2) {
$error = 'ERROR: The specified sniff code "'.$sniff.'" is invalid'.PHP_EOL.PHP_EOL;
$error .= $this->printShortUsage(true);
throw new DeepExitException($error, 3);
}
}

$this->exclude = $sniffs;
$this->exclude = $this->parseSniffCodes(substr($arg, 8), 'exclude');
self::$overriddenDefaults['exclude'] = true;
} else if (defined('PHP_CODESNIFFER_IN_TESTS') === false
&& substr($arg, 0, 6) === 'cache='
Expand Down Expand Up @@ -1277,6 +1259,93 @@ public function processLongArgument($arg, $pos)
}//end processLongArgument()


/**
* Parse supplied string into a list of validated sniff codes.
*
* @param string $input Comma-separated string of sniff codes.
* @param string $argument The name of the argument which is being processed.
*
* @return array<string>
* @throws DeepExitException When any of the provided codes are not valid as sniff codes.
*/
private function parseSniffCodes($input, $argument)
{
$errors = [];
$sniffs = [];

$possibleSniffs = array_filter(explode(',', $input));

if ($possibleSniffs === []) {
$errors[] = 'No codes specified / empty argument';
}

foreach ($possibleSniffs as $sniff) {
$sniff = trim($sniff);

$partCount = substr_count($sniff, '.');
if ($partCount === 2) {
// Correct number of parts.
$sniffs[] = $sniff;
continue;
}

if ($partCount === 0) {
$errors[] = 'Standard codes are not supported: '.$sniff;
} else if ($partCount === 1) {
$errors[] = 'Category codes are not supported: '.$sniff;
} else if ($partCount === 3) {
$errors[] = 'Message codes are not supported: '.$sniff;
} else {
$errors[] = 'Too many parts: '.$sniff;
}

if ($partCount > 2) {
$parts = explode('.', $sniff, 4);
$sniffs[] = $parts[0].'.'.$parts[1].'.'.$parts[2];
}
}//end foreach

$sniffs = array_reduce(
$sniffs,
static function ($carry, $item) {
$lower = strtolower($item);

foreach ($carry as $found) {
if ($lower === strtolower($found)) {
// This sniff is already in our list.
return $carry;
}
}

$carry[] = $item;

return $carry;
},
[]
);

if ($errors !== []) {
$error = 'ERROR: The --'.$argument.' option only supports sniff codes.'.PHP_EOL;
$error .= 'Sniff codes are in the form "Standard.Category.Sniff".'.PHP_EOL;
$error .= PHP_EOL;
$error .= 'The following problems were detected:'.PHP_EOL;
$error .= '* '.implode(PHP_EOL.'* ', $errors).PHP_EOL;

if ($sniffs !== []) {
$error .= PHP_EOL;
$error .= 'Perhaps try --'.$argument.'="'.implode(',', $sniffs).'" instead.'.PHP_EOL;
}

$error .= PHP_EOL;
$error .= $this->printShortUsage(true);
throw new DeepExitException(ltrim($error), 3);
}

return $sniffs;

}//end parseSniffCodes()


/**
* Processes an unknown command line argument.
*
Expand Down
Loading