git: Add script to check localized texts occurrences in code (#1511)
This script will be executed on every CI run as part of tests, and will
ensure no unlocalised strings are present in the code
Note that texts without the `_lang` suffix will not be checked, e.g.
96fe608d60/plugins/builtin/source/content/views/view_provider_settings.cpp (L10)
This commit is contained in:
parent
e61ee528ff
commit
d86bf44e39
14
.github/workflows/tests.yml
vendored
14
.github/workflows/tests.yml
vendored
@ -61,3 +61,17 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
cd build
|
cd build
|
||||||
ctest --output-on-failure
|
ctest --output-on-failure
|
||||||
|
|
||||||
|
langs:
|
||||||
|
name: 🧪 Langs
|
||||||
|
runs-on: ubuntu-22.04
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: 🧰 Checkout
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
submodules: recursive
|
||||||
|
|
||||||
|
- name: Check langs
|
||||||
|
run:
|
||||||
|
python3 tests/check_langs.py
|
||||||
|
@ -148,6 +148,7 @@
|
|||||||
"hex.builtin.menu.file.import.pattern": "Pattern File",
|
"hex.builtin.menu.file.import.pattern": "Pattern File",
|
||||||
"hex.builtin.menu.file.import.data_processor": "Data Processor Workspace",
|
"hex.builtin.menu.file.import.data_processor": "Data Processor Workspace",
|
||||||
"hex.builtin.menu.file.import.custom_encoding": "Custom Encoding File",
|
"hex.builtin.menu.file.import.custom_encoding": "Custom Encoding File",
|
||||||
|
"hex.builtin.menu.file.import.modified_file.popup.invalid_size": "File selected do not have the same size as the current file. Both sizes must match",
|
||||||
"hex.builtin.menu.file.open_file": "Open File...",
|
"hex.builtin.menu.file.open_file": "Open File...",
|
||||||
"hex.builtin.menu.file.open_other": "Open Other...",
|
"hex.builtin.menu.file.open_other": "Open Other...",
|
||||||
"hex.builtin.menu.file.project": "Project",
|
"hex.builtin.menu.file.project": "Project",
|
||||||
|
@ -205,7 +205,7 @@ namespace hex::plugin::builtin {
|
|||||||
|
|
||||||
// Draw table containing everything that's being reported
|
// Draw table containing everything that's being reported
|
||||||
if (ImGui::CollapsingHeader("hex.builtin.oobe.server_contact.data_collected_title"_lang)) {
|
if (ImGui::CollapsingHeader("hex.builtin.oobe.server_contact.data_collected_title"_lang)) {
|
||||||
if (ImGui::BeginTable("hex.builtin.oobe.server_contact.data_collected_table"_lang, 2,
|
if (ImGui::BeginTable("hex.builtin.oobe.server_contact.data_collected_table", 2,
|
||||||
ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg | ImGuiTableFlags_ScrollY | ImGuiTableFlags_NoHostExtendY,
|
ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg | ImGuiTableFlags_ScrollY | ImGuiTableFlags_NoHostExtendY,
|
||||||
ImVec2(ImGui::GetContentRegionAvail().x, 150_scaled))) {
|
ImVec2(ImGui::GetContentRegionAvail().x, 150_scaled))) {
|
||||||
ImGui::TableSetupColumn("hex.builtin.oobe.server_contact.data_collected_table.key"_lang);
|
ImGui::TableSetupColumn("hex.builtin.oobe.server_contact.data_collected_table.key"_lang);
|
||||||
|
72
tests/check_langs.py
Normal file
72
tests/check_langs.py
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
import json
|
||||||
|
import re
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
SHOW_UNUSED_LANGS = "--unused" in sys.argv
|
||||||
|
|
||||||
|
# use a regex on code to get all "hex.lang.id"_lang occurences
|
||||||
|
def get_lang_occurences_in_code(path):
|
||||||
|
for dir, _, files in os.walk(path):
|
||||||
|
for file in files:
|
||||||
|
|
||||||
|
if not os.path.splitext(file)[1] in (".cpp", ".c", ".hpp", ".h"):
|
||||||
|
continue
|
||||||
|
filepath = os.path.join(dir, file)
|
||||||
|
with open(filepath) as file:
|
||||||
|
for line_num, line in enumerate(file):
|
||||||
|
for m in re.finditer('"([^"]*?)"_lang', line):
|
||||||
|
yield (filepath, line_num+1, m.group(1))
|
||||||
|
|
||||||
|
# Get langs in a specific json file
|
||||||
|
def get_langs(filepath) -> list[str]:
|
||||||
|
if filepath == None:
|
||||||
|
return []
|
||||||
|
elif not os.path.exists(filepath):
|
||||||
|
print(f"Warning: no langs file found at {filepath}")
|
||||||
|
return []
|
||||||
|
|
||||||
|
with open(filepath, "r") as file:
|
||||||
|
data = json.loads(file.read())
|
||||||
|
existing_langs = []
|
||||||
|
|
||||||
|
for key, _ in data["translations"].items():
|
||||||
|
existing_langs.append(key)
|
||||||
|
|
||||||
|
return existing_langs
|
||||||
|
|
||||||
|
def check_langs(code_path, bonus_langs, specific_langs_path):
|
||||||
|
print(f"\n--- Checking langs at {code_path}")
|
||||||
|
|
||||||
|
specific_langs = get_langs(specific_langs_path)
|
||||||
|
unused_langs = specific_langs.copy()
|
||||||
|
ret = True
|
||||||
|
|
||||||
|
for filepath, line, match in get_lang_occurences_in_code(code_path):
|
||||||
|
try:
|
||||||
|
unused_langs.remove(match)
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
if not match in bonus_langs + specific_langs:
|
||||||
|
ret = False
|
||||||
|
print(f"Problem: Lang '{match}' at {filepath}:{line} not found")
|
||||||
|
|
||||||
|
if SHOW_UNUSED_LANGS and len(unused_langs) > 0:
|
||||||
|
print(f"Unused langs in {specific_langs_path}:")
|
||||||
|
for unused_lang in unused_langs:
|
||||||
|
print(unused_lang)
|
||||||
|
return ret
|
||||||
|
|
||||||
|
|
||||||
|
ui_langs = get_langs("./plugins/ui/romfs/lang/en_US.json")
|
||||||
|
|
||||||
|
exit_ok = True
|
||||||
|
exit_ok &= check_langs("./main", ui_langs, None)
|
||||||
|
|
||||||
|
for plugin in os.listdir("./plugins"):
|
||||||
|
if plugin == "ui": continue
|
||||||
|
exit_ok &= check_langs(f"./plugins/{plugin}", ui_langs, f"./plugins/{plugin}/romfs/lang/en_US.json")
|
||||||
|
|
||||||
|
sys.exit(0 if exit_ok else 1)
|
Loading…
Reference in New Issue
Block a user