From 0ee912dbd876c0bdc4944c6819cca99e838c3af8 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Wed, 20 Jun 2018 15:10:07 +0200 Subject: [PATCH] [Translation] Added support for translation files with other filename patterns --- .../Translation/Command/XliffLintCommand.php | 14 ++++--- .../Tests/Command/XliffLintCommandTest.php | 39 ++++++++++++++++--- 2 files changed, 43 insertions(+), 10 deletions(-) diff --git a/src/Symfony/Component/Translation/Command/XliffLintCommand.php b/src/Symfony/Component/Translation/Command/XliffLintCommand.php index 2caa6abefbcf7..751971616ea5e 100644 --- a/src/Symfony/Component/Translation/Command/XliffLintCommand.php +++ b/src/Symfony/Component/Translation/Command/XliffLintCommand.php @@ -33,13 +33,15 @@ class XliffLintCommand extends Command private $displayCorrectFiles; private $directoryIteratorProvider; private $isReadableProvider; + private $requireStrictFileNames; - public function __construct(string $name = null, callable $directoryIteratorProvider = null, callable $isReadableProvider = null) + public function __construct(string $name = null, callable $directoryIteratorProvider = null, callable $isReadableProvider = null, bool $requireStrictFileNames = true) { parent::__construct($name); $this->directoryIteratorProvider = $directoryIteratorProvider; $this->isReadableProvider = $isReadableProvider; + $this->requireStrictFileNames = $requireStrictFileNames; } /** @@ -115,14 +117,16 @@ private function validate($content, $file = null) $document->loadXML($content); if (null !== $targetLanguage = $this->getTargetLanguageFromFile($document)) { - $expectedFileExtension = sprintf('%s.xlf', str_replace('-', '_', $targetLanguage)); - $realFileExtension = explode('.', basename($file), 2)[1] ?? ''; + $normalizedLocale = preg_quote(str_replace('-', '_', $targetLanguage), '/'); + // strict file names require translation files to be named '____.locale.xlf' + // otherwise, both '____.locale.xlf' and 'locale.____.xlf' are allowed + $expectedFilenamePattern = $this->requireStrictFileNames ? sprintf('/^.*\.%s\.xlf/', $normalizedLocale) : sprintf('/^(.*\.%s\.xlf|%s\..*\.xlf)/', $normalizedLocale, $normalizedLocale); - if ($expectedFileExtension !== $realFileExtension) { + if (0 === preg_match($expectedFilenamePattern, basename($file))) { $errors[] = array( 'line' => -1, 'column' => -1, - 'message' => sprintf('There is a mismatch between the file extension ("%s") and the "%s" value used in the "target-language" attribute of the file.', $realFileExtension, $targetLanguage), + 'message' => sprintf('There is a mismatch between the language included in the file name ("%s") and the "%s" value used in the "target-language" attribute of the file.', basename($file), $targetLanguage), ); } } diff --git a/src/Symfony/Component/Translation/Tests/Command/XliffLintCommandTest.php b/src/Symfony/Component/Translation/Tests/Command/XliffLintCommandTest.php index e37600c3ebb87..8b1187ae26e00 100644 --- a/src/Symfony/Component/Translation/Tests/Command/XliffLintCommandTest.php +++ b/src/Symfony/Component/Translation/Tests/Command/XliffLintCommandTest.php @@ -40,6 +40,23 @@ public function testLintCorrectFile() $this->assertContains('OK', trim($tester->getDisplay())); } + /** + * @dataProvider provideStrictFilenames + */ + public function testStrictFilenames($requireStrictFileNames, $fileNamePattern, $targetLanguage, $mustFail) + { + $tester = $this->createCommandTester($requireStrictFileNames); + $filename = $this->createFile('note', $targetLanguage, $fileNamePattern); + + $tester->execute( + array('filename' => $filename), + array('verbosity' => OutputInterface::VERBOSITY_VERBOSE, 'decorated' => false) + ); + + $this->assertEquals($mustFail ? 1 : 0, $tester->getStatusCode()); + $this->assertContains($mustFail ? '[WARNING] 0 XLIFF files have valid syntax and 1 contain errors.' : '[OK] All 1 XLIFF files contain valid syntax.', $tester->getDisplay()); + } + public function testLintIncorrectXmlSyntax() { $tester = $this->createCommandTester(); @@ -59,7 +76,7 @@ public function testLintIncorrectTargetLanguage() $tester->execute(array('filename' => $filename), array('decorated' => false)); $this->assertEquals(1, $tester->getStatusCode(), 'Returns 1 in case of error'); - $this->assertContains('There is a mismatch between the file extension ("en.xlf") and the "es" value used in the "target-language" attribute of the file.', trim($tester->getDisplay())); + $this->assertContains('There is a mismatch between the language included in the file name ("messages.en.xlf") and the "es" value used in the "target-language" attribute of the file.', trim($tester->getDisplay())); } /** @@ -102,7 +119,7 @@ public function testGetHelp() /** * @return string Path to the new file */ - private function createFile($sourceContent = 'note', $targetLanguage = 'en') + private function createFile($sourceContent = 'note', $targetLanguage = 'en', $fileNamePattern = 'messages.%locale%.xlf') { $xliffContent = << @@ -118,7 +135,7 @@ private function createFile($sourceContent = 'note', $targetLanguage = 'en') XLIFF; - $filename = sprintf('%s/translation-xliff-lint-test/messages.en.xlf', sys_get_temp_dir()); + $filename = sprintf('%s/translation-xliff-lint-test/%s', sys_get_temp_dir(), str_replace('%locale%', 'en', $fileNamePattern)); file_put_contents($filename, $xliffContent); $this->files[] = $filename; @@ -129,11 +146,11 @@ private function createFile($sourceContent = 'note', $targetLanguage = 'en') /** * @return CommandTester */ - private function createCommandTester($application = null) + private function createCommandTester($requireStrictFileNames = true, $application = null) { if (!$application) { $application = new Application(); - $application->add(new XliffLintCommand()); + $application->add(new XliffLintCommand(null, null, null, $requireStrictFileNames)); } $command = $application->find('lint:xliff'); @@ -160,4 +177,16 @@ protected function tearDown() } rmdir(sys_get_temp_dir().'/translation-xliff-lint-test'); } + + public function provideStrictFilenames() + { + yield array(false, 'messages.%locale%.xlf', 'en', false); + yield array(false, 'messages.%locale%.xlf', 'es', true); + yield array(false, '%locale%.messages.xlf', 'en', false); + yield array(false, '%locale%.messages.xlf', 'es', true); + yield array(true, 'messages.%locale%.xlf', 'en', false); + yield array(true, 'messages.%locale%.xlf', 'es', true); + yield array(true, '%locale%.messages.xlf', 'en', true); + yield array(true, '%locale%.messages.xlf', 'es', true); + } }