8000 Add merge.py · python-docs-tr/python-docs-tr@ff22bb3 · GitHub
[go: up one dir, main page]

Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit ff22bb3

Browse files
committed
Add merge.py
1 parent c1fa00a commit ff22bb3

File tree

1 file changed

+141
-0
lines changed

1 file changed

+141
-0
lines changed

merge.py

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
"""Tool to merge cpython pot files to python-docs-fr po files for a
2+
given branch.
3+
"""
4+
5+
import re
6+
import shutil
7+
from pathlib import Path
8+
import argparse
9+
import subprocess
10+
from subprocess import PIPE
11+
from tqdm import tqdm
12+
13+
14+
def run(*args: str | Path, **kwargs) -> subprocess.CompletedProcess:
15+
"""Run a shell command with subprocess.run() with check=True and
16+
encoding="UTF-8".
17+
"""
18+
return subprocess.run(list(args), encoding="UTF-8", check=True, **kwargs)
19+
20+
21+
def parse_args():
22+
parser = argparse.ArgumentParser(description=__doc__)
23+
parser.add_argument(
24+
"--cpython_repo",
25+
default=Path("../cpython"),
26+
type=Path,
27+
help="Use this given cpython clone.",
28+
)
29+
parser.add_argument("branch", help="Merge from this branch")
30+
return parser.parse_args()
31+
32+
33+
def setup_repo(repo_path: Path, branch: str):
34+
"""Ensure we're up-to-date."""
35+
run("git", "-C", repo_path, "checkout", branch)
36+
run("git", "-C", repo_path, "pull", "--ff-only")
37+
38+
39+
def copy_new_files(new_files: set[Path], pot_path: Path) -> None:
40+
"""Just copy new po files to our hierarchy."""
41+
print(f"{len(new_files)} new files.")
42+
for file in new_files:
43+
file.parent.mkdir(parents=True, exist_ok=True)
44+
src = (pot_path / file).with_suffix(".pot")
45+
run("msgcat", "-o", file, src)
46+
47+
48+
def update_known_files(known_files: set[Path], pot_path: Path) -> None:
49+
"""msgmerge updated pot files in our po files."""
50+
print(f"{len(known_files)} files to update.")
51+
for file in tqdm(known_files, desc="merging pot files"):
52+
src = (pot_path / file).with_suffix(".pot")
53+
run("msgmerge", "-q", "--backup=off", "--force-po", "-U", file, src)
54+
55+
56+
def remove_old_files(old_files: set[Path]) -> None:
57+
"""Remove files removed upstream."""
58+
print(f"{len(old_files)} removed files.")
59+
60+
for file in old_files:
61+
run("git", "rm", file)
62+
63+
64+
def clean_paths(files: set[Path]) -> None:
65+
"""Ensure the path present in po files are always relative.
66+
67+
This avoid having diffs on those paths when we change something in
68+
a script.
69+
"""
70+
for file in tqdm(files, desc="Cleaning rst path in pot files"):
71+
contents = file.read_text(encoding="UTF-8")
72+
contents = re.sub("^#: .*Doc/", "#: ", contents, flags=re.M)
73+
file.write_text(contents, encoding="UTF-8")
74+
75+
76+
def update_makefile(cpython_repo: Path) -> None:
77+
"""Update CPYTHON_CURRENT_COMMIT in the Makefile.
78+
79+
So that when we run `make` it use the same commit than the one
80+
used to generate the `po` files.
81+
"""
82+
makefile = Path("Makefile").read_text(encoding="UTF-8")
83+
head = run(
84+
"git", "-C", cpython_repo, "rev-parse", "HEAD", stdout=PIPE
85+
).stdout.strip()
86+
makefile = re.sub(
87+
"^CPYTHON_CURRENT_COMMIT :=.*$",
88+
f"CPYTHON_CURRENT_COMMIT := {head}",
89+
makefile,
90+
flags=re.M,
91+
)
92+
Path("Makefile").write_text(makefile, encoding="UTF-8")
93+
run("git", "add", "Makefile")
94+
95+
96+
def git_add_relevant_files():
97+
"""Add only files with relevant modifications.
98+
99+
This only add files with actual modifications, not just metadata
100+
modifications, to avoid noise in history.
101+
"""
102+
modified_files = run("git", "ls-files", "-m", stdout=PIPE).stdout.split("\n")
103+
modified_po_files = [line for line in modified_files if line.endswith(".po")]
104+
for file in modified_po_files:
105+
diff = run("git", "diff", "-U0", file, stdout=PIPE).stdout
106+
if len(diff.split("\n")) > 8:
107+
run("git", "add", file)
108+
else:
109+
run("git", "checkout", "--", file)
110+
run("rm", "-f", "whatsnew/changelog.po") # We don't translate this file.
111+
112+
113+
def main():
114+
args = parse_args()
115+
setup_repo(args.cpython_repo, args.branch)
116+
run(
117+
*["sphinx-build", "-jauto", "-QDgettext_compact=0", "-bgettext", ".", "../pot"],
118+
cwd=args.cpython_repo / "Doc",
119+
)
120+
pot_path = args.cpython_repo / "pot"
121+
upstream = {
122+
file.relative_to(pot_path).with_suffix(".po")
123+
for file in pot_path.glob("**/*.pot")
124+
}
125+
downstream = {
126+
Path(po)
127+
for po in run("git", "ls-files", "*.po", stdout=PIPE).stdout.splitlines()
128+
}
129+
copy_new_files(upstream - downstream, pot_path=pot_path)
130+
update_known_files(upstream & downstream, pot_path=pot_path)
131+
remove_old_files(downstream - upstream)
132+
clean_paths((upstream - downstream) | (upstream & downstream))
133+
shutil.rmtree(pot_path)
134+
run("powrap", "-m")
135+
update_makefile(args.cpython_repo)
136+
git_add_relevant_files()
137+
run("git", "commit", "-m", "Make merge")
138+
139+
140+
if __name__ == "__main__":
141+
main()

0 commit comments

Comments
 (0)
0