Skip to content

Commit 1a3911b

Browse files
Quetzacoalt91ondrejmirtes
authored andcommitted
Add Formatter for GitHub Actions
1 parent f61f3f9 commit 1a3911b

3 files changed

Lines changed: 229 additions & 0 deletions

File tree

conf/config.neon

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1216,3 +1216,9 @@ services:
12161216
class: PHPStan\Command\ErrorFormatter\GitlabErrorFormatter
12171217
arguments:
12181218
relativePathHelper: @simpleRelativePathHelper
1219+
1220+
errorFormatter.github:
1221+
class: PHPStan\Command\ErrorFormatter\GithubErrorFormatter
1222+
arguments:
1223+
relativePathHelper: @simpleRelativePathHelper
1224+
tableErrorformatter: '@errorFormatter.table'
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace PHPStan\Command\ErrorFormatter;
4+
5+
use PHPStan\Command\AnalysisResult;
6+
use PHPStan\Command\Output;
7+
use PHPStan\File\RelativePathHelper;
8+
9+
/**
10+
* Allow errors to be reported in pull-requests diff when run in a GitHub Action
11+
* @see https://help.github.com/en/actions/reference/workflow-commands-for-github-actions#setting-an-error-message
12+
*/
13+
class GithubErrorFormatter implements ErrorFormatter
14+
{
15+
16+
private RelativePathHelper $relativePathHelper;
17+
18+
private TableErrorFormatter $tableErrorformatter;
19+
20+
public function __construct(
21+
RelativePathHelper $relativePathHelper,
22+
TableErrorFormatter $tableErrorformatter
23+
)
24+
{
25+
$this->relativePathHelper = $relativePathHelper;
26+
$this->tableErrorformatter = $tableErrorformatter;
27+
}
28+
29+
public function formatErrors(AnalysisResult $analysisResult, Output $output): int
30+
{
31+
$this->tableErrorformatter->formatErrors($analysisResult, $output);
32+
33+
foreach ($analysisResult->getFileSpecificErrors() as $fileSpecificError) {
34+
$metas = [
35+
'file' => $this->relativePathHelper->getRelativePath($fileSpecificError->getFile()),
36+
'line' => $fileSpecificError->getLine(),
37+
'col' => 0,
38+
];
39+
array_walk($metas, static function (&$value, string $key): void {
40+
$value = sprintf('%s=%s', $key, (string) $value);
41+
});
42+
43+
$message = $fileSpecificError->getMessage();
44+
45+
$line = sprintf('::error %s::%s', implode(',', $metas), $message);
46+
47+
$output->writeRaw($line);
48+
$output->writeLineFormatted('');
49+
}
50+
51+
return $analysisResult->hasErrors() ? 1 : 0;
52+
}
53+
54+
}
Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace PHPStan\Command\ErrorFormatter;
4+
5+
use PHPStan\File\FuzzyRelativePathHelper;
6+
use PHPStan\Testing\ErrorFormatterTestCase;
7+
8+
class GithubErrorFormatterTest extends ErrorFormatterTestCase
9+
{
10+
11+
public function dataFormatterOutputProvider(): iterable
12+
{
13+
yield [
14+
'No errors',
15+
0,
16+
0,
17+
0,
18+
'
19+
[OK] No errors
20+
21+
',
22+
];
23+
24+
yield [
25+
'One file error',
26+
1,
27+
1,
28+
0,
29+
' ------ -----------------------------------------------------------------
30+
Line folder with unicode 😃/file name with "spaces" and unicode 😃.php
31+
------ -----------------------------------------------------------------
32+
4 Foo
33+
------ -----------------------------------------------------------------
34+
35+
[ERROR] Found 1 error
36+
37+
::error file=folder with unicode 😃/file name with "spaces" and unicode 😃.php,line=4,col=0::Foo
38+
',
39+
];
40+
41+
yield [
42+
'One generic error',
43+
1,
44+
0,
45+
1,
46+
' -- ---------------------
47+
Error
48+
-- ---------------------
49+
first generic error
50+
-- ---------------------
51+
52+
[ERROR] Found 1 error
53+
54+
',
55+
];
56+
57+
yield [
58+
'Multiple file errors',
59+
1,
60+
4,
61+
0,
62+
' ------ -----------------------------------------------------------------
63+
Line folder with unicode 😃/file name with "spaces" and unicode 😃.php
64+
------ -----------------------------------------------------------------
65+
2 Bar
66+
4 Foo
67+
------ -----------------------------------------------------------------
68+
69+
------ ---------
70+
Line foo.php
71+
------ ---------
72+
1 Foo
73+
5 Bar
74+
------ ---------
75+
76+
[ERROR] Found 4 errors
77+
78+
::error file=folder with unicode 😃/file name with "spaces" and unicode 😃.php,line=2,col=0::Bar
79+
::error file=folder with unicode 😃/file name with "spaces" and unicode 😃.php,line=4,col=0::Foo
80+
::error file=foo.php,line=1,col=0::Foo
81+
::error file=foo.php,line=5,col=0::Bar
82+
',
83+
];
84+
85+
yield [
86+
'Multiple generic errors',
87+
1,
88+
0,
89+
2,
90+
' -- ----------------------
91+
Error
92+
-- ----------------------
93+
first generic error
94+
second generic error
95+
-- ----------------------
96+
97+
[ERROR] Found 2 errors
98+
99+
',
100+
];
101+
102+
yield [
103+
'Multiple file, multiple generic errors',
104+
1,
105+
4,
106+
2,
107+
' ------ -----------------------------------------------------------------
108+
Line folder with unicode 😃/file name with "spaces" and unicode 😃.php
109+
------ -----------------------------------------------------------------
110+
2 Bar
111+
4 Foo
112+
------ -----------------------------------------------------------------
113+
114+
------ ---------
115+
Line foo.php
116+
------ ---------
117+
1 Foo
118+
5 Bar
119+
------ ---------
120+
121+
-- ----------------------
122+
Error
123+
-- ----------------------
124+
first generic error
125+
second generic error
126+
-- ----------------------
127+
128+
[ERROR] Found 6 errors
129+
130+
::error file=folder with unicode 😃/file name with "spaces" and unicode 😃.php,line=2,col=0::Bar
131+
::error file=folder with unicode 😃/file name with "spaces" and unicode 😃.php,line=4,col=0::Foo
132+
::error file=foo.php,line=1,col=0::Foo
133+
::error file=foo.php,line=5,col=0::Bar
134+
',
135+
];
136+
}
137+
138+
/**
139+
* @dataProvider dataFormatterOutputProvider
140+
*
141+
* @param string $message
142+
* @param int $exitCode
143+
* @param int $numFileErrors
144+
* @param int $numGenericErrors
145+
* @param string $expected
146+
*/
147+
public function testFormatErrors(
148+
string $message,
149+
int $exitCode,
150+
int $numFileErrors,
151+
int $numGenericErrors,
152+
string $expected
153+
): void
154+
{
155+
$relativePathHelper = new FuzzyRelativePathHelper(self::DIRECTORY_PATH, [], '/');
156+
$formatter = new GithubErrorFormatter(
157+
$relativePathHelper,
158+
new TableErrorFormatter($relativePathHelper, false)
159+
);
160+
161+
$this->assertSame($exitCode, $formatter->formatErrors(
162+
$this->getAnalysisResult($numFileErrors, $numGenericErrors),
163+
$this->getOutput()
164+
), sprintf('%s: response code do not match', $message));
165+
166+
$this->assertEquals($expected, $this->getOutputContent(), sprintf('%s: output do not match', $message));
167+
}
168+
169+
}

0 commit comments

Comments
 (0)