Skip to content

Commit

Permalink
minor #30237 [Translation] Added a script to display the status of tr…
Browse files Browse the repository at this point in the history
…anslations (javiereguiluz)

This PR was squashed before being merged into the 3.4 branch (closes #30237).

Discussion
----------

[Translation] Added a script to display the status of translations

| Q             | A
| ------------- | ---
| Branch?       | 3.4
| Bug fix?      | no
| New feature?  | no <!-- don't forget to update src/**/CHANGELOG.md files -->
| BC breaks?    | no     <!-- see https://symfony.com/bc -->
| Deprecations? | no <!-- don't forget to update UPGRADE-*.md and src/**/CHANGELOG.md files -->
| Tests pass?   | yes    <!-- please add some, will be required by reviewers -->
| Fixed tickets | -
| License       | MIT
| Doc PR        | -

This is the script I used to get the missing translations for each locale. I think it could come in handy for Symfony to always keep translations in sync.

Commits
-------

5ca7ded [Translation] Added a script to display the status of translations
  • Loading branch information
fabpot committed Feb 18, 2019
2 parents 3315c8e + 5ca7ded commit 1f829ec
Showing 1 changed file with 195 additions and 0 deletions.
195 changes: 195 additions & 0 deletions src/Symfony/Component/Translation/Resources/bin/translation-status.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

$usageInstructions = <<<END
Usage instructions
-------------------------------------------------------------------------------
$ cd symfony-code-root-directory/
# show the translation status of all locales
$ php translation-status.php
# show the translation status of all locales and all their missing translations
$ php translation-status.php -v
# show the status of a single locale
$ php translation-status.php fr
# show the status of a single locale and all its missing translations
$ php translation-status.php fr -v
END;

$config = [
// if TRUE, the full list of missing translations is displayed
'verbose_output' => false,
// NULL = analyze all locales
'locale_to_analyze' => null,
// the reference files all the other translations are compared to
'original_files' => [
'src/Symfony/Component/Form/Resources/translations/validators.en.xlf',
'src/Symfony/Component/Security/Core/Resources/translations/security.en.xlf',
'src/Symfony/Component/Validator/Resources/translations/validators.en.xlf',
],
];

$argc = $_SERVER['argc'];
$argv = $_SERVER['argv'];

if ($argc > 3) {
echo str_replace('translation-status.php', $argv[0], $usageInstructions);
exit(1);
}

foreach (array_slice($argv, 1) as $argumentOrOption) {
if (0 === strpos($argumentOrOption, '-')) {
$config['verbose_output'] = true;
} else {
$config['locale_to_analyze'] = $argumentOrOption;
}
}

foreach ($config['original_files'] as $originalFilePath) {
if (!file_exists($originalFilePath)) {
echo sprintf('The following file does not exist. Make sure that you execute this command at the root dir of the Symfony code repository.%s %s', PHP_EOL, $originalFilePath);
exit(1);
}
}

$totalMissingTranslations = 0;

foreach ($config['original_files'] as $originalFilePath) {
$translationFilePaths = findTranslationFiles($originalFilePath, $config['locale_to_analyze']);
$translationStatus = calculateTranslationStatus($originalFilePath, $translationFilePaths);

$totalMissingTranslations += array_sum(array_map(function ($translation) {
return \count($translation['missingKeys']);
}, array_values($translationStatus)));

printTranslationStatus($originalFilePath, $translationStatus, $config['verbose_output']);
}

exit($totalMissingTranslations > 0 ? 1 : 0);

function findTranslationFiles($originalFilePath, $localeToAnalyze)
{
$translations = [];

$translationsDir = dirname($originalFilePath);
$originalFileName = basename($originalFilePath);
$translationFileNamePattern = str_replace('.en.', '.*.', $originalFileName);

$translationFiles = glob($translationsDir.'/'.$translationFileNamePattern);
foreach ($translationFiles as $filePath) {
$locale = extractLocaleFromFilePath($filePath);

if (null !== $localeToAnalyze && $locale !== $localeToAnalyze) {
continue;
}

$translations[$locale] = $filePath;
}

return $translations;
}

function calculateTranslationStatus($originalFilePath, $translationFilePaths)
{
$translationStatus = [];
$allTranslationKeys = extractTranslationKeys($originalFilePath);

foreach ($translationFilePaths as $locale => $translationPath) {
$translatedKeys = extractTranslationKeys($translationPath);
$missingKeys = array_diff_key($allTranslationKeys, $translatedKeys);

$translationStatus[$locale] = [
'total' => \count($allTranslationKeys),
'translated' => \count($translatedKeys),
'missingKeys' => $missingKeys,
];
}

return $translationStatus;
}

function printTranslationStatus($originalFilePath, $translationStatus, $verboseOutput)
{
printTitle($originalFilePath);
printTable($translationStatus, $verboseOutput);
echo PHP_EOL.PHP_EOL;
}

function extractLocaleFromFilePath($filePath)
{
$parts = explode('.', $filePath);

return $parts[count($parts) - 2];
}

function extractTranslationKeys($filePath)
{
$translationKeys = [];
$contents = new \SimpleXMLElement(file_get_contents($filePath));

foreach ($contents->file->body->{'trans-unit'} as $translationKey) {
$translationId = (string) $translationKey['id'];
$translationKey = (string) $translationKey->source;

$translationKeys[$translationId] = $translationKey;
}

return $translationKeys;
}

function printTitle($title)
{
echo $title.PHP_EOL;
echo str_repeat('=', strlen($title)).PHP_EOL.PHP_EOL;
}

function printTable($translations, $verboseOutput)
{
$longestLocaleNameLength = max(array_map('strlen', array_keys($translations)));

foreach ($translations as $locale => $translation) {
$isTranslationCompleted = $translation['translated'] === $translation['total'];
if ($isTranslationCompleted) {
textColorGreen();
}

echo sprintf('| Locale: %-'.$longestLocaleNameLength.'s | Translated: %d/%d', $locale, $translation['translated'], $translation['total']).PHP_EOL;

textColorNormal();

if (true === $verboseOutput && \count($translation['missingKeys']) > 0) {
echo str_repeat('-', 80).PHP_EOL;
echo '| Missing Translations:'.PHP_EOL;

foreach ($translation['missingKeys'] as $id => $content) {
echo sprintf('| (id=%s) %s', $id, $content).PHP_EOL;
}

echo str_repeat('-', 80).PHP_EOL;
}
}
}

function textColorGreen()
{
echo "\033[32m";
}

function textColorNormal()
{
echo "\033[0m";
}

0 comments on commit 1f829ec

Please sign in to comment.