Skip to content

Commit 85c709d

Browse files
authored
excludePaths: include example for optional path
1 parent 75debf6 commit 85c709d

File tree

4 files changed

+62
-37
lines changed

4 files changed

+62
-37
lines changed

src/Command/CommandHelper.php

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
use PHPStan\File\FileExcluder;
2626
use PHPStan\File\FileFinder;
2727
use PHPStan\File\FileHelper;
28+
use PHPStan\File\ParentDirectoryRelativePathHelper;
2829
use PHPStan\File\SimpleRelativePathHelper;
2930
use PHPStan\Internal\ComposerHelper;
3031
use PHPStan\Internal\DirectoryCreator;
@@ -379,9 +380,30 @@ public static function begin(
379380
$errorOutput->writeLineFormatted('');
380381
}
381382

382-
$errorOutput->writeLineFormatted('If the excluded path can sometimes exist, append <fg=cyan>(?)</>');
383-
$errorOutput->writeLineFormatted('to its config entry to mark it as optional.');
384-
$errorOutput->writeLineFormatted('');
383+
$suggestOptional = $e->getSuggestOptional();
384+
if (count($suggestOptional) > 0) {
385+
$baselinePathHelper = null;
386+
if ($projectConfigFile !== null) {
387+
$baselinePathHelper = new ParentDirectoryRelativePathHelper(dirname($projectConfigFile));
388+
}
389+
$errorOutput->writeLineFormatted('If the excluded path can sometimes exist, append <fg=cyan>(?)</>');
390+
$errorOutput->writeLineFormatted('to its config entry to mark it as optional. Example:');
391+
$errorOutput->writeLineFormatted('');
392+
$errorOutput->writeLineFormatted('<fg=cyan>parameters:</>');
393+
$errorOutput->writeLineFormatted("\t<fg=cyan>excludePaths:</>");
394+
foreach ($suggestOptional as $key => $suggestOptionalPaths) {
395+
$errorOutput->writeLineFormatted(sprintf("\t\t<fg=cyan>%s:</>", $key));
396+
foreach ($suggestOptionalPaths as $suggestOptionalPath) {
397+
if ($baselinePathHelper === null) {
398+
$errorOutput->writeLineFormatted(sprintf("\t\t\t- <fg=cyan>%s (?)</>", $suggestOptionalPath));
399+
continue;
400+
}
401+
402+
$errorOutput->writeLineFormatted(sprintf("\t\t\t- <fg=cyan>%s (?)</>", $baselinePathHelper->getRelativePath($suggestOptionalPath)));
403+
}
404+
}
405+
$errorOutput->writeLineFormatted('');
406+
}
385407

386408
throw new InceptionNotSuccessfulException();
387409
} catch (ValidationException $e) {

src/DependencyInjection/InvalidExcludePathsException.php

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,9 @@ final class InvalidExcludePathsException extends Exception
1010

1111
/**
1212
* @param string[] $errors
13+
* @param array{analyse?: list<string>, analyseAndScan?: list<string>} $suggestOptional
1314
*/
14-
public function __construct(private array $errors)
15+
public function __construct(private array $errors, private array $suggestOptional)
1516
{
1617
parent::__construct(implode("\n", $this->errors));
1718
}
@@ -24,4 +25,12 @@ public function getErrors(): array
2425
return $this->errors;
2526
}
2627

28+
/**
29+
* @return array{analyse?: list<string>, analyseAndScan?: list<string>}
30+
*/
31+
public function getSuggestOptional(): array
32+
{
33+
return $this->suggestOptional;
34+
}
35+
2736
}

src/DependencyInjection/ValidateExcludePathsExtension.php

Lines changed: 26 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
use PHPStan\File\FileExcluder;
88
use function array_key_exists;
99
use function array_map;
10-
use function array_merge;
1110
use function count;
1211
use function is_dir;
1312
use function is_file;
@@ -27,41 +26,42 @@ public function loadConfiguration(): void
2726
return;
2827
}
2928

29+
$newExcludePaths = [];
30+
if (array_key_exists('analyseAndScan', $excludePaths)) {
31+
$newExcludePaths['analyseAndScan'] = $excludePaths['analyseAndScan'];
32+
}
33+
if (array_key_exists('analyse', $excludePaths)) {
34+
$newExcludePaths['analyse'] = $excludePaths['analyse'];
35+
}
36+
3037
$errors = [];
38+
$suggestOptional = [];
3139
if ($builder->parameters['__validate']) {
32-
$paths = [];
33-
if (array_key_exists('analyse', $excludePaths)) {
34-
$paths = $excludePaths['analyse'];
35-
}
36-
if (array_key_exists('analyseAndScan', $excludePaths)) {
37-
$paths = array_merge($paths, $excludePaths['analyseAndScan']);
38-
}
39-
foreach ($paths as $path) {
40-
if ($path instanceof OptionalPath) {
41-
continue;
42-
}
43-
if (FileExcluder::isAbsolutePath($path)) {
44-
if (is_dir($path)) {
40+
foreach ($newExcludePaths as $key => $paths) {
41+
foreach ($paths as $path) {
42+
if ($path instanceof OptionalPath) {
4543
continue;
4644
}
47-
if (is_file($path)) {
45+
if (FileExcluder::isAbsolutePath($path)) {
46+
if (is_dir($path)) {
47+
continue;
48+
}
49+
if (is_file($path)) {
50+
continue;
51+
}
52+
}
53+
if (FileExcluder::isFnmatchPattern($path)) {
4854
continue;
4955
}
50-
}
51-
if (FileExcluder::isFnmatchPattern($path)) {
52-
continue;
53-
}
5456

55-
$errors[] = sprintf('Path %s is neither a directory, nor a file path, nor a fnmatch pattern.', $path);
57+
$suggestOptional[$key][] = $path;
58+
$errors[] = sprintf('Path "%s" is neither a directory, nor a file path, nor a fnmatch pattern.', $path);
59+
}
5660
}
5761
}
5862

59-
$newExcludePaths = [];
60-
if (array_key_exists('analyseAndScan', $excludePaths)) {
61-
$newExcludePaths['analyseAndScan'] = $excludePaths['analyseAndScan'];
62-
}
63-
if (array_key_exists('analyse', $excludePaths)) {
64-
$newExcludePaths['analyse'] = $excludePaths['analyse'];
63+
if (count($errors) !== 0) {
64+
throw new InvalidExcludePathsException($errors, $suggestOptional);
6565
}
6666

6767
foreach ($newExcludePaths as $key => $p) {
@@ -72,12 +72,6 @@ public function loadConfiguration(): void
7272
}
7373

7474
$builder->parameters['excludePaths'] = $newExcludePaths;
75-
76-
if (count($errors) === 0) {
77-
return;
78-
}
79-
80-
throw new InvalidExcludePathsException($errors);
8175
}
8276

8377
}

src/DependencyInjection/ValidateIgnoredErrorsExtension.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ public function getRegistry(): OperatorTypeSpecifyingExtensionRegistry
168168
continue;
169169
}
170170

171-
$errors[] = sprintf('Path %s is neither a directory, nor a file path, nor a fnmatch pattern.', $ignorePath);
171+
$errors[] = sprintf('Path "%s" is neither a directory, nor a file path, nor a fnmatch pattern.', $ignorePath);
172172
}
173173
}
174174
}

0 commit comments

Comments
 (0)