8000 Move merge to its own script. · python/python-docs-fr@96ed486 · GitHub
[go: up one dir, main page]

Skip to content

Commit 96ed486

Browse files
committed
Move merge to its own script.
1 parent 4427533 commit 96ed486

File tree

1 file changed

+146
-0
lines changed

1 file changed

+146
-0
lines changed

merge.py

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

0 commit comments

Comments
 (0)
0