From 464db126a551639b036c4a5e4e494684c68f56f2 Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Tue, 19 Jul 2022 12:38:58 -0700 Subject: [PATCH] Multilanguage: readme improvements (#25214) * catch2 needs to iterate through the whole function each time to test this (spams warnings) * Update readme * Add update the ui header * build in scons * release by default * scons in another pr Co-authored-by: Vincent Wright --- selfdrive/ui/tests/test_translations.cc | 30 +++++++++++-------------- selfdrive/ui/tests/test_translations.py | 11 +++++---- selfdrive/ui/translations/README.md | 21 ++++++++++++----- selfdrive/ui/update_translations.py | 10 ++++----- 4 files changed, 38 insertions(+), 34 deletions(-) diff --git a/selfdrive/ui/tests/test_translations.cc b/selfdrive/ui/tests/test_translations.cc index ba0612b4c0..fcefc5784f 100644 --- a/selfdrive/ui/tests/test_translations.cc +++ b/selfdrive/ui/tests/test_translations.cc @@ -17,25 +17,21 @@ QStringList getParentWidgets(QWidget* widget){ template void checkWidgetTrWrap(MainWindow &w) { - int i = 0; for (auto widget : w.findChildren()) { - const QString text = widget->text(); - SECTION(text.toStdString() + "-" + std::to_string(i)) { - bool isNumber = RE_NUM.exactMatch(text); - bool wrapped = text.contains(TEST_TEXT); - QString parentWidgets = getParentWidgets(widget).join("->"); - - if (!text.isEmpty() && !isNumber && !wrapped) { - FAIL(("\"" + text + "\" must be wrapped. Parent widgets: " + parentWidgets).toStdString()); - } - - // warn if source string wrapped, but UI adds text - // TODO: add way to ignore this - if (wrapped && text != TEST_TEXT) { - WARN(("\"" + text + "\" is dynamic and needs a custom retranslate function. Parent widgets: " + parentWidgets).toStdString()); - } + const QString text = widget->text(); + bool isNumber = RE_NUM.exactMatch(text); + bool wrapped = text.contains(TEST_TEXT); + QString parentWidgets = getParentWidgets(widget).join("->"); + + if (!text.isEmpty() && !isNumber && !wrapped) { + FAIL(("\"" + text + "\" must be wrapped. Parent widgets: " + parentWidgets).toStdString()); + } + + // warn if source string wrapped, but UI adds text + // TODO: add way to ignore this + if (wrapped && text != TEST_TEXT) { + WARN(("\"" + text + "\" is dynamic and needs a custom retranslate function. Parent widgets: " + parentWidgets).toStdString()); } - i++; } } diff --git a/selfdrive/ui/tests/test_translations.py b/selfdrive/ui/tests/test_translations.py index d5409dd416..59751eec19 100755 --- a/selfdrive/ui/tests/test_translations.py +++ b/selfdrive/ui/tests/test_translations.py @@ -35,13 +35,12 @@ class TestTranslations(unittest.TestCase): if not len(file): self.skipTest(f"{name} translation has no defined file") - self.assertTrue(os.path.exists(os.path.join(TRANSLATIONS_DIR, f"{file}.ts")), - f"{name} has no XML translation file, run selfdrive/ui/update_translations.py") - self.assertTrue(os.path.exists(os.path.join(TRANSLATIONS_DIR, f"{file}.qm")), - f"{name} has no compiled QM translation file, run selfdrive/ui/update_translations.py --release") + if not (os.path.exists(os.path.join(TRANSLATIONS_DIR, f"{file}.ts")) and + os.path.exists(os.path.join(TRANSLATIONS_DIR, f"{file}.qm"))): + self.fail(f"{name} is missing translation files, run selfdrive/ui/update_translations.py") def test_translations_updated(self): - update_translations(release=True, translations_dir=TMP_TRANSLATIONS_DIR) + update_translations(translations_dir=TMP_TRANSLATIONS_DIR) for name, file in self.translation_files.items(): with self.subTest(name=name, file=file): @@ -59,7 +58,7 @@ class TestTranslations(unittest.TestCase): new_translations = self._read_translation_file(TMP_TRANSLATIONS_DIR, file, file_ext) self.assertEqual(cur_translations, new_translations, - f"{file} ({name}) {file_ext.upper()} translation file out of date. Run selfdrive/ui/update_translations.py --release to update the translation files") + f"{file} ({name}) {file_ext.upper()} translation file out of date. Run selfdrive/ui/update_translations.py to update the translation files") @unittest.skip("Only test unfinished translations before going to release") def test_unfinished_translations(self): diff --git a/selfdrive/ui/translations/README.md b/selfdrive/ui/translations/README.md index 0ddb03a24c..4038b1e0ce 100644 --- a/selfdrive/ui/translations/README.md +++ b/selfdrive/ui/translations/README.md @@ -1,7 +1,5 @@ # Multilanguage -![multilanguage_onroad](https://user-images.githubusercontent.com/25857203/178912800-2c798af8-78e3-498e-9e19-35906e0bafff.png) - ## Contributing Before getting started, make sure you have set up the openpilot Ubuntu development environment by reading the [tools README.md](/tools/README.md). @@ -28,12 +26,25 @@ openpilot provides a few tools to help contributors manage their translations an Follow the steps above, omitting steps 1. and 2. Any time you edit translations you'll want to make sure to compile them. +### Updating the UI + +Any time you edit source code in the UI, you need to update and compile the translations to ensure the line numbers and contexts are up to date (last step above). + ### Testing -openpilot has a unit test to make sure all translations are up to date with the text in openpilot and that all translations are completed. +openpilot has a few unit tests to make sure all translations are up to date and that all strings are wrapped in a translation marker. -Run and fix any issues: +Tests translation files up to date: -```python +```shell selfdrive/ui/tests/test_translations.py ``` + +Tests all static source strings are wrapped: + +```shell +selfdrive/ui/tests/create_test_translations.sh && selfdrive/ui/tests/test_translations +``` + +--- +![multilanguage_onroad](https://user-images.githubusercontent.com/25857203/178912800-2c798af8-78e3-498e-9e19-35906e0bafff.png) diff --git a/selfdrive/ui/update_translations.py b/selfdrive/ui/update_translations.py index f06d54b2d5..5ccae0eb02 100755 --- a/selfdrive/ui/update_translations.py +++ b/selfdrive/ui/update_translations.py @@ -10,7 +10,7 @@ TRANSLATIONS_DIR = os.path.join(UI_DIR, "translations") LANGUAGES_FILE = os.path.join(TRANSLATIONS_DIR, "languages.json") -def update_translations(release=False, vanish=False, translations_dir=TRANSLATIONS_DIR): +def update_translations(vanish=False, translations_dir=TRANSLATIONS_DIR): with open(LANGUAGES_FILE, "r") as f: translation_files = json.load(f) @@ -26,16 +26,14 @@ def update_translations(release=False, vanish=False, translations_dir=TRANSLATIO ret = os.system(args) assert ret == 0 - if release: - ret = os.system(f"lrelease {tr_file}") - assert ret == 0 + ret = os.system(f"lrelease {tr_file}") + assert ret == 0 if __name__ == "__main__": parser = argparse.ArgumentParser(description="Update translation files for UI", formatter_class=argparse.ArgumentDefaultsHelpFormatter) - parser.add_argument("--release", action="store_true", help="Create compiled QM translation files used by UI") parser.add_argument("--vanish", action="store_true", help="Remove translations with source text no longer found") args = parser.parse_args() - update_translations(args.release, args.vanish) + update_translations(args.vanish)