From 22c84d2e64dd30780c995d8a720a487bb484dc02 Mon Sep 17 00:00:00 2001 From: Ondrej Mirtes Date: Wed, 10 Jul 2024 13:45:48 +0200 Subject: [PATCH] Add `diagnose` command to run DiagnoseExtensions --- bin/phpstan | 2 + src/Command/DiagnoseCommand.php | 104 ++++++++++++++++++++++ src/Diagnose/DiagnoseExtension.php | 2 +- src/Diagnose/PHPStanDiagnoseExtension.php | 10 +-- 4 files changed, 112 insertions(+), 6 deletions(-) create mode 100644 src/Command/DiagnoseCommand.php diff --git a/bin/phpstan b/bin/phpstan index 537f3e123d..a8c0fd8dd0 100755 --- a/bin/phpstan +++ b/bin/phpstan @@ -3,6 +3,7 @@ use PHPStan\Command\AnalyseCommand; use PHPStan\Command\ClearResultCacheCommand; +use PHPStan\Command\DiagnoseCommand; use PHPStan\Command\DumpParametersCommand; use PHPStan\Command\FixerWorkerCommand; use PHPStan\Command\WorkerCommand; @@ -166,5 +167,6 @@ use Symfony\Component\Console\Helper\ProgressBar; $application->add(new ClearResultCacheCommand($reversedComposerAutoloaderProjectPaths)); $application->add(new FixerWorkerCommand($reversedComposerAutoloaderProjectPaths)); $application->add(new DumpParametersCommand($reversedComposerAutoloaderProjectPaths)); + $application->add(new DiagnoseCommand($reversedComposerAutoloaderProjectPaths)); $application->run(); })(); diff --git a/src/Command/DiagnoseCommand.php b/src/Command/DiagnoseCommand.php new file mode 100644 index 0000000000..608cf732f1 --- /dev/null +++ b/src/Command/DiagnoseCommand.php @@ -0,0 +1,104 @@ +setName(self::NAME) + ->setDescription('Shows diagnose information about PHPStan and extensions') + ->setDefinition([ + new InputOption('configuration', 'c', InputOption::VALUE_REQUIRED, 'Path to project configuration file'), + new InputOption(AnalyseCommand::OPTION_LEVEL, 'l', InputOption::VALUE_REQUIRED, 'Level of rule options - the higher the stricter'), + new InputOption('autoload-file', 'a', InputOption::VALUE_REQUIRED, 'Project\'s additional autoload file path'), + new InputOption('debug', null, InputOption::VALUE_NONE, 'Show debug information - do not catch internal errors'), + new InputOption('memory-limit', null, InputOption::VALUE_REQUIRED, 'Memory limit for clearing result cache'), + ]); + } + + protected function initialize(InputInterface $input, OutputInterface $output): void + { + if ((bool) $input->getOption('debug')) { + $application = $this->getApplication(); + if ($application === null) { + throw new ShouldNotHappenException(); + } + $application->setCatchExceptions(false); + return; + } + } + + protected function execute(InputInterface $input, OutputInterface $output): int + { + $memoryLimit = $input->getOption('memory-limit'); + $autoloadFile = $input->getOption('autoload-file'); + $configuration = $input->getOption('configuration'); + $level = $input->getOption(AnalyseCommand::OPTION_LEVEL); + + if ( + (!is_string($memoryLimit) && $memoryLimit !== null) + || (!is_string($autoloadFile) && $autoloadFile !== null) + || (!is_string($configuration) && $configuration !== null) + || (!is_string($level) && $level !== null) + ) { + throw new ShouldNotHappenException(); + } + + try { + $inceptionResult = CommandHelper::begin( + $input, + $output, + [], + $memoryLimit, + $autoloadFile, + $this->composerAutoloaderProjectPaths, + $configuration, + null, + $level, + false, + ); + } catch (InceptionNotSuccessfulException) { + return 1; + } + + $container = $inceptionResult->getContainer(); + $output = $inceptionResult->getStdOutput(); + + /** @var PHPStanDiagnoseExtension $phpstanDiagnoseExtension */ + $phpstanDiagnoseExtension = $container->getService('phpstanDiagnoseExtension'); + + // not using tag for this extension to make sure it's always first + $phpstanDiagnoseExtension->print($output); + + /** @var DiagnoseExtension $extension */ + foreach ($container->getServicesByTag(DiagnoseExtension::EXTENSION_TAG) as $extension) { + $extension->print($output); + } + + return 0; + } + +} diff --git a/src/Diagnose/DiagnoseExtension.php b/src/Diagnose/DiagnoseExtension.php index 5df5d628ef..084134495a 100644 --- a/src/Diagnose/DiagnoseExtension.php +++ b/src/Diagnose/DiagnoseExtension.php @@ -26,6 +26,6 @@ interface DiagnoseExtension public const EXTENSION_TAG = 'phpstan.diagnoseExtension'; - public function print(Output $errorOutput): void; + public function print(Output $output): void; } diff --git a/src/Diagnose/PHPStanDiagnoseExtension.php b/src/Diagnose/PHPStanDiagnoseExtension.php index 9184987cb8..a7eb786ed8 100644 --- a/src/Diagnose/PHPStanDiagnoseExtension.php +++ b/src/Diagnose/PHPStanDiagnoseExtension.php @@ -15,23 +15,23 @@ public function __construct(private PhpVersion $phpVersion) { } - public function print(Output $errorOutput): void + public function print(Output $output): void { $phpRuntimeVersion = new PhpVersion(PHP_VERSION_ID); - $errorOutput->writeLineFormatted(sprintf( + $output->writeLineFormatted(sprintf( 'PHP runtime version: %s', $phpRuntimeVersion->getVersionString(), )); - $errorOutput->writeLineFormatted(sprintf( + $output->writeLineFormatted(sprintf( 'PHP version for analysis: %s (from %s)', $this->phpVersion->getVersionString(), $this->phpVersion->getSourceLabel(), )); - $errorOutput->writeLineFormatted(sprintf( + $output->writeLineFormatted(sprintf( 'PHPStan version: %s', ComposerHelper::getPhpStanVersion(), )); - $errorOutput->writeLineFormatted(''); + $output->writeLineFormatted(''); } }