Skip to content

Commit

Permalink
ci: validate that template extraction works (#3353)
Browse files Browse the repository at this point in the history
* fix(i18n): extract `mutation_flag`

* refactor: add type hints and use f-string

* ci: validate translation template extraction
  • Loading branch information
scarf005 authored Oct 5, 2023
1 parent 54030bd commit 614ed77
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 22 deletions.
27 changes: 27 additions & 0 deletions .github/workflows/i18n-extraction.yml
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
Expand Up @@ -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
33 changes: 16 additions & 17 deletions lang/dedup_pot_file.py
Original file line number Diff line number Diff line change
@@ -1,75 +1,74 @@
#!/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:
return pl2
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)
Expand Down
5 changes: 3 additions & 2 deletions lang/extract_json_strings.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ def warning_supressed(filename):
"item_action",
"ITEM_CATEGORY",
"json_flag",
"mutation_flag",
"keybinding",
"LOOT_ZONE",
"MAGAZINE",
Expand Down Expand Up @@ -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):
Expand Down Expand Up @@ -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:
Expand Down

0 comments on commit 614ed77

Please sign in to comment.