|
4 | 4 |
|
5 | 5 | use Closure; |
6 | 6 | use Composer\XdebugHandler\XdebugHandler; |
7 | | -use Nette\DI\Config\Adapters\PhpAdapter; |
8 | 7 | use Nette\DI\Helpers; |
9 | 8 | use Nette\DI\InvalidConfigurationException; |
10 | 9 | use Nette\DI\ServiceCreationException; |
|
13 | 12 | use Nette\Schema\ValidationException; |
14 | 13 | use Nette\Utils\AssertionException; |
15 | 14 | use Nette\Utils\Strings; |
16 | | -use Nette\Utils\Validators; |
17 | 15 | use PHPStan\Command\Symfony\SymfonyOutput; |
18 | 16 | use PHPStan\Command\Symfony\SymfonyStyle; |
19 | 17 | use PHPStan\DependencyInjection\Container; |
20 | 18 | use PHPStan\DependencyInjection\ContainerFactory; |
| 19 | +use PHPStan\DependencyInjection\DuplicateIncludedFilesException; |
21 | 20 | use PHPStan\DependencyInjection\InvalidIgnoredErrorPatternsException; |
22 | 21 | use PHPStan\DependencyInjection\LoaderFactory; |
23 | | -use PHPStan\DependencyInjection\NeonAdapter; |
24 | 22 | use PHPStan\ExtensionInstaller\GeneratedConfig; |
25 | 23 | use PHPStan\File\FileFinder; |
26 | 24 | use PHPStan\File\FileHelper; |
|
30 | 28 | use Symfony\Component\Console\Output\ConsoleOutputInterface; |
31 | 29 | use Symfony\Component\Console\Output\OutputInterface; |
32 | 30 | use Throwable; |
33 | | -use function array_diff_key; |
34 | 31 | use function array_key_exists; |
35 | 32 | use function array_map; |
36 | | -use function array_merge; |
37 | | -use function array_unique; |
38 | 33 | use function class_exists; |
39 | 34 | use function count; |
40 | 35 | use function dirname; |
|
53 | 48 | use function register_shutdown_function; |
54 | 49 | use function spl_autoload_functions; |
55 | 50 | use function sprintf; |
56 | | -use function str_ends_with; |
57 | 51 | use function str_repeat; |
58 | 52 | use function strpos; |
59 | 53 | use function sys_get_temp_dir; |
@@ -270,18 +264,6 @@ public static function begin( |
270 | 264 | $additionalConfigFiles[] = $projectConfigFile; |
271 | 265 | } |
272 | 266 |
|
273 | | - $loaderParameters = [ |
274 | | - 'rootDir' => $containerFactory->getRootDirectory(), |
275 | | - 'currentWorkingDirectory' => $containerFactory->getCurrentWorkingDirectory(), |
276 | | - ]; |
277 | | - |
278 | | - self::detectDuplicateIncludedFiles( |
279 | | - $errorOutput, |
280 | | - $currentWorkingDirectoryFileHelper, |
281 | | - $additionalConfigFiles, |
282 | | - $loaderParameters, |
283 | | - ); |
284 | | - |
285 | 267 | $createDir = static function (string $path) use ($errorOutput): void { |
286 | 268 | if (!is_dir($path) && !@mkdir($path, 0777) && !is_dir($path)) { |
287 | 269 | $errorOutput->writeLineFormatted(sprintf('Cannot create a temp directory %s', $path)); |
@@ -343,6 +325,19 @@ public static function begin( |
343 | 325 | $errorOutput->writeLineFormatted(sprintf("\t\t%s: @defaultAnalysisParser", $matches['parameterName'])); |
344 | 326 | $errorOutput->writeLineFormatted(''); |
345 | 327 |
|
| 328 | + throw new InceptionNotSuccessfulException(); |
| 329 | + } catch (DuplicateIncludedFilesException $e) { |
| 330 | + $format = "<error>These files are included multiple times:</error>\n- %s"; |
| 331 | + if (count($e->getFiles()) === 1) { |
| 332 | + $format = "<error>This file is included multiple times:</error>\n- %s"; |
| 333 | + } |
| 334 | + $errorOutput->writeLineFormatted(sprintf($format, implode("\n- ", $e->getFiles()))); |
| 335 | + |
| 336 | + if (class_exists('PHPStan\ExtensionInstaller\GeneratedConfig')) { |
| 337 | + $errorOutput->writeLineFormatted(''); |
| 338 | + $errorOutput->writeLineFormatted('It can lead to unexpected results. If you\'re using phpstan/extension-installer, make sure you have removed corresponding neon files from your project config file.'); |
| 339 | + } |
| 340 | + |
346 | 341 | throw new InceptionNotSuccessfulException(); |
347 | 342 | } |
348 | 343 |
|
@@ -516,90 +511,4 @@ private static function executeBootstrapFile( |
516 | 511 | } |
517 | 512 | } |
518 | 513 |
|
519 | | - /** |
520 | | - * @param string[] $configFiles |
521 | | - * @param array<string, string> $loaderParameters |
522 | | - * @throws InceptionNotSuccessfulException |
523 | | - */ |
524 | | - private static function detectDuplicateIncludedFiles( |
525 | | - Output $output, |
526 | | - FileHelper $fileHelper, |
527 | | - array $configFiles, |
528 | | - array $loaderParameters, |
529 | | - ): void |
530 | | - { |
531 | | - $neonAdapter = new NeonAdapter(); |
532 | | - $phpAdapter = new PhpAdapter(); |
533 | | - $allConfigFiles = []; |
534 | | - foreach ($configFiles as $configFile) { |
535 | | - $allConfigFiles = array_merge($allConfigFiles, self::getConfigFiles($fileHelper, $neonAdapter, $phpAdapter, $configFile, $loaderParameters, null)); |
536 | | - } |
537 | | - |
538 | | - $normalized = array_map(static fn (string $file): string => $fileHelper->normalizePath($file), $allConfigFiles); |
539 | | - |
540 | | - $deduplicated = array_unique($normalized); |
541 | | - if (count($normalized) <= count($deduplicated)) { |
542 | | - return; |
543 | | - } |
544 | | - |
545 | | - $duplicateFiles = array_unique(array_diff_key($normalized, $deduplicated)); |
546 | | - |
547 | | - $format = "<error>These files are included multiple times:</error>\n- %s"; |
548 | | - if (count($duplicateFiles) === 1) { |
549 | | - $format = "<error>This file is included multiple times:</error>\n- %s"; |
550 | | - } |
551 | | - $output->writeLineFormatted(sprintf($format, implode("\n- ", $duplicateFiles))); |
552 | | - |
553 | | - if (class_exists('PHPStan\ExtensionInstaller\GeneratedConfig')) { |
554 | | - $output->writeLineFormatted(''); |
555 | | - $output->writeLineFormatted('It can lead to unexpected results. If you\'re using phpstan/extension-installer, make sure you have removed corresponding neon files from your project config file.'); |
556 | | - } |
557 | | - throw new InceptionNotSuccessfulException(); |
558 | | - } |
559 | | - |
560 | | - /** |
561 | | - * @param array<string, string> $loaderParameters |
562 | | - * @return string[] |
563 | | - */ |
564 | | - private static function getConfigFiles( |
565 | | - FileHelper $fileHelper, |
566 | | - NeonAdapter $neonAdapter, |
567 | | - PhpAdapter $phpAdapter, |
568 | | - string $configFile, |
569 | | - array $loaderParameters, |
570 | | - ?string $generateBaselineFile, |
571 | | - ): array |
572 | | - { |
573 | | - if ($generateBaselineFile === $fileHelper->normalizePath($configFile)) { |
574 | | - return []; |
575 | | - } |
576 | | - if (!is_file($configFile) || !is_readable($configFile)) { |
577 | | - return []; |
578 | | - } |
579 | | - |
580 | | - if (str_ends_with($configFile, '.php')) { |
581 | | - $data = $phpAdapter->load($configFile); |
582 | | - } else { |
583 | | - $data = $neonAdapter->load($configFile); |
584 | | - } |
585 | | - $allConfigFiles = [$configFile]; |
586 | | - if (isset($data['includes'])) { |
587 | | - Validators::assert($data['includes'], 'list', sprintf("section 'includes' in file '%s'", $configFile)); |
588 | | - $includes = Helpers::expand($data['includes'], $loaderParameters); |
589 | | - foreach ($includes as $include) { |
590 | | - $include = self::expandIncludedFile($include, $configFile); |
591 | | - $allConfigFiles = array_merge($allConfigFiles, self::getConfigFiles($fileHelper, $neonAdapter, $phpAdapter, $include, $loaderParameters, $generateBaselineFile)); |
592 | | - } |
593 | | - } |
594 | | - |
595 | | - return $allConfigFiles; |
596 | | - } |
597 | | - |
598 | | - private static function expandIncludedFile(string $includedFile, string $mainFile): string |
599 | | - { |
600 | | - return Strings::match($includedFile, '#([a-z]+:)?[/\\\\]#Ai') !== null // is absolute |
601 | | - ? $includedFile |
602 | | - : dirname($mainFile) . '/' . $includedFile; |
603 | | - } |
604 | | - |
605 | 514 | } |
0 commit comments