Merge pull request #8804 from furo321/validate-languages-ci

Validate language files for `…` and non-matching formatters in CI
This commit is contained in:
Dennis Felsing 2024-08-24 23:15:05 +00:00 committed by GitHub
commit cd3e85f532
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 65 additions and 28 deletions

View file

@ -40,6 +40,8 @@ jobs:
run: scripts/fix_style.py --dry-run run: scripts/fix_style.py --dry-run
- name: Check header guards - name: Check header guards
run: scripts/check_header_guards.py run: scripts/check_header_guards.py
- name: Validate Languages
run: scripts/languages/validate.py
- name: Check languages - name: Check languages
run: scripts/languages/update_all.py run: scripts/languages/update_all.py
- name: Check dilated images - name: Check dilated images

View file

@ -1027,7 +1027,7 @@ Existing Player
== ﺩﻮﺟﻮﻣ ﺐﻋﻼﻟﺍ == ﺩﻮﺟﻮﻣ ﺐﻋﻼﻟﺍ
Your nickname '%s' is already used (%d points). Do you still want to use it? Your nickname '%s' is already used (%d points). Do you still want to use it?
== ﻪﻣﺍﺪﺨﺘﺳﺍ ﺪﻳﺮﺗ ﺖﻟﺯﺎﻣ ﻞﻫ '%s' ﻞﻤﻌﺘﺴﻣ ﻚﻤﺳﺍ ==
Checking for existing player with your name Checking for existing player with your name
== ﻚﻤﺳﺎﺑ ﺐﻋﻻ ﺩﻮﺟﻭ ﻦﻣ ﻖﻘﺤﺘﻟﺍ == ﻚﻤﺳﺎﺑ ﺐﻋﻻ ﺩﻮﺟﻭ ﻦﻣ ﻖﻘﺤﺘﻟﺍ

View file

@ -1622,7 +1622,7 @@ Go back the specified duration
[Demo player duration] [Demo player duration]
%d sec. %d sec.
== % сек. == %d сек.
Change the skip duration Change the skip duration
== Змяніць працягласць пропуску == Змяніць працягласць пропуску
@ -1765,14 +1765,14 @@ Following
== Бягучыя == Бягучыя
Loading commands… Loading commands…
== Загрузка каманд... == Загрузка каманд
[Spectating] [Spectating]
Following %s Following %s
== Назіранне за %s == Назіранне за %s
Press a key… Press a key…
== Націсніце клавішу... == Націсніце клавішу
Main menu Main menu
== Галоўнае меню == Галоўнае меню
@ -1805,7 +1805,7 @@ Friends
== Сябры == Сябры
Loading… Loading…
== Загрузка... == Загрузка
Player info change cooldown Player info change cooldown
== Затрымка абнаўлення інфармацыі пра гульца == Затрымка абнаўлення інфармацыі пра гульца
@ -1863,7 +1863,7 @@ Round %d/%d
[Spectators] [Spectators]
%d others… %d others…
== %d іншых... == %d іншых
[Team and size] [Team and size]
%d\n(%d/%d) %d\n(%d/%d)

View file

@ -1061,7 +1061,7 @@ Replay
== Visszajátszás == Visszajátszás
The width of texture %s is not divisible by %d, or the height is not divisible by %d, which might cause visual bugs. The width of texture %s is not divisible by %d, or the height is not divisible by %d, which might cause visual bugs.
== Ennek a Textúrának szélessége, vagy magassága (%s) nem megfelelően osztható el ezzel a számmal: (%d), ami vizuális hibákhoz vezethet. (Méretek máshogyan fognak kinézni és a teljesítményt is ronthatja.) ==
Getting server list from master server Getting server list from master server
== Szerverlista lekérése a fő szerverekről == Szerverlista lekérése a fő szerverekről

View file

@ -1180,7 +1180,7 @@ No server selected
== Nessun server selezionato == Nessun server selezionato
Online clanmates (%d) Online clanmates (%d)
== Compagni di clan online == Compagni di clan online (%d)
Click to select server. Double click to join your friend. Click to select server. Double click to join your friend.
== Fare click per selezionare il server. Fai doppio click per unirti al tuo amico. == Fare click per selezionare il server. Fai doppio click per unirti al tuo amico.

