mirror of
https://github.com/danog/psalm.git
synced 2025-01-22 05:41:20 +01:00
add CodeClimate output format (#4387)
* add CodeClimate output format * cosmetic fixes * add CodeClimate output format * cosmetic fixes * phpcs fixes
This commit is contained in:
parent
b6cb9785ac
commit
70a130f11e
@ -25,6 +25,7 @@ use Psalm\Internal\Analyzer\ProjectAnalyzer;
|
||||
use Psalm\Issue\CodeIssue;
|
||||
use Psalm\Issue\UnusedPsalmSuppress;
|
||||
use Psalm\Report\CheckstyleReport;
|
||||
use Psalm\Report\CodeClimateReport;
|
||||
use Psalm\Report\CompactReport;
|
||||
use Psalm\Report\ConsoleReport;
|
||||
use Psalm\Report\EmacsReport;
|
||||
@ -765,6 +766,10 @@ class IssueBuffer
|
||||
case Report::TYPE_SARIF:
|
||||
$output = new SarifReport($normalized_data, self::$fixable_issue_counts, $report_options);
|
||||
break;
|
||||
|
||||
case Report::TYPE_CODECLIMATE:
|
||||
$output = new CodeClimateReport($normalized_data, self::$fixable_issue_counts, $report_options);
|
||||
break;
|
||||
}
|
||||
|
||||
return $output->create();
|
||||
|
@ -20,6 +20,7 @@ abstract class Report
|
||||
public const TYPE_GITHUB_ACTIONS = 'github';
|
||||
public const TYPE_PHP_STORM = 'phpstorm';
|
||||
public const TYPE_SARIF = 'sarif';
|
||||
public const TYPE_CODECLIMATE = 'codeclimate';
|
||||
|
||||
public const SUPPORTED_OUTPUT_TYPES = [
|
||||
self::TYPE_COMPACT,
|
||||
@ -36,6 +37,7 @@ abstract class Report
|
||||
self::TYPE_GITHUB_ACTIONS,
|
||||
self::TYPE_PHP_STORM,
|
||||
self::TYPE_SARIF,
|
||||
self::TYPE_CODECLIMATE,
|
||||
];
|
||||
|
||||
/**
|
||||
|
95
src/Psalm/Report/CodeClimateReport.php
Normal file
95
src/Psalm/Report/CodeClimateReport.php
Normal file
@ -0,0 +1,95 @@
|
||||
<?php
|
||||
|
||||
namespace Psalm\Report;
|
||||
|
||||
use Psalm\Config;
|
||||
use Psalm\Internal\Json\Json;
|
||||
use Psalm\Report;
|
||||
use Psalm\Internal\Analyzer\IssueData;
|
||||
|
||||
use function array_values;
|
||||
use function md5;
|
||||
|
||||
/**
|
||||
* CodeClimate format
|
||||
* This is the format used by Gitlab for CodeQuality
|
||||
*
|
||||
* @see https://docs.gitlab.com/ee/user/project/merge_requests/code_quality.html
|
||||
* @see https://github.com/codeclimate/platform/blob/master/spec/analyzers/SPEC.md#data-types
|
||||
*
|
||||
* @author Olivier Doucet <webmaster@ajeux.com>
|
||||
*/
|
||||
class CodeClimateReport extends Report
|
||||
{
|
||||
public function create(): string
|
||||
{
|
||||
$options = $this->pretty ? Json::PRETTY : Json::DEFAULT;
|
||||
|
||||
$issues_data = \array_map(
|
||||
function (IssueData $issue): array {
|
||||
/**
|
||||
* map fields to new structure.
|
||||
* Expected fields:
|
||||
* - type
|
||||
* - check_name
|
||||
* - description*
|
||||
* - content
|
||||
* - categories[]
|
||||
* - severity
|
||||
* - fingerprint*
|
||||
* - location.path*
|
||||
* - location.lines.begin*
|
||||
*
|
||||
* Fields with * are the one used by Gitlab for Code Quality
|
||||
*/
|
||||
return [
|
||||
'type' => 'issue',
|
||||
'check_name' => $issue->type,
|
||||
'description' => $issue->message,
|
||||
'categories' => [$issue->type],
|
||||
'severity' => $this->convertSeverity($issue->severity),
|
||||
'fingerprint' => $this->calculateFingerprint($issue),
|
||||
'location' => [
|
||||
'path' => $issue->file_path,
|
||||
'lines' => [
|
||||
'begin' => $issue->from,
|
||||
'end' => $issue->to,
|
||||
],
|
||||
],
|
||||
];
|
||||
},
|
||||
$this->issues_data
|
||||
);
|
||||
|
||||
return Json::encode(array_values($issues_data), $options) . "\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* convert our own severity to CodeClimate format
|
||||
* Values can be : info, minor, major, critical, or blocker
|
||||
* @return string
|
||||
*/
|
||||
protected function convertSeverity(string $input): string
|
||||
{
|
||||
if (Config::REPORT_INFO === $input) {
|
||||
return 'info';
|
||||
}
|
||||
if (Config::REPORT_ERROR === $input) {
|
||||
return 'critical';
|
||||
}
|
||||
if (Config::REPORT_SUPPRESS === $input) {
|
||||
return 'minor';
|
||||
}
|
||||
|
||||
// unknown cases ? fallback
|
||||
return 'critical';
|
||||
}
|
||||
|
||||
/**
|
||||
* calculate a unique fingerprint for a given issue
|
||||
*/
|
||||
protected function calculateFingerprint(IssueData $issue): string
|
||||
{
|
||||
return md5($issue->type.$issue->message.$issue->file_path.$issue->from.$issue->to);
|
||||
}
|
||||
}
|
@ -372,7 +372,7 @@ Output:
|
||||
--output-format=console
|
||||
Changes the output format.
|
||||
Available formats: compact, console, text, emacs, json, pylint, xml, checkstyle, junit, sonarqube, github,
|
||||
phpstorm
|
||||
phpstorm, codeclimate
|
||||
|
||||
--no-progress
|
||||
Disable the progress indicator
|
||||
|
Loading…
x
Reference in New Issue
Block a user