forked from ChelseaKR/nearmiss
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathi18n_normalize_pot.py
More file actions
69 lines (59 loc) · 3.05 KB
/
Copy pathi18n_normalize_pot.py
File metadata and controls
69 lines (59 loc) · 3.05 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
69
#!/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 ``%`` — e.g. ``95%`` or ``{pct}%`` — as
``python-format`` (printf style) *in addition to* ``python-brace-format``. That
is a false positive here: nearmiss's messages are rendered with ``str.format``,
never ``%``-formatting, so ``msgfmt --check-format`` would wrongly reject the
literal percent signs. 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 the repo's end-of-file-fixer pre-commit hook (Babel emits a
# trailing blank line after the last entry, which the hook would strip —
# the mismatch would otherwise break the G2-lite "POT current" diff).
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))