View file

@ -535,7 +535,7 @@ Replay feature is disabled!
== 리플레이 기능을 비활성화했습니다! == 리플레이 기능을 비활성화했습니다!
The width of texture %s is not divisible by %d, or the height is not divisible by %d, which might cause visual bugs. The width of texture %s is not divisible by %d, or the height is not divisible by %d, which might cause visual bugs.
== 텍스처 %s 의 너비 또는 높이를 %d 으로 나눌 수 없습니다. 이는 시각적 오류를 발생시킬 수 있습니다. ==
Warning Warning
== 주의 == 주의

View file

@ -7,22 +7,6 @@ class LanguageDecodeError(Exception):
error = f"File \"{filename}\", line {line+1}: {message}" error = f"File \"{filename}\", line {line+1}: {message}"
super().__init__(error) super().__init__(error)
# Taken from https://stackoverflow.com/questions/30011379/how-can-i-parse-a-c-format-string-in-python
cfmt = r'''\
( # start of capture group 1
% # literal "%"
(?: # first option
(?:[-+0 #]{0,5}) # optional flags
(?:\d+|\*)? # width
(?:\.(?:\d+|\*))? # precision
(?:h|l|ll|w|I|I32|I64)? # size
[cCdiouxXeEfgGaAnpsSZ] # type
) | # OR
%%) # literal "%%"
'''
def decode(fileobj, elements_per_key): def decode(fileobj, elements_per_key):
data = {} data = {}
current_context = "" current_context = ""
@ -45,10 +29,7 @@ def decode(fileobj, elements_per_key):
if len(data[current_key]) >= 1+elements_per_key: if len(data[current_key]) >= 1+elements_per_key:
raise LanguageDecodeError("Wrong number of elements per key", fileobj.name, index) raise LanguageDecodeError("Wrong number of elements per key", fileobj.name, index)
if current_key: if current_key:
original = current_key[0] # pylint: disable=unsubscriptable-object
translation = line[3:] translation = line[3:]
if translation and [m.group(1) for m in re.finditer(cfmt, original, flags=re.X)] != [m.group(1) for m in re.finditer(cfmt, translation, flags=re.X)]:
raise LanguageDecodeError("Non-matching formatting string", fileobj.name, index)
data[current_key].extend([translation]) data[current_key].extend([translation])
else: else:
raise LanguageDecodeError("Element before key given", fileobj.name, index) raise LanguageDecodeError("Element before key given", fileobj.name, index)

54
scripts/languages/validate.py Executable file
View file

@ -0,0 +1,54 @@
#!/usr/bin/env python3
import os
import sys
import re
import twlang
os.chdir(os.path.dirname(__file__) + "/../..")
# Taken from https://stackoverflow.com/questions/30011379/how-can-i-parse-a-c-format-string-in-python
cfmt = '''
( # start of capture group 1
% # literal "%"
(?: # first option
(?:[-+0 #]{0,5}) # optional flags
(?:\\d+|\\*)? # width
(?:\\.(?:\\d+|\\*))? # precision
(?:h|l|ll|w|I|I32|I64)? # size
[cCdiouxXeEfgGaAnpsSZ] # type
) | # OR
%%) # literal "%%"
'''
total_errors = 0
def print_validation_error(error, filename, error_line):
print(f"Invalid: {translated}")
print(f"- {error} in {filename}:{error_line + 1}\n")
global total_errors
total_errors += 1
if len(sys.argv) > 1:
languages = sys.argv[1:]
else:
languages = twlang.languages()
local = twlang.localizes()
for language in languages:
translations = twlang.translations(language)
for (english, _), (line, translated, _) in translations.items():
if not translated:
continue
# Validate c format strings. Strings that move the formatters are not validated.
if re.findall(cfmt, english, flags=re.X) != re.findall(cfmt, translated, flags=re.X) and not "1$" in translated:
print_validation_error("Non-matching formatting", language, line)
# Check for elipisis
if "" in english and "..." in translated:
print_validation_error("Usage of ... instead of the … character", language, line)
if total_errors:
print(f"Found {total_errors} {'error' if total_errors == 1 else 'errors'} ")
sys.exit(1)