Skip to content

Commit

Permalink
add --bare
Browse files Browse the repository at this point in the history
  • Loading branch information
TomasVotruba committed May 31, 2024
1 parent e30a0a3 commit e8b11e2
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 26 deletions.
18 changes: 16 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,20 @@

[![Downloads total](https://img.shields.io/packagist/dt/tomasvotruba/phpstan-bodyscan.svg?style=flat-square)](https://packagist.org/packages/tomasvotruba/phpstan-bodyscan/stats)

Do you want to get quick glimpse of new project code quality?
* Do you want to get quick glimpse of new project code quality?
* Do you want to know, what PHPStan level is the best for your project?
* Do you want to know, how much errors you're facing per level to see how hard it will be to reach them?

Get error count for each PHPStan level!

<br>

## How does it work?

First, we look into the project root for `phpstan.neon` file. If found, we reuse its `parameters > paths` configuration. If not, we look for defaults source code paths like `/src`, `/app`, `/tests`, etc.
First, we look into the project root for `phpstan.neon` file.

* If found, we reuse it.
* If not, we look for defaults source code paths like `/src`, `/app`, `/tests`, etc.

Then we run PHPStan for each level from 0 to 8. We count errors and display them in a table.

Expand Down Expand Up @@ -53,6 +58,15 @@ To get errors count per level:

<br>

## Do you want to run levels without extensions?

```bash
vendor/bin/phpstan-bodyscan --bare
```

<br>


## Do you need a JSON format?

We got you covered:
Expand Down
16 changes: 9 additions & 7 deletions src/Command/RunCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ protected function configure(): void
InputOption::VALUE_NONE,
'Without any extensions, without ignores, without baselines, just pure PHPStan'
);

// @todo nobaseline - without ignores and baseline files
}

/**
Expand All @@ -61,7 +63,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
/** @var string $projectDirectory */
$projectDirectory = getcwd();

$minPhpStanLevel = (int) $input->getOption('min-level');
$minPhpStanLevel = $input->getOption('min-level');
$maxPhpStanLevel = (int) $input->getOption('max-level');
Assert::lessThanEq($minPhpStanLevel, $maxPhpStanLevel);

Expand All @@ -77,8 +79,8 @@ protected function execute(InputInterface $input, OutputInterface $output): int

// 1. prepare empty phpstan config
// no baselines, ignores etc. etc :)
$phpstanConfiguration = $this->phpStanConfigFactory->create($projectDirectory, $isBare);
file_put_contents($projectDirectory . '/phpstan-bodyscan.neon', $phpstanConfiguration);
$phpstanConfig = $this->phpStanConfigFactory->create($projectDirectory, [], $isBare);
file_put_contents($projectDirectory . '/phpstan-bodyscan.neon', $phpstanConfig->getFileContents());

$levelResults = [];

Expand All @@ -94,8 +96,8 @@ protected function execute(InputInterface $input, OutputInterface $output): int

// 2. measure phpstan levels
for ($phpStanLevel = $minPhpStanLevel; $phpStanLevel <= $maxPhpStanLevel; ++$phpStanLevel) {
$this->symfonyStyle->section(sprintf('Running PHPStan level %d %s', $phpStanLevel, $withExtensions ?
'with extensions' : 'without extensions'));
$this->symfonyStyle->section(sprintf('Running PHPStan level %d %s', $phpStanLevel, $isBare ?
'without extensions' : 'with extensions'));

$levelResult = $this->measureErrorCountInLevel($phpStanLevel, $projectDirectory, $envVariables);
$levelResults[] = $levelResult;
Expand All @@ -104,11 +106,11 @@ protected function execute(InputInterface $input, OutputInterface $output): int
$this->symfonyStyle->newLine();
}

if ($withExtensions === false) {
if ($isBare) {
// restore PHPStan extension file
$this->symfonyStyle->writeln('Restoring PHPStan extensions...');
$this->symfonyStyle->newLine();

// restore PHPStan extension file
$phpstanExtensionFile = $projectDirectory . '/vendor/phpstan/extension-installer/src/GeneratedConfig.php';
rename($phpstanExtensionFile . '.bak', $phpstanExtensionFile);
}
Expand Down
36 changes: 28 additions & 8 deletions src/PHPStanConfigFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,15 @@ final class PHPStanConfigFactory
/**
* @var string[]
*/
private const PHPSTAN_FILE_NAMES = ['phpstan.neon', 'phpstan.neon.dist', 'phpstan.php', 'phpstan.php.dist'];
private const PHPSTAN_FILE_NAMES = ['phpstan.neon', 'phpstan.neon.dist'];

/**
* @param array<string, mixed[]> $extraConfiguration
*/
public function create(string $projectDirectory, array $extraConfiguration = [], bool $bare = false): PHPStanConfig
{
$existingPHPStanFile = null;
$phpstanFileName = null;

foreach (self::PHPSTAN_FILE_NAMES as $phpstanFileName) {
if (file_exists($projectDirectory . '/' . $phpstanFileName)) {
$existingPHPStanFile = $projectDirectory . '/' . $phpstanFileName;
Expand All @@ -39,20 +39,26 @@ public function create(string $projectDirectory, array $extraConfiguration = [],
// no config found? we have to create it
if ($existingPHPStanFile === null) {
$phpstanConfiguration = $this->createBasicPHPStanConfiguration($projectDirectory);
$phpstanNeon = $this->dumpToNeon($phpstanConfiguration);
return new PHPStanConfig($phpstanNeon, null);
$phpStanNeonContents = $this->dumpNeonToString($phpstanConfiguration);
return new PHPStanConfig($phpStanNeonContents);
}

// keep original setup
if ($bare === false) {
return new PHPStanConfig(file_get_contents($existingPHPStanFile), $phpstanFileName);
$phpStanNeonContents = $this->loadFileAndMergeParameters($existingPHPStanFile, [
'parameters' => [
// disable ignored error reporting, to make no fatal errors
'reportUnmatchedIgnoredErrors' => false,
],
]);
return new PHPStanConfig($phpStanNeonContents);
}

$phpstanConfiguration = $this->createBarePHPStanConfiguration($existingPHPStanFile);
$phpstanConfiguration = array_merge_recursive($phpstanConfiguration, $extraConfiguration);

$phpstanNeon = $this->dumpToNeon($phpstanConfiguration);
return new PHPStanConfig($phpstanNeon, $phpstanFileName);
$phpstanNeon = $this->dumpNeonToString($phpstanConfiguration);
return new PHPStanConfig($phpstanNeon);
}

/**
Expand Down Expand Up @@ -93,7 +99,21 @@ private function createBasicPHPStanConfiguration(string $projectDirectory): arra
];
}

private function dumpToNeon(array $phpstanConfiguration): string
/**
* @param array<string, mixed> $extraContents
*/
private function loadFileAndMergeParameters(string $existingPHPStanFile, array $extraContents): string
{
$neon = Neon::decodeFile($existingPHPStanFile);
$neon = array_merge_recursive($neon, $extraContents);

return $this->dumpNeonToString($neon);
}

/**
* @param array<string, mixed> $phpstanConfiguration
*/
private function dumpNeonToString(array $phpstanConfiguration): string
{
$encodedNeon = Neon::encode($phpstanConfiguration, true, ' ');
return trim($encodedNeon) . PHP_EOL;
Expand Down
6 changes: 0 additions & 6 deletions src/ValueObject/PHPStanConfig.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,11 @@
{
public function __construct(
private string $fileContents,
private ?string $originalFileName
) {
}

public function getFileContents(): string
{
return $this->fileContents;
}

public function getOriginalFileName(): ?string
{
return $this->originalFileName;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,5 @@ parameters:

excludePaths:
- src/SomeOther

reportUnmatchedIgnoredErrors: false
5 changes: 2 additions & 3 deletions tests/PHPStanConfigFactory/PHPStanConfigFactoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,8 @@ protected function setUp(): void
#[DataProvider('provideData')]
public function test(string $projectDirectory, string $expectedPHPStanConfigFile): void
{
$phpstanNeon = $this->phpStanConfigFactory->create($projectDirectory);

$this->assertStringEqualsFile($expectedPHPStanConfigFile, $phpstanNeon->getFileContents());
$phpStanConfig = $this->phpStanConfigFactory->create($projectDirectory);
$this->assertStringEqualsFile($expectedPHPStanConfigFile, $phpStanConfig->getFileContents());
}

public static function provideData(): Iterator
Expand Down

0 comments on commit e8b11e2

Please sign in to comment.