Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
14 changes: 13 additions & 1 deletion bin/phpstan-baseline-analyze.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,5 +38,17 @@
$format = ResultPrinter::FORMAT_JSON;
}

$exitCode = $app->start($argv[1], $format);
$excludeOptions = preg_grep('/^--exclude=/', $argv);
if ($excludeOptions) {
$excludedFiles = preg_replace('/^--exclude=/', '', $excludeOptions);

Check failure on line 43 in bin/phpstan-baseline-analyze.php

View workflow job for this annotation

GitHub Actions / phpstan static code analysis (ubuntu-latest, 8.2)

Parameter #3 $subject of function preg_replace expects array<float|int|string>|string, array given.

Check failure on line 43 in bin/phpstan-baseline-analyze.php

View workflow job for this annotation

GitHub Actions / phpstan static code analysis (ubuntu-latest, 8.0)

Parameter #3 $subject of function preg_replace expects array<float|int|string>|string, array given.

Check failure on line 43 in bin/phpstan-baseline-analyze.php

View workflow job for this annotation

GitHub Actions / phpstan static code analysis (ubuntu-latest, 8.1)

Parameter #3 $subject of function preg_replace expects array<float|int|string>|string, array given.

Check failure on line 43 in bin/phpstan-baseline-analyze.php

View workflow job for this annotation

GitHub Actions / phpstan static code analysis (ubuntu-latest, 7.4)

Parameter #3 $subject of function preg_replace expects array<float|int|string>|string, array given.
} else {
$excludedFiles = [];
}

if (in_array('--summary', $argv)) {
$exitCode = $app->summarize($argv[1], $format, $excludedFiles);
} else {
$exitCode = $app->start($argv[1], $format);
}

exit($exitCode);
58 changes: 58 additions & 0 deletions lib/AnalyzeApplication.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace staabm\PHPStanBaselineAnalysis;

use DateTimeImmutable;
use \Iterator;

final class AnalyzeApplication
Expand Down Expand Up @@ -51,6 +52,45 @@ public function start(string $glob, string $format): int
return self::EXIT_ERROR;
}

/**
* @param string[] $excludedFilenames
*/
public function summarize(string $glob, string $format, array $excludedFilenames = []): int
{
$baselines = BaselineFinder::forGlob($glob, $excludedFilenames);
$numBaselines = count($baselines);
if ($numBaselines === 0) {
return self::EXIT_ERROR;
}

$resultSummary = new AnalyzerResult();
$baselineSummary = new Baseline();

foreach ($baselines as $baseline) {
$analyzer = new BaselineAnalyzer($baseline);
$result = $analyzer->analyze();
$resultSummary->referenceDate = new DateTimeImmutable();
$resultSummary->overallErrors += $result->overallErrors;
$resultSummary->deprecations += $result->deprecations;
$resultSummary->invalidPhpdocs += $result->invalidPhpdocs;
$resultSummary->unknownTypes += $result->unknownTypes;
$resultSummary->anonymousVariables += $result->anonymousVariables;
$resultSummary->unusedSymbols += $result->unusedSymbols;
}

$printer = new ResultPrinter();

if ($format == ResultPrinter::FORMAT_JSON) {
$stream = $printer->streamJson($baselineSummary, $resultSummary);
} else {
$stream = $printer->streamText($baselineSummary, $resultSummary);
}

$this->printSummary($format, $stream);

return self::EXIT_SUCCESS;
}

/**
* @api
*/
Expand Down Expand Up @@ -84,4 +124,22 @@ private function printResult(string $format, bool $isFirst, bool $isLast, Iterat
}
}
}

/**
* @param Iterator<string> $stream
*/
private function printSummary(string $format, Iterator $stream): void
{
if ($format === ResultPrinter::FORMAT_JSON) {
printf('[');
}

foreach ($stream as $string) {
printf($string);
}

if ($format === ResultPrinter::FORMAT_JSON) {
printf(']');
}
}
}
2 changes: 1 addition & 1 deletion lib/Baseline.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,6 @@
}

public function getFilePath():string {
return $this->filePath;
return $this->filePath ? : basename(getcwd());

Check failure on line 62 in lib/Baseline.php

View workflow job for this annotation

GitHub Actions / phpstan static code analysis (ubuntu-latest, 8.2)

Parameter #1 $path of function basename expects string, string|false given.

Check failure on line 62 in lib/Baseline.php

View workflow job for this annotation

GitHub Actions / phpstan static code analysis (ubuntu-latest, 8.0)

Parameter #1 $path of function basename expects string, string|false given.

Check failure on line 62 in lib/Baseline.php

View workflow job for this annotation

GitHub Actions / phpstan static code analysis (ubuntu-latest, 8.1)

Parameter #1 $path of function basename expects string, string|false given.

Check failure on line 62 in lib/Baseline.php

View workflow job for this annotation

GitHub Actions / phpstan static code analysis (ubuntu-latest, 7.4)

Parameter #1 $path of function basename expects string, string|false given.
}
}
33 changes: 29 additions & 4 deletions lib/BaselineFinder.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@
final class BaselineFinder
{
/**
* @param string[] $excludeFilenames
* @return Baseline[]
*/
static public function forGlob(string $glob): array
static public function forGlob(string $glob, array $excludeFilenames = []): array
{
$baselines = [];

foreach (self::rglob($glob) as $baseline) {
foreach (self::rglob($glob, 0, $excludeFilenames) as $baseline) {
if (!is_file($baseline)) {
continue;
}
Expand All @@ -29,22 +30,46 @@ static public function forGlob(string $glob): array
/**
* from https://stackoverflow.com/a/17161106
*
* @param string[] $excludeFilenames
* @return string[]
*/
static private function rglob(string $pattern,int $flags = 0):array
static private function rglob(string $pattern, int $flags = 0, array $excludeFilenames = []): array
{
$files = glob($pattern, $flags);
if (!$files) {
return [];
}

// Filter out excluded filenames
if ($excludeFilenames !== []) {
$files = self::filerExcludedFiles($files, $excludeFilenames);
}

foreach (glob(dirname($pattern) . '/*', GLOB_ONLYDIR | GLOB_NOSORT) ?: [] as $dir) {
if (basename($dir) == 'vendor') {
continue;
}

$files = array_merge($files, self::rglob($dir . '/' . basename($pattern), $flags));
$files = array_merge($files, self::rglob($dir . '/' . basename($pattern), $flags, $excludeFilenames));
}
return $files;
}

/**
* @param string[] $files
* @param string[] $excludeFilenames
* @return string[]
*/
private static function filerExcludedFiles(array $files, array $excludeFilenames): array
{
return array_filter($files, function (string $file) use ($excludeFilenames) {
foreach ($excludeFilenames as $excludeFilename) {
if (str_ends_with($file, $excludeFilename)) {
return false;
}
}

return true;
});
}
}
Loading