forked from ChelseaKR/fare-policy-assistant
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathi18n_normalize_pot.py
More file actions
68 lines (58 loc) · 2.94 KB
/
Copy pathi18n_normalize_pot.py
File metadata and controls
68 lines (58 loc) · 2.94 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#!/usr/bin/env python3
"""Normalize a freshly extracted ``messages.pot`` into its committed form.
`pybabel extract` writes a few tokens that are volatile across machines, dates,
and Babel patch releases (the POT creation timestamp, the Babel version in
``Generated-By``, and the current year in the boilerplate comment block). It also
tags any string containing a literal ``%`` as ``python-format`` (printf style) in
addition to ``python-brace-format``. That is a false positive here: the
assistant's fixed strings are rendered with ``str.format``, never ``%``-format,
so ``msgfmt --check-format`` would wrongly reject a literal percent. We drop the
spurious ``python-format`` flag.
This runs both when the catalog is authored and inside the ``make i18n`` gate
(``pybabel extract`` -> normalize -> ``git diff --exit-code``), so the committed
template stays byte-stable and "POT is current" is a meaningful, non-flaky check.
"""
from __future__ import annotations
import re
import sys
from pathlib import Path
def normalize(text: str) -> str:
# 1. Freeze volatile header values to fixed tokens.
text = re.sub(
r'"POT-Creation-Date:.*?\\n"', '"POT-Creation-Date: 2026-06-30 00:00+0000\\\\n"', text
)
text = re.sub(r'"Generated-By:.*?\\n"', '"Generated-By: Babel\\\\n"', text)
# 2. Freeze the auto-generated year tokens in the boilerplate comment block.
text = text.replace("# Copyright (C) 2026 ORGANIZATION", "# Copyright (C) YEAR ORGANIZATION")
text = re.sub(
r"# Copyright \(C\) \d{4} ORGANIZATION", "# Copyright (C) YEAR ORGANIZATION", text
)
text = re.sub(
r"# FIRST AUTHOR <EMAIL@ADDRESS>, \d{4}\.", "# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.", text
)
# 3. Drop the spurious ``python-format`` flag (keep every other flag/order).
out_lines: list[str] = []
for line in text.splitlines(keepends=True):
stripped = line.rstrip("\n")
if stripped.startswith("#,"):
flags = [f.strip() for f in stripped[2:].split(",") if f.strip()]
flags = [f for f in flags if f != "python-format"]
if not flags:
continue # nothing left -- drop the comment line entirely
newline = "\n" if line.endswith("\n") else ""
out_lines.append("#, " + ", ".join(flags) + newline)
else:
out_lines.append(line)
# 4. Collapse trailing blank lines to a single newline so the committed POT
# agrees with an end-of-file-fixer: Babel emits a trailing blank line after
# the last entry; normalizing it keeps the G2-lite "POT current" diff clean.
return "".join(out_lines).rstrip("\n") + "\n"
def main(argv: list[str]) -> int:
if len(argv) != 2:
print("usage: i18n_normalize_pot.py <messages.pot>", file=sys.stderr)
return 2
path = Path(argv[1])
path.write_text(normalize(path.read_text(encoding="utf-8")), encoding="utf-8")
return 0
if __name__ == "__main__":
raise SystemExit(main(sys.argv))