From 614ed777a08db2a7bd3fc9b90fcfe3e251559f7e Mon Sep 17 00:00:00 2001 From: scarf Date: Thu, 5 Oct 2023 11:04:29 +0900 Subject: [PATCH] ci: validate that template extraction works (#3353) * fix(i18n): extract `mutation_flag` * refactor: add type hints and use f-string * ci: validate translation template extraction --- .github/workflows/i18n-extraction.yml | 27 +++++++++++++++ ...translation.yml => i18n-printf-format.yml} | 7 ++-- lang/dedup_pot_file.py | 33 +++++++++---------- lang/extract_json_strings.py | 5 +-- 4 files changed, 50 insertions(+), 22 deletions(-) create mode 100644 .github/workflows/i18n-extraction.yml rename .github/workflows/{check-translation.yml => i18n-printf-format.yml} (84%) diff --git a/.github/workflows/i18n-extraction.yml b/.github/workflows/i18n-extraction.yml new file mode 100644 index 000000000000..498a35c895f8 --- /dev/null +++ b/.github/workflows/i18n-extraction.yml @@ -0,0 +1,27 @@ +name: Validate translation template extraction + +on: + pull_request: + paths: + - "src/**/*.cpp" + - "lang/extract_json_strings.py" + +# We only care about the latest revision of a PR, so cancel previous instances. +concurrency: + group: i18n-extraction-${{ github.event.pull_request.number || github.ref_name }} + cancel-in-progress: true + +jobs: + check-extraction: + runs-on: ubuntu-22.04 + steps: + - name: Install dependencies + run: | + sudo apt-get update + sudo apt-get install gettext python3-pip + sudo pip3 install polib luaparser + + - uses: actions/checkout@v3 + + - name: Check that translation template extraction works + run: lang/update_pot.sh diff --git a/.github/workflows/check-translation.yml b/.github/workflows/i18n-printf-format.yml similarity index 84% rename from .github/workflows/check-translation.yml rename to .github/workflows/i18n-printf-format.yml index 9d3ea4c15376..039402e8113d 100644 --- a/.github/workflows/check-translation.yml +++ b/.github/workflows/i18n-printf-format.yml @@ -8,14 +8,15 @@ on: jobs: check-po-printf: - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 steps: - name: "Install dependencies" run: | sudo apt-get update sudo apt-get install python3-pip sudo pip3 install polib - - name: "Checkout" - uses: actions/checkout@v3 + + - uses: actions/checkout@v3 + - name: "Check printf format string in translations" run: ./tools/check_po_printf_format.py diff --git a/lang/dedup_pot_file.py b/lang/dedup_pot_file.py index 059d6d8aa2f5..88d13aef6d51 100755 --- a/lang/dedup_pot_file.py +++ b/lang/dedup_pot_file.py @@ -1,44 +1,47 @@ #!/usr/bin/env python3 "Resolve duplicates and conflicts within POT file." -import polib import os from optparse import OptionParser +from typing import Dict, List, Tuple + +import polib +from polib import POEntry ## ## FUNCTIONS ## -def first_occurence(entry): +def first_occurence(entry: POEntry) -> str: if len(entry.occurrences) > 0: return entry.occurrences[0][0] else: return 'unknown_file' -def merged_flags(entry1, entry2): +def merged_flags(entry1: POEntry, entry2: POEntry) -> List[str]: flags1 = set(entry1.flags) flags2 = set(entry2.flags) return entry1.flags + list(flags2 - flags1) # Assumes 2nd entry has only 1 comment. -def merged_comments(entry1, entry2): +def merged_comments(entry1: POEntry, entry2: POEntry) -> str: if entry2.comment[0] in entry1.comment: return entry1.comment else: return entry1.comment + entry2.comment -def merged_occurrences(entry1, entry2): +def merged_occurrences(entry1: POEntry, entry2: POEntry) -> List[Tuple[str, int]]: res = entry1.occurrences for x in entry2.occurrences: - if not x in res: + if x not in res: res.append(x) return res -def merged_msgid_pl(entry1, entry2): +def merged_msgid_pl(entry1: POEntry, entry2: POEntry) -> str: pl1 = entry1.msgid_plural pl2 = entry2.msgid_plural if not pl1: @@ -46,30 +49,26 @@ def merged_msgid_pl(entry1, entry2): elif not pl2: return pl1 if pl1 != pl2: - print("WARNING: plural form mismatch for msgid='{}' msgctxt='{}' in {} and {}: '{}' vs '{}'".format( \ - entry1.msgid, entry1.msgctxt, first_occurence(entry1), first_occurence(entry2), pl1, pl2 \ - )) + print(f"WARNING: plural form mismatch for msgid='{entry1.msgid}' msgctxt='{entry1.msgctxt}' in {first_occurence(entry1)} and {first_occurence(entry2)}: '{pl1}' vs '{pl2}'") return pl1 -def resolve_duplicates(entries): - nodup = [] - nodup_keys = {} +def resolve_duplicates(entries: List[POEntry]) -> List[POEntry]: + nodup: List[POEntry] = [] + nodup_keys: Dict[Tuple[str, str], int] = {} for entry in entries: # Strip line numbers, remove repeating occurrences entry.occurrences = list(dict.fromkeys([(x[0], None) for x in entry.occurrences])) # The only flag we use is c-format if entry.flags != [] and entry.flags != ['c-format']: - print("WARNING: unexpected flags {} for msgid='{}' in {}".format( \ - entry.flags, entry.msgid, first_occurence(entry) - )) + print(f"WARNING: unexpected flags {entry.flags} for msgid='{entry.msgid}' in {first_occurence(entry)}") # Convert comment string into list of strings (simplifies merging of comments) entry.comment = [entry.comment] key = (entry.msgid, entry.msgctxt) - if not key in nodup_keys: + if key not in nodup_keys: # Add new entry nodup_keys[key] = len(nodup) nodup.append(entry) diff --git a/lang/extract_json_strings.py b/lang/extract_json_strings.py index 7cd9d7e4e795..e4a4b997554f 100755 --- a/lang/extract_json_strings.py +++ b/lang/extract_json_strings.py @@ -162,6 +162,7 @@ def warning_supressed(filename): "item_action", "ITEM_CATEGORY", "json_flag", + "mutation_flag", "keybinding", "LOOT_ZONE", "MAGAZINE", @@ -1173,7 +1174,7 @@ def extract_json(state, item): def assert_num_args(node, args, n): if len(args) != n: - raise Exception(f"invalid amount of arguments in translation call (found {len(args)}, expected {n}). Error source: {ast.to_lua_source(node)}") + raise Exception(f"invalid amount of arguments in translation call (found {len(args)}, expected {n}). Error source: {ast.to_lua_source(node)}") def get_string_literal(node, args, pos): @@ -1228,7 +1229,7 @@ def load_comments(self, comments): if comment.is_trans_comment: self.trans_comments.append(comment) else: - self.regular_comments.append(comment) + self.regular_comments.append(comment) def report_unused_comments(self): for comment in self.trans_comments: