aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.travis.yml20
-rw-r--r--tools/check.translation.php127
-rw-r--r--tools/translation.ignore.php58
3 files changed, 201 insertions, 4 deletions
diff --git a/.travis.yml b/.travis.yml
index 5c43e5666..945e77a74 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -14,16 +14,27 @@ install:
script:
- phpenv rehash
- - phpcs . --standard=phpcs.xml --warning-severity=0 --extensions=php -p
+ - |
+ if [[ $VALIDATE_STANDARD == yes ]]; then
+ phpcs . --standard=phpcs.xml --warning-severity=0 --extensions=php -p
+ fi
+ - |
+ if [[ $CHECK_TRANSLATION == yes ]]; then
+ php tools/check.translation.php -r
+ fi
+
+env:
+ - CHECK_TRANSLATION=no VALIDATE_STANDARD=yes
-env: # important! otherwise no job will be allowed to fail
matrix:
- # PHP 5.3 only runs on Ubuntu 12.04 (precise), not 14.04 (trusty)
+ fast_finish: true
include:
- php: "5.3"
dist: precise
- fast_finish: true
+ - php: "7.1"
+ env: CHECK_TRANSLATION=yes VALIDATE_STANDARD=no
allow_failures:
+ # PHP 5.3 only runs on Ubuntu 12.04 (precise), not 14.04 (trusty)
- php: "5.3"
dist: precise
- php: "5.4"
@@ -32,3 +43,4 @@ matrix:
- php: "7.0"
- php: hhvm
- php: nightly
+ - env: CHECK_TRANSLATION=yes VALIDATE_STANDARD=no
diff --git a/tools/check.translation.php b/tools/check.translation.php
new file mode 100644
index 000000000..7854e131f
--- /dev/null
+++ b/tools/check.translation.php
@@ -0,0 +1,127 @@
+<?php
+
+$options = getopt("dhl:r");
+
+$ignore = include __DIR__ . '/translation.ignore.php';
+
+if (array_key_exists('h', $options)) {
+ help();
+}
+if (array_key_exists('l', $options)) {
+ $langPattern = sprintf('/%s/', $options['l']);
+} else {
+ $langPattern = '/*/';
+}
+$displayErrors = array_key_exists('d', $options);
+$displayReport = array_key_exists('r', $options);
+
+$i18nPath = __DIR__ . '/../app/i18n/';
+$errors = array();
+$report = array();
+
+foreach (glob($i18nPath . 'en/*.php') as $i18nFileReference) {
+ $en = flatten(include $i18nFileReference);
+ foreach (glob(str_replace('/en/', $langPattern, $i18nFileReference)) as $i18nFile) {
+ preg_match('#(?P<lang>[^/]+)/(?P<file>[^/]*.php)#', $i18nFile, $matches);
+ $lang = $matches['lang'];
+ $file = $matches['file'];
+ if ('en' === $lang) {
+ continue;
+ }
+ if (!array_key_exists($lang, $report)) {
+ $report[$lang]['total'] = 0;
+ $report[$lang]['errors'] = 0;
+ }
+ $i18n = flatten(include $i18nFile);
+ foreach ($en as $key => $value) {
+ $report[$lang]['total'] ++;
+ if (array_key_exists($lang, $ignore) && array_key_exists($file, $ignore[$lang]) && in_array($key, $ignore[$lang][$file])) {
+ continue;
+ }
+ if (!array_key_exists($key, $i18n)) {
+ $errors[$lang][$file][] = sprintf('Missing key %s', $key);
+ $report[$lang]['errors'] ++;
+ continue;
+ }
+ if ($i18n[$key] === $value) {
+ $errors[$lang][$file][] = sprintf('Untranslated key %s - %s', $key, $value);
+ $report[$lang]['errors'] ++;
+ continue;
+ }
+ }
+ }
+}
+
+if ($displayErrors) {
+ foreach ($errors as $lang => $value) {
+ echo 'Language: ', $lang, PHP_EOL;
+ foreach ($value as $file => $messages) {
+ echo ' - File: ', $file, PHP_EOL;
+ foreach ($messages as $message) {
+ echo ' - ', $message, PHP_EOL;
+ }
+ }
+ echo PHP_EOL;
+ }
+}
+
+if ($displayReport) {
+ foreach ($report as $lang => $value) {
+ $completion = ($value['total'] - $value['errors']) / $value['total'] * 100;
+ echo sprintf('Translation for %-5s is %5.1f%% complete.', $lang, $completion), PHP_EOL;
+ }
+}
+
+if (!empty($errors)) {
+ exit(1);
+}
+
+/**
+ * Flatten an array of translation
+ *
+ * @param array $translation
+ * @param string $prependKey
+ * @return array
+ */
+function flatten($translation, $prependKey = '') {
+ $a = array();
+
+ if ('' !== $prependKey) {
+ $prependKey .= '.';
+ }
+
+ foreach ($translation as $key => $value) {
+ if (is_array($value)) {
+ $a += flatten($value, $prependKey . $key);
+ } else {
+ $a[$prependKey . $key] = $value;
+ }
+ }
+
+ return $a;
+}
+
+/**
+ * Output help message.
+ */
+function help() {
+ $help = <<<HELP
+NAME
+ %s
+
+SYNOPSIS
+ php %s [OPTION]...
+
+DESCRIPTION
+ Check if translation files have missing keys or missing translations.
+
+ -d display results.
+ -h display this help and exit.
+ -l=LANG filter by LANG.
+ -r display completion report.
+
+HELP;
+ $file = str_replace(__DIR__ . '/', '', __FILE__);
+ echo sprintf($help, $file, $file);
+ exit;
+}
diff --git a/tools/translation.ignore.php b/tools/translation.ignore.php
new file mode 100644
index 000000000..a05f36267
--- /dev/null
+++ b/tools/translation.ignore.php
@@ -0,0 +1,58 @@
+<?php
+
+$ignore = array();
+
+// ignore for FR
+$ignore['fr']['admin.php'][] = 'extensions.title';
+$ignore['fr']['admin.php'][] = 'stats.number_entries';
+$ignore['fr']['admin.php'][] = 'user.articles_and_size';
+$ignore['fr']['conf.php'][] = 'display.width.large';
+$ignore['fr']['conf.php'][] = 'sharing.blogotext';
+$ignore['fr']['conf.php'][] = 'sharing.diaspora';
+$ignore['fr']['conf.php'][] = 'sharing.facebook';
+$ignore['fr']['conf.php'][] = 'sharing.g+';
+$ignore['fr']['conf.php'][] = 'sharing.print';
+$ignore['fr']['conf.php'][] = 'sharing.shaarli';
+$ignore['fr']['conf.php'][] = 'sharing.twitter';
+$ignore['fr']['conf.php'][] = 'sharing.wallabag';
+$ignore['fr']['conf.php'][] = 'shortcut.navigation';
+$ignore['fr']['conf.php'][] = 'user.articles_and_size';
+$ignore['fr']['gen.php'][] = 'freshrss._';
+$ignore['fr']['gen.php'][] = 'lang.cz';
+$ignore['fr']['gen.php'][] = 'lang.de';
+$ignore['fr']['gen.php'][] = 'lang.en';
+$ignore['fr']['gen.php'][] = 'lang.es';
+$ignore['fr']['gen.php'][] = 'lang.fr';
+$ignore['fr']['gen.php'][] = 'lang.it';
+$ignore['fr']['gen.php'][] = 'lang.kr';
+$ignore['fr']['gen.php'][] = 'lang.nl';
+$ignore['fr']['gen.php'][] = 'lang.pt-br';
+$ignore['fr']['gen.php'][] = 'lang.ru';
+$ignore['fr']['gen.php'][] = 'lang.tr';
+$ignore['fr']['gen.php'][] = 'lang.zh-cn';
+$ignore['fr']['gen.php'][] = 'menu.admin';
+$ignore['fr']['gen.php'][] = 'menu.configuration';
+$ignore['fr']['gen.php'][] = 'menu.extensions';
+$ignore['fr']['gen.php'][] = 'menu.logs';
+$ignore['fr']['gen.php'][] = 'share.blogotext';
+$ignore['fr']['gen.php'][] = 'share.diaspora';
+$ignore['fr']['gen.php'][] = 'share.facebook';
+$ignore['fr']['gen.php'][] = 'share.g+';
+$ignore['fr']['gen.php'][] = 'share.movim';
+$ignore['fr']['gen.php'][] = 'share.shaarli';
+$ignore['fr']['gen.php'][] = 'share.twitter';
+$ignore['fr']['gen.php'][] = 'share.wallabag';
+$ignore['fr']['gen.php'][] = 'share.wallabagv2';
+$ignore['fr']['gen.php'][] = 'share.jdh';
+$ignore['fr']['gen.php'][] = 'share.gnusocial';
+$ignore['fr']['index.php'][] = 'about.agpl3';
+$ignore['fr']['index.php'][] = 'about.version';
+$ignore['fr']['index.php'][] = 'log._';
+$ignore['fr']['index.php'][] = 'log.title';
+$ignore['fr']['install.php'][] = 'title';
+$ignore['fr']['install.php'][] = 'this_is_the_end';
+$ignore['fr']['sub.php'][] = 'bookmarklet.title';
+$ignore['fr']['sub.php'][] = 'feed.description';
+$ignore['fr']['sub.php'][] = 'feed.number_entries';
+
+return $ignore;