From 8ac2b2a05aeee7c70748c3662a0ac73938ae80b7 Mon Sep 17 00:00:00 2001 From: YaFou <33806646+YaFou@users.noreply.github.com> Date: Thu, 14 Jan 2021 11:33:26 +0100 Subject: [PATCH] [Translation] XliffLintCommand supports Github Actions annotations --- .../Component/Translation/CHANGELOG.md | 6 +++++ .../Translation/Command/XliffLintCommand.php | 22 ++++++++++++--- .../Tests/Command/XliffLintCommandTest.php | 27 +++++++++++++++++++ .../Component/Translation/composer.json | 3 ++- 4 files changed, 53 insertions(+), 5 deletions(-) diff --git a/src/Symfony/Component/Translation/CHANGELOG.md b/src/Symfony/Component/Translation/CHANGELOG.md index 3341328a92d0..74b63c9b2e4f 100644 --- a/src/Symfony/Component/Translation/CHANGELOG.md +++ b/src/Symfony/Component/Translation/CHANGELOG.md @@ -1,6 +1,12 @@ CHANGELOG ========= +5.4 +--- + +* Add `github` format & autodetection to render errors as annotations when + running the XLIFF linter command in a Github Actions environment. + 5.3 --- diff --git a/src/Symfony/Component/Translation/Command/XliffLintCommand.php b/src/Symfony/Component/Translation/Command/XliffLintCommand.php index 4117d87c855e..64977e5c629a 100644 --- a/src/Symfony/Component/Translation/Command/XliffLintCommand.php +++ b/src/Symfony/Component/Translation/Command/XliffLintCommand.php @@ -11,6 +11,7 @@ namespace Symfony\Component\Translation\Command; +use Symfony\Component\Console\CI\GithubActionReporter; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Exception\RuntimeException; use Symfony\Component\Console\Input\InputArgument; @@ -56,7 +57,7 @@ protected function configure() $this ->setDescription(self::$defaultDescription) ->addArgument('filename', InputArgument::IS_ARRAY, 'A file, a directory or "-" for reading from STDIN') - ->addOption('format', null, InputOption::VALUE_REQUIRED, 'The output format', 'txt') + ->addOption('format', null, InputOption::VALUE_REQUIRED, 'The output format') ->setHelp(<<%command.name% command lints an XLIFF file and outputs to STDOUT the first encountered syntax error. @@ -86,6 +87,10 @@ protected function execute(InputInterface $input, OutputInterface $output) $this->format = $input->getOption('format'); $this->displayCorrectFiles = $output->isVerbose(); + if (null === $this->format) { + $this->format = GithubActionReporter::isGithubActionEnvironment() ? 'github' : 'txt'; + } + if (['-'] === $filenames) { return $this->display($io, [$this->validate(file_get_contents('php://stdin'))]); } @@ -160,15 +165,18 @@ private function display(SymfonyStyle $io, array $files) return $this->displayTxt($io, $files); case 'json': return $this->displayJson($io, $files); + case 'github': + return $this->displayTxt($io, $files, true); default: throw new InvalidArgumentException(sprintf('The format "%s" is not supported.', $this->format)); } } - private function displayTxt(SymfonyStyle $io, array $filesInfo) + private function displayTxt(SymfonyStyle $io, array $filesInfo, bool $errorAsGithubAnnotations = false) { $countFiles = \count($filesInfo); $erroredFiles = 0; + $githubReporter = $errorAsGithubAnnotations ? new GithubActionReporter($io) : null; foreach ($filesInfo as $info) { if ($info['valid'] && $this->displayCorrectFiles) { @@ -176,9 +184,15 @@ private function displayTxt(SymfonyStyle $io, array $filesInfo) } elseif (!$info['valid']) { ++$erroredFiles; $io->text(' ERROR '.($info['file'] ? sprintf(' in %s', $info['file']) : '')); - $io->listing(array_map(function ($error) { + $io->listing(array_map(function ($error) use ($info, $githubReporter) { // general document errors have a '-1' line number - return -1 === $error['line'] ? $error['message'] : sprintf('Line %d, Column %d: %s', $error['line'], $error['column'], $error['message']); + $line = -1 === $error['line'] ? null : $error['line']; + + if ($githubReporter) { + $githubReporter->error($error['message'], $info['file'], $line, null !== $line ? $error['column'] : null); + } + + return null === $line ? $error['message'] : sprintf('Line %d, Column %d: %s', $line, $error['column'], $error['message']); }, $info['messages'])); } } diff --git a/src/Symfony/Component/Translation/Tests/Command/XliffLintCommandTest.php b/src/Symfony/Component/Translation/Tests/Command/XliffLintCommandTest.php index 176bada55d8e..eb3fba3d1e2c 100644 --- a/src/Symfony/Component/Translation/Tests/Command/XliffLintCommandTest.php +++ b/src/Symfony/Component/Translation/Tests/Command/XliffLintCommandTest.php @@ -140,6 +140,33 @@ public function testGetHelp() $this->assertStringContainsString($expected, $command->getHelp()); } + public function testLintIncorrectFileWithGithubFormat() + { + $filename = $this->createFile('note '); + $tester = $this->createCommandTester(); + $tester->execute(['filename' => [$filename], '--format' => 'github'], ['decorated' => false]); + self::assertEquals(1, $tester->getStatusCode(), 'Returns 1 in case of error'); + self::assertStringMatchesFormat('%A::error file=%s,line=6,col=47::Opening and ending tag mismatch: target line 6 and source%A', trim($tester->getDisplay())); + } + + public function testLintAutodetectsGithubActionEnvironment() + { + $prev = getenv('GITHUB_ACTIONS'); + putenv('GITHUB_ACTIONS'); + + try { + putenv('GITHUB_ACTIONS=1'); + + $filename = $this->createFile('note '); + $tester = $this->createCommandTester(); + + $tester->execute(['filename' => [$filename]], ['decorated' => false]); + self::assertStringMatchesFormat('%A::error file=%s,line=6,col=47::Opening and ending tag mismatch: target line 6 and source%A', trim($tester->getDisplay())); + } finally { + putenv('GITHUB_ACTIONS'.($prev ? "=$prev" : '')); + } + } + private function createFile($sourceContent = 'note', $targetLanguage = 'en', $fileNamePattern = 'messages.%locale%.xlf'): string { $xliffContent = <<