1 changed files with 133 additions and 0 deletions
@ -0,0 +1,133 @@ |
|||||||
|
#!/usr/bin/env python |
||||||
|
|
||||||
|
import datetime |
||||||
|
import glob |
||||||
|
import os |
||||||
|
import sys |
||||||
|
import pathlib |
||||||
|
import subprocess |
||||||
|
|
||||||
|
from packaging.version import Version |
||||||
|
|
||||||
|
|
||||||
|
# Version 0.22 is the first version to support c++-format |
||||||
|
_MIN_XGETTEXT_VERSION = Version("0.22") |
||||||
|
|
||||||
|
_HEADER = """ |
||||||
|
#, fuzzy |
||||||
|
msgid "" |
||||||
|
msgstr "" |
||||||
|
"Project-Id-Version: DevilutionX\\n" |
||||||
|
"POT-Creation-Date: {timestamp}\\n" |
||||||
|
"PO-Revision-Date: \\n" |
||||||
|
"Last-Translator: \\n" |
||||||
|
"Language-Team: \\n" |
||||||
|
"MIME-Version: 1.0\\n" |
||||||
|
"Content-Type: text/plain; charset=UTF-8\\n" |
||||||
|
"Content-Transfer-Encoding: 8bit\\n" |
||||||
|
"X-Generator: xgettext {xgettext_version}\\n" |
||||||
|
"X-Poedit-SourceCharset: UTF-8\\n" |
||||||
|
"X-Poedit-KeywordsList: ;_;N_;ngettext:1,2;pgettext:1c,2;P_:1c,2\\n" |
||||||
|
"X-Poedit-Basepath: ..\\n" |
||||||
|
"X-Poedit-SearchPath-0: Source\\n" |
||||||
|
|
||||||
|
""" |
||||||
|
|
||||||
|
|
||||||
|
class Error(Exception): |
||||||
|
def __init__(self, message): |
||||||
|
self.message = message |
||||||
|
|
||||||
|
def __str__(self): |
||||||
|
return self.message |
||||||
|
|
||||||
|
|
||||||
|
def get_xgettext() -> tuple[str, str]: |
||||||
|
xgettext_bin = os.environ.get("XGETTEXT_BIN", "xgettext") |
||||||
|
result: subprocess.CompletedProcess = subprocess.run( |
||||||
|
[xgettext_bin, "--version"], |
||||||
|
stdout=subprocess.PIPE, |
||||||
|
stderr=sys.stderr, |
||||||
|
check=True, |
||||||
|
) |
||||||
|
version_str = result.stdout.split(b"\n")[0].split(b" ")[-1].decode() |
||||||
|
version = Version(version_str.split("-")[0]) |
||||||
|
if version < _MIN_XGETTEXT_VERSION: |
||||||
|
raise Error( |
||||||
|
f"{xgettext_bin} version {version} is too low," |
||||||
|
+ f" minimum required is {_MIN_XGETTEXT_VERSION}" |
||||||
|
) |
||||||
|
return xgettext_bin, version_str |
||||||
|
|
||||||
|
|
||||||
|
def run_xgettext(): |
||||||
|
xgettext_binary, xgettext_version = get_xgettext() |
||||||
|
files = [] |
||||||
|
for ext in ["h", "c", "hpp", "cpp"]: |
||||||
|
files.extend(glob.glob(f"Source/**/*.{ext}", recursive=True)) |
||||||
|
files.sort() |
||||||
|
|
||||||
|
result: subprocess.CompletedProcess = subprocess.run( |
||||||
|
[ |
||||||
|
xgettext_binary, |
||||||
|
"--output=-", |
||||||
|
"--keyword", |
||||||
|
"--keyword=_", |
||||||
|
"--flag=_:1:pass-c++-format", |
||||||
|
"--keyword=N_", |
||||||
|
"--flag=N_:1:pass-c++-format", |
||||||
|
"--keyword=ngettext:1,2", |
||||||
|
"--flag=ngettext:1:pass-c++-format", |
||||||
|
"--flag=ngettext:2:pass-c++-format", |
||||||
|
"--keyword=pgettext:1c,2", |
||||||
|
"--flag=pgettext:2:pass-c++-format", |
||||||
|
"--keyword=P_:1c,2", |
||||||
|
"--flag=P_:2:pass-c++-format", |
||||||
|
"--flag=runtime:1:c++-format", |
||||||
|
"--flag=Log:1:c++-format", |
||||||
|
"--flag=LogError:1:c++-format", |
||||||
|
"--flag=LogWarn:1:c++-format", |
||||||
|
"--flag=LogInfo:1:c++-format", |
||||||
|
"--flag=LogDebug:1:c++-format", |
||||||
|
"--flag=LogVerbose:1:c++-format", |
||||||
|
"--language=C++", |
||||||
|
"--from-code=UTF-8", |
||||||
|
"--add-comments=TRANSLATORS: ", |
||||||
|
# Omitting the header causes spurious warnings: |
||||||
|
# "msgid contains non-ASCII characters". |
||||||
|
# |
||||||
|
# To avoid the warnings, we generate the header |
||||||
|
# but skip writing it later. |
||||||
|
# "--omit-header", |
||||||
|
"--debug", |
||||||
|
*files, |
||||||
|
], |
||||||
|
stdout=subprocess.PIPE, |
||||||
|
stderr=sys.stderr, |
||||||
|
check=True, |
||||||
|
) |
||||||
|
|
||||||
|
timestamp = datetime.datetime.now(datetime.UTC).strftime("%Y-%m-%d %H:%M:%S%z") |
||||||
|
with open("Translations/devilutionx.pot", "wb") as f: |
||||||
|
f.write( |
||||||
|
_HEADER.format( |
||||||
|
timestamp=timestamp, |
||||||
|
xgettext_version=xgettext_version, |
||||||
|
).encode() |
||||||
|
) |
||||||
|
f.write(b"\n\n".join(result.stdout.split(b"\n\n")[1:])) |
||||||
|
|
||||||
|
|
||||||
|
def main(): |
||||||
|
os.chdir(pathlib.Path(__file__).resolve().parent.parent) |
||||||
|
try: |
||||||
|
run_xgettext() |
||||||
|
except Error as e: |
||||||
|
print("Error:", e, file=sys.stderr) |
||||||
|
return 1 |
||||||
|
except subprocess.CalledProcessError as e: |
||||||
|
print("Error:", e.cmd[0], "failed", file=sys.stderr) |
||||||
|
return e.returncode |
||||||
|
|
||||||
|
|
||||||
|
main() |
||||||
Loading…
Reference in new issue