From 09ab8c1645da4aaca24225f9b118050aceb2dbfa Mon Sep 17 00:00:00 2001 From: Michael Wikberg Date: Thu, 5 Dec 2024 14:08:15 +0200 Subject: [PATCH 1/4] Take date from baseline file mtime instead of current time --- lib/BaselineAnalyzer.php | 4 ++-- tests/AnalyzeApplicationTest.php | 8 ++++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/lib/BaselineAnalyzer.php b/lib/BaselineAnalyzer.php index 31a5bd7..af869c5 100644 --- a/lib/BaselineAnalyzer.php +++ b/lib/BaselineAnalyzer.php @@ -3,7 +3,7 @@ namespace staabm\PHPStanBaselineAnalysis; use Safe\DateTimeImmutable; -use function Safe\preg_match; +use function Safe\filemtime; final class BaselineAnalyzer { @@ -41,7 +41,7 @@ public function __construct(Baseline $baseline) public function analyze(): AnalyzerResult { $result = new AnalyzerResult(); - $result->referenceDate = new DateTimeImmutable(); + $result->referenceDate = DateTimeImmutable::createFromFormat("U", (string) filemtime($this->baseline->getFilePath())); /** * @var BaselineError $baselineError diff --git a/tests/AnalyzeApplicationTest.php b/tests/AnalyzeApplicationTest.php index 10e4700..7bd360b 100644 --- a/tests/AnalyzeApplicationTest.php +++ b/tests/AnalyzeApplicationTest.php @@ -2,9 +2,13 @@ namespace staabm\PHPStanBaselineAnalysis\Tests; +use Safe\DateTimeImmutable; use staabm\PHPStanBaselineAnalysis\AnalyzeApplication; use staabm\PHPStanBaselineAnalysis\ResultPrinter; + +use function Safe\filemtime; use function Safe\json_encode; +use function Safe\ob_start; class AnalyzeApplicationTest extends BaseTestCase { @@ -18,7 +22,7 @@ function testTextPrinting():void $rendered = str_replace(__DIR__, '', $rendered); - $expectedDate = date(ResultPrinter::DATE_FORMAT); + $expectedDate = DateTimeImmutable::createFromFormat("U", (string) filemtime(__DIR__ . '/fixtures/all-in.neon'))->format(ResultPrinter::DATE_FORMAT); $expected = <<format(ResultPrinter::DATE_FORMAT); $expected = << Date: Thu, 5 Dec 2024 14:08:59 +0200 Subject: [PATCH 2/4] Sort dates correctly, as otherwise the rendered graph is super weird --- lib/GraphTemplate.php | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/GraphTemplate.php b/lib/GraphTemplate.php index e86bc76..7e8d6b7 100644 --- a/lib/GraphTemplate.php +++ b/lib/GraphTemplate.php @@ -103,6 +103,7 @@ public function render(Iterator $it):string { } foreach ($dataByDates as $baselinePath => $dataByDate) { + ksort($dataByDate); foreach ($dataByDate as $date => $data) { $dates[$baselinePath][] = 'new Date(' . $date . ' * 1000).toLocaleDateString("de-DE")'; $splines[$baselinePath][0]['data'][] = $data[0]; From 60b81f4709b4dbbf79496c9733388cac026ed5e3 Mon Sep 17 00:00:00 2001 From: Michael Wikberg Date: Thu, 5 Dec 2024 15:16:02 +0200 Subject: [PATCH 3/4] Add `--mtime` flag for `phpstan-baseline-analyze` --- README.md | 3 +++ bin/phpstan-baseline-analyze.php | 7 ++++++- lib/AnalyzeApplication.php | 3 ++- lib/BaselineAnalyzer.php | 12 ++++++++++- tests/AnalyzeApplicationTest.php | 35 ++++++++++++++++++++++++++++++-- 5 files changed, 55 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 1631040..e0db7b2 100644 --- a/README.md +++ b/README.md @@ -83,6 +83,9 @@ $ git clone ... $ phpstan-baseline-analyze *phpstan-baseline.neon --json > now.json +# To use baseline file modification time as the analysis date instead of "now" +$ phpstan-baseline-analyze *phpstan-baseline.neon --json --mtime > now.json + $ git checkout `git rev-list -n 1 --before="1 week ago" HEAD` $ phpstan-baseline-analyze '*phpstan-baseline.neon' --json > 1-week-ago.json diff --git a/bin/phpstan-baseline-analyze.php b/bin/phpstan-baseline-analyze.php index f5c56a8..0fc8517 100644 --- a/bin/phpstan-baseline-analyze.php +++ b/bin/phpstan-baseline-analyze.php @@ -35,9 +35,14 @@ $format = ResultPrinter::FORMAT_TEXT; +$useFileMtime = false; if (in_array('--json', $argv)) { $format = ResultPrinter::FORMAT_JSON; } -$exitCode = $app->start($argv[1], $format); +if (in_array('--mtime', $argv)) { + $useFileMtime = true; +} + +$exitCode = $app->start($argv[1], $format, $useFileMtime); exit($exitCode); diff --git a/lib/AnalyzeApplication.php b/lib/AnalyzeApplication.php index deb39f9..b803c21 100644 --- a/lib/AnalyzeApplication.php +++ b/lib/AnalyzeApplication.php @@ -24,7 +24,7 @@ final class AnalyzeApplication * * @api */ - public function start(string $glob, string $format): int + public function start(string $glob, string $format, bool $useFileMtime = false): int { $printer = new ResultPrinter(); $baselines = BaselineFinder::forGlob($glob); @@ -36,6 +36,7 @@ public function start(string $glob, string $format): int $isLast = $i == $numBaselines - 1; $analyzer = new BaselineAnalyzer($baseline); + $analyzer->useFileMtime($useFileMtime); $result = $analyzer->analyze(); if ($format == ResultPrinter::FORMAT_JSON) { diff --git a/lib/BaselineAnalyzer.php b/lib/BaselineAnalyzer.php index af869c5..4e9cce4 100644 --- a/lib/BaselineAnalyzer.php +++ b/lib/BaselineAnalyzer.php @@ -32,16 +32,26 @@ final class BaselineAnalyzer * @var Baseline */ private $baseline; + private bool $fileMtime; public function __construct(Baseline $baseline) { $this->baseline = $baseline; } + public function useFileMtime(bool $useFileMtime) + { + $this->fileMtime = $useFileMtime; + } + public function analyze(): AnalyzerResult { $result = new AnalyzerResult(); - $result->referenceDate = DateTimeImmutable::createFromFormat("U", (string) filemtime($this->baseline->getFilePath())); + if ($this->fileMtime) { + $result->referenceDate = DateTimeImmutable::createFromFormat("U", (string)filemtime($this->baseline->getFilePath())); + } else { + $result->referenceDate = new DateTimeImmutable(); + } /** * @var BaselineError $baselineError diff --git a/tests/AnalyzeApplicationTest.php b/tests/AnalyzeApplicationTest.php index 7bd360b..44b8989 100644 --- a/tests/AnalyzeApplicationTest.php +++ b/tests/AnalyzeApplicationTest.php @@ -12,7 +12,7 @@ class AnalyzeApplicationTest extends BaseTestCase { - function testTextPrinting():void + function testTextPrintingWithCurrentTime():void { $app = new AnalyzeApplication(); @@ -22,6 +22,37 @@ function testTextPrinting():void $rendered = str_replace(__DIR__, '', $rendered); + $expectedDate = date(ResultPrinter::DATE_FORMAT); + $expected = <<assertSame($expected, $rendered); + $this->assertSame(0, $exitCode); + } + + function testTextPrintingWithFileModificationTime():void + { + $app = new AnalyzeApplication(); + + ob_start(); + $exitCode = $app->start(__DIR__ . '/fixtures/all-in.neon', ResultPrinter::FORMAT_TEXT, true); + $rendered = ob_get_clean(); + + $rendered = str_replace(__DIR__, '', $rendered); + $expectedDate = DateTimeImmutable::createFromFormat("U", (string) filemtime(__DIR__ . '/fixtures/all-in.neon'))->format(ResultPrinter::DATE_FORMAT); $expected = <<format(ResultPrinter::DATE_FORMAT); + $expectedDate = date(ResultPrinter::DATE_FORMAT); $expected = << Date: Thu, 5 Dec 2024 15:23:17 +0200 Subject: [PATCH 4/4] Update README.md --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index e0db7b2..183717c 100644 --- a/README.md +++ b/README.md @@ -84,6 +84,7 @@ $ git clone ... $ phpstan-baseline-analyze *phpstan-baseline.neon --json > now.json # To use baseline file modification time as the analysis date instead of "now" +# Best used together with `git restore-mtime *phpstan-baseline.neon` $ phpstan-baseline-analyze *phpstan-baseline.neon --json --mtime > now.json $ git checkout `git rev-list -n 1 --before="1 week ago" HEAD` @@ -95,6 +96,8 @@ $ phpstan-baseline-analyze '*phpstan-baseline.neon' --json > 2-weeks-ago.json $ php phpstan-baseline-graph '*.json' > result.html ``` +See [git-tools](https://github.com/MestreLion/git-tools) for details on `git restore-mtime` + ![PHPStan baseline analysis graph](https://github.com/staabm/phpstan-baseline-analysis/assets/120441/ea5abe25-21e8-43f2-9118-0967a75517c6)