From bb8977f1f4344bef17afcacd916b400f51defa72 Mon Sep 17 00:00:00 2001 From: Andreas Braun Date: Wed, 22 May 2024 16:10:11 +0200 Subject: [PATCH] Add SARIF output formatter for PHPStan (#2965) --- .github/workflows/coding-standards.yml | 8 +- phpstan.neon.dist | 8 ++ tests/PHPStan/SarifErrorFormatter.php | 129 +++++++++++++++++++++++++ 3 files changed, 144 insertions(+), 1 deletion(-) create mode 100644 tests/PHPStan/SarifErrorFormatter.php diff --git a/.github/workflows/coding-standards.yml b/.github/workflows/coding-standards.yml index 0d5ec53cd..1eebcaa5f 100644 --- a/.github/workflows/coding-standards.yml +++ b/.github/workflows/coding-standards.yml @@ -108,7 +108,13 @@ jobs: phpstan-result-cache- - name: Run PHPStan - run: ./vendor/bin/phpstan analyse --no-interaction --no-progress --ansi + run: ./vendor/bin/phpstan analyse --no-interaction --no-progress --ansi --error-format=sarif > phpstan.sarif + + - name: "Upload SARIF report" + if: always() + uses: "github/codeql-action/upload-sarif@v3" + with: + sarif_file: phpstan.sarif - name: Save cache PHPStan results id: phpstan-cache-save diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 518fe9ab8..539536a11 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -14,3 +14,11 @@ parameters: ignoreErrors: - '#Unsafe usage of new static#' - '#Call to an undefined method [a-zA-Z0-9\\_\<\>]+::[a-zA-Z]+\(\)#' + +services: + errorFormatter.sarif: + class: MongoDB\Laravel\Tests\PHPStan\SarifErrorFormatter + arguments: + relativePathHelper: @simpleRelativePathHelper + currentWorkingDirectory: %currentWorkingDirectory% + pretty: true diff --git a/tests/PHPStan/SarifErrorFormatter.php b/tests/PHPStan/SarifErrorFormatter.php new file mode 100644 index 000000000..1fb814cde --- /dev/null +++ b/tests/PHPStan/SarifErrorFormatter.php @@ -0,0 +1,129 @@ + [ + 'uri' => 'file://' . $this->currentWorkingDirectory . '/', + ], + ]; + + $results = []; + $rules = []; + + foreach ($analysisResult->getFileSpecificErrors() as $fileSpecificError) { + $ruleId = $fileSpecificError->getIdentifier(); + $rules[$ruleId] = ['id' => $ruleId]; + + $result = [ + 'ruleId' => $ruleId, + 'level' => 'error', + 'message' => [ + 'text' => $fileSpecificError->getMessage(), + ], + 'locations' => [ + [ + 'physicalLocation' => [ + 'artifactLocation' => [ + 'uri' => $this->relativePathHelper->getRelativePath($fileSpecificError->getFile()), + 'uriBaseId' => self::URI_BASE_ID, + ], + 'region' => [ + 'startLine' => $fileSpecificError->getLine(), + ], + ], + ], + ], + 'properties' => [ + 'ignorable' => $fileSpecificError->canBeIgnored(), + ], + ]; + + if ($fileSpecificError->getTip() !== null) { + $result['properties']['tip'] = $fileSpecificError->getTip(); + } + + $results[] = $result; + } + + foreach ($analysisResult->getNotFileSpecificErrors() as $notFileSpecificError) { + $results[] = [ + 'level' => 'error', + 'message' => [ + 'text' => $notFileSpecificError, + ], + ]; + } + + foreach ($analysisResult->getWarnings() as $warning) { + $results[] = [ + 'level' => 'warning', + 'message' => [ + 'text' => $warning, + ], + ]; + } + + $sarif = [ + '$schema' => 'https://json.schemastore.org/sarif-2.1.0.json', + 'version' => '2.1.0', + 'runs' => [ + [ + 'tool' => [ + 'driver' => [ + 'name' => 'PHPStan', + 'fullName' => 'PHP Static Analysis Tool', + 'informationUri' => 'https://phpstan.org', + 'version' => $phpstanVersion, + 'semanticVersion' => $phpstanVersion, + 'rules' => array_values($rules), + ], + ], + 'originalUriBaseIds' => $originalUriBaseIds, + 'results' => $results, + ], + ], + ]; + + $json = Json::encode($sarif, $this->pretty ? Json::PRETTY : 0); + + $output->writeRaw($json); + + return $analysisResult->hasErrors() ? 1 : 0; + } +}