Skip to content

Commit

Permalink
Add Formatter for GitHub Actions
Browse files Browse the repository at this point in the history
  • Loading branch information
Quetzacoalt91 authored and ondrejmirtes committed Jun 30, 2020
1 parent f61f3f9 commit 1a3911b
Show file tree
Hide file tree
Showing 3 changed files with 229 additions and 0 deletions.
6 changes: 6 additions & 0 deletions conf/config.neon
Original file line number Diff line number Diff line change
Expand Up @@ -1216,3 +1216,9 @@ services:
class: PHPStan\Command\ErrorFormatter\GitlabErrorFormatter
arguments:
relativePathHelper: @simpleRelativePathHelper

errorFormatter.github:
class: PHPStan\Command\ErrorFormatter\GithubErrorFormatter
arguments:
relativePathHelper: @simpleRelativePathHelper
tableErrorformatter: '@errorFormatter.table'
54 changes: 54 additions & 0 deletions src/Command/ErrorFormatter/GithubErrorFormatter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?php declare(strict_types = 1);

namespace PHPStan\Command\ErrorFormatter;

use PHPStan\Command\AnalysisResult;
use PHPStan\Command\Output;
use PHPStan\File\RelativePathHelper;

/**
* Allow errors to be reported in pull-requests diff when run in a GitHub Action
* @see https://help.github.com/en/actions/reference/workflow-commands-for-github-actions#setting-an-error-message
*/
class GithubErrorFormatter implements ErrorFormatter
{

private RelativePathHelper $relativePathHelper;

private TableErrorFormatter $tableErrorformatter;

public function __construct(
RelativePathHelper $relativePathHelper,
TableErrorFormatter $tableErrorformatter
)
{
$this->relativePathHelper = $relativePathHelper;
$this->tableErrorformatter = $tableErrorformatter;
}

public function formatErrors(AnalysisResult $analysisResult, Output $output): int
{
$this->tableErrorformatter->formatErrors($analysisResult, $output);

foreach ($analysisResult->getFileSpecificErrors() as $fileSpecificError) {
$metas = [
'file' => $this->relativePathHelper->getRelativePath($fileSpecificError->getFile()),
'line' => $fileSpecificError->getLine(),
'col' => 0,
];
array_walk($metas, static function (&$value, string $key): void {
$value = sprintf('%s=%s', $key, (string) $value);
});

$message = $fileSpecificError->getMessage();

$line = sprintf('::error %s::%s', implode(',', $metas), $message);

$output->writeRaw($line);
$output->writeLineFormatted('');
}

return $analysisResult->hasErrors() ? 1 : 0;
}

}
169 changes: 169 additions & 0 deletions tests/PHPStan/Command/ErrorFormatter/GithubErrorFormatterTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
<?php declare(strict_types = 1);

namespace PHPStan\Command\ErrorFormatter;

use PHPStan\File\FuzzyRelativePathHelper;
use PHPStan\Testing\ErrorFormatterTestCase;

class GithubErrorFormatterTest extends ErrorFormatterTestCase
{

public function dataFormatterOutputProvider(): iterable
{
yield [
'No errors',
0,
0,
0,
'
[OK] No errors
',
];

yield [
'One file error',
1,
1,
0,
' ------ -----------------------------------------------------------------
Line folder with unicode 😃/file name with "spaces" and unicode 😃.php
------ -----------------------------------------------------------------
4 Foo
------ -----------------------------------------------------------------
[ERROR] Found 1 error
::error file=folder with unicode 😃/file name with "spaces" and unicode 😃.php,line=4,col=0::Foo
',
];

yield [
'One generic error',
1,
0,
1,
' -- ---------------------
Error
-- ---------------------
first generic error
-- ---------------------
[ERROR] Found 1 error
',
];

yield [
'Multiple file errors',
1,
4,
0,
' ------ -----------------------------------------------------------------
Line folder with unicode 😃/file name with "spaces" and unicode 😃.php
------ -----------------------------------------------------------------
2 Bar
4 Foo
------ -----------------------------------------------------------------
------ ---------
Line foo.php
------ ---------
1 Foo
5 Bar
------ ---------
[ERROR] Found 4 errors
::error file=folder with unicode 😃/file name with "spaces" and unicode 😃.php,line=2,col=0::Bar
::error file=folder with unicode 😃/file name with "spaces" and unicode 😃.php,line=4,col=0::Foo
::error file=foo.php,line=1,col=0::Foo
::error file=foo.php,line=5,col=0::Bar
',
];

yield [
'Multiple generic errors',
1,
0,
2,
' -- ----------------------
Error
-- ----------------------
first generic error
second generic error
-- ----------------------
[ERROR] Found 2 errors
',
];

yield [
'Multiple file, multiple generic errors',
1,
4,
2,
' ------ -----------------------------------------------------------------
Line folder with unicode 😃/file name with "spaces" and unicode 😃.php
------ -----------------------------------------------------------------
2 Bar
4 Foo
------ -----------------------------------------------------------------
------ ---------
Line foo.php
------ ---------
1 Foo
5 Bar
------ ---------
-- ----------------------
Error
-- ----------------------
first generic error
second generic error
-- ----------------------
[ERROR] Found 6 errors
::error file=folder with unicode 😃/file name with "spaces" and unicode 😃.php,line=2,col=0::Bar
::error file=folder with unicode 😃/file name with "spaces" and unicode 😃.php,line=4,col=0::Foo
::error file=foo.php,line=1,col=0::Foo
::error file=foo.php,line=5,col=0::Bar
',
];
}

/**
* @dataProvider dataFormatterOutputProvider
*
* @param string $message
* @param int $exitCode
* @param int $numFileErrors
* @param int $numGenericErrors
* @param string $expected
*/
public function testFormatErrors(
string $message,
int $exitCode,
int $numFileErrors,
int $numGenericErrors,
string $expected
): void
{
$relativePathHelper = new FuzzyRelativePathHelper(self::DIRECTORY_PATH, [], '/');
$formatter = new GithubErrorFormatter(
$relativePathHelper,
new TableErrorFormatter($relativePathHelper, false)
);

$this->assertSame($exitCode, $formatter->formatErrors(
$this->getAnalysisResult($numFileErrors, $numGenericErrors),
$this->getOutput()
), sprintf('%s: response code do not match', $message));

$this->assertEquals($expected, $this->getOutputContent(), sprintf('%s: output do not match', $message));
}

}

0 comments on commit 1a3911b

Please sign in to comment.