Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 88b83f5

Browse filesBrowse files
committed
[Translation] XliffLintCommand supports Github Actions annotations
1 parent c01b032 commit 88b83f5
Copy full SHA for 88b83f5

File tree

3 files changed

+71
-4
lines changed
Filter options

3 files changed

+71
-4
lines changed

‎src/Symfony/Component/Translation/CHANGELOG.md

Copy file name to clipboardExpand all lines: src/Symfony/Component/Translation/CHANGELOG.md
+6Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
CHANGELOG
22
=========
33

4+
5.3
5+
---
6+
7+
* Add `github` format & autodetection to render errors as annotations when
8+
running the XLIFF linter command in a Github Actions environment.
9+
410
5.2.0
511
-----
612

‎src/Symfony/Component/Translation/Command/XliffLintCommand.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Translation/Command/XliffLintCommand.php
+22-4Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace Symfony\Component\Translation\Command;
1313

14+
use Symfony\Component\Console\CI\GithubActionReporter;
1415
use Symfony\Component\Console\Command\Command;
1516
use Symfony\Component\Console\Exception\RuntimeException;
1617
use Symfony\Component\Console\Input\InputArgument;
@@ -55,7 +56,7 @@ protected function configure()
5556
$this
5657
->setDescription('Lints a XLIFF file and outputs encountered errors')
5758
->addArgument('filename', InputArgument::IS_ARRAY, 'A file, a directory or "-" for reading from STDIN')
58-
->addOption('format', null, InputOption::VALUE_REQUIRED, 'The output format', 'txt')
59+
->addOption('format', null, InputOption::VALUE_REQUIRED, 'The output format')
5960
->setHelp(<<<EOF
6061
The <info>%command.name%</info> command lints a XLIFF file and outputs to STDOUT
6162
the first encountered syntax error.
@@ -85,6 +86,14 @@ protected function execute(InputInterface $input, OutputInterface $output)
8586
$this->format = $input->getOption('format');
8687
$this->displayCorrectFiles = $output->isVerbose();
8788

89+
if ('github' === $this->format && !class_exists(GithubActionReporter::class)) {
90+
throw new \InvalidArgumentException('The "github" format is only available since "symfony/console" >= 5.3.');
91+
}
92+
93+
if (null === $this->format) {
94+
$this->format = class_exists(GithubActionReporter::class) && GithubActionReporter::isGithubActionEnvironment() ? 'github' : 'txt';
95+
}
96+
8897
if (['-'] === $filenames) {
8998
return $this->display($io, [$this->validate(file_get_contents('php://stdin'))]);
9099
}
@@ -159,25 +168,34 @@ private function display(SymfonyStyle $io, array $files)
159168
return $this->displayTxt($io, $files);
160169
case 'json':
161170
return $this->displayJson($io, $files);
171+
case 'github':
172+
return $this->displayTxt($io, $files, true);
162173
default:
163174
throw new InvalidArgumentException(sprintf('The format "%s" is not supported.', $this->format));
164175
}
165176
}
166177

167-
private function displayTxt(SymfonyStyle $io, array $filesInfo)
178+
private function displayTxt(SymfonyStyle $io, array $filesInfo, bool $errorAsGithubAnnotations = false)
168179
{
169180
$countFiles = \count($filesInfo);
170181
$erroredFiles = 0;
182+
$githubReporter = $errorAsGithubAnnotations ? new GithubActionReporter($io) : null;
171183

172184
foreach ($filesInfo as $info) {
173185
if ($info['valid'] && $this->displayCorrectFiles) {
174186
$io->comment('<info>OK</info>'.($info['file'] ? sprintf(' in %s', $info['file']) : ''));
175187
} elseif (!$info['valid']) {
176188
++$erroredFiles;
177189
$io->text('<error> ERROR </error>'.($info['file'] ? sprintf(' in %s', $info['file']) : ''));
178-
$io->listing(array_map(function ($error) {
190+
$io->listing(array_map(function ($error) use ($info, $githubReporter) {
179191
// general document errors have a '-1' line number
180-
return -1 === $error['line'] ? $error['message'] : sprintf('Line %d, Column %d: %s', $error['line'], $error['column'], $error['message']);
192+
$line = -1 === $error['line'] ? null : $error['line'];
193+
194+
if ($githubReporter) {
195+
$githubReporter->error($error['message'], $info['file'], $line, null !== $line ? $error['column'] : null);
196+
}
197+
198+
return null === $line ? $error['message'] : sprintf('Line %d, Column %d: %s', $line, $error['column'], $error['message']);
181199
}, $info['messages']));
182200
}
183201
}

‎src/Symfony/Component/Translation/Tests/Command/XliffLintCommandTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Translation/Tests/Command/XliffLintCommandTest.php
+43Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
use PHPUnit\Framework\TestCase;
1515
use Symfony\Component\Console\Application;
16+
use Symfony\Component\Console\CI\GithubActionReporter;
1617
use Symfony\Component\Console\Output\OutputInterface;
1718
use Symfony\Component\Console\Tester\CommandTester;
1819
use Symfony\Component\Translation\Command\XliffLintCommand;
@@ -129,6 +130,48 @@ public function testGetHelp()
129130
$this->assertStringContainsString($expected, $command->getHelp());
130131
}
131132

133+
public function testLintIncorrectFileWithGithubFormat()
134+
{
135+
if (!class_exists(GithubActionReporter::class)) {
136+
$this->expectException(\InvalidArgumentException::class);
137+
$this->expectExceptionMessage('The "github" format is only available since "symfony/console" >= 5.3');
138+
}
139+
140+
$filename = $this->createFile('note <target>');
141+
$tester = $this->createCommandTester();
142+
143+
$tester->execute(['filename' => [$filename], '--format' => 'github'], ['decorated' => false]);
144+
145+
if (!class_exists(GithubActionReporter::class)) {
146+
return;
147+
}
148+
149+
self::assertEquals(1, $tester->getStatusCode(), 'Returns 1 in case of error');
150+
self::assertStringMatchesFormat('%A::error file=%s, line=6, col=47::Opening and ending tag mismatch: target line 6 and source%A', trim($tester->getDisplay()));
151+
}
152+
153+
public function testLintAutodetectsGithubActionEnvironment()
154+
{
155+
if (!class_exists(GithubActionReporter::class)) {
156+
$this->markTestSkipped('The "github" format is only available since "symfony/console" >= 5.3.');
157+
}
158+
159+
$prev = getenv('GITHUB_ACTIONS');
160+
putenv('GITHUB_ACTIONS');
161+
162+
try {
163+
putenv('GITHUB_ACTIONS=1');
164+
165+
$filename = $this->createFile('note <target>');
166+
$tester = $this->createCommandTester();
167+
168+
$tester->execute(['filename' => [$filename]], ['decorated' => false]);
169+
self::assertStringMatchesFormat('%A::error file=%s, line=6, col=47::Opening and ending tag mismatch: target line 6 and source%A', trim($tester->getDisplay()));
170+
} finally {
171+
putenv('GITHUB_ACTIONS'.($prev ? "=$prev" : ''));
172+
}
173+
}
174+
132175
private function createFile($sourceContent = 'note', $targetLanguage = 'en', $fileNamePattern = 'messages.%locale%.xlf'): string
133176
{
134177
$xliffContent = <<<XLIFF

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.