Merge 'remotes/trunk'
[0ad.git] / source / tools / i18n / checkDiff.py
blobc211bf9e7b0824d1e2aef7c2fdfb1940fa05f8c3
1 #!/usr/bin/env python3
3 # Copyright (C) 2021 Wildfire Games.
4 # This file is part of 0 A.D.
6 # 0 A.D. is free software: you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation, either version 2 of the License, or
9 # (at your option) any later version.
11 # 0 A.D. is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
19 import io
20 import os
21 import subprocess
22 from typing import List
24 from i18n_helper import projectRootDirectory
26 def get_diff():
27 """Return a diff using svn diff"""
28 os.chdir(projectRootDirectory)
30 diff_process = subprocess.run(["svn", "diff", "binaries"], capture_output=True)
31 if diff_process.returncode != 0:
32 print(f"Error running svn diff: {diff_process.stderr.decode()}. Exiting.")
33 return
34 return io.StringIO(diff_process.stdout.decode())
36 def check_diff(diff : io.StringIO, verbose = False) -> List[str]:
37 """Run through a diff of .po files and check that some of the changes
38 are real translations changes and not just noise (line changes....).
39 The algorithm isn't extremely clever, but it is quite fast."""
41 keep = set()
42 files = set()
44 curfile = None
45 l = diff.readline()
46 while l:
47 if l.startswith("Index: binaries"):
48 if not l.endswith(".pot\n") and not l.endswith(".po\n"):
49 curfile = None
50 else:
51 curfile = l[7:-1]
52 files.add(curfile)
53 # skip patch header
54 diff.readline()
55 diff.readline()
56 diff.readline()
57 diff.readline()
58 l = diff.readline()
59 continue
60 if l[0] != '-' and l[0] != '+':
61 l = diff.readline()
62 continue
63 if l[1] == '\n' or (l[1] == '#' and l[2] == ":"):
64 l = diff.readline()
65 continue
66 if "# Copyright (C)" in l or "POT-Creation-Date:" in l or "PO-Revision-Date" in l or "Last-Translator" in l:
67 l = diff.readline()
68 continue
69 # We've hit a real line
70 if curfile:
71 keep.add(curfile)
72 curfile = None
73 l = diff.readline()
75 return list(files.difference(keep))
78 def revert_files(files: List[str], verbose = False):
79 revert_process = subprocess.run(["svn", "revert"] + files, capture_output=True)
80 if revert_process.returncode != 0:
81 print(f"Warning: Some files could not be reverted. Error: {revert_process.stderr.decode()}")
82 if verbose:
83 for file in files:
84 print(f"Reverted {file}")
87 def add_untracked(verbose = False):
88 """Add untracked .po files to svn"""
89 diff_process = subprocess.run(["svn", "st", "binaries"], capture_output=True)
90 if diff_process.stderr != b'':
91 print(f"Error running svn st: {diff_process.stderr.decode('utf-8')}. Exiting.")
92 return
94 for line in diff_process.stdout.decode('utf-8').split('\n'):
95 if not line.startswith("?"):
96 continue
97 # Ignore non PO files. This is important so that the translator credits
98 # correctly be updated, note however the script assumes a pristine SVN otherwise.
99 if not line.endswith(".po") and not line.endswith(".pot"):
100 continue
101 file = line[1:].strip()
102 add_process = subprocess.run(["svn", "add", file, "--parents"], capture_output=True)
103 if add_process.stderr != b'':
104 print(f"Warning: file {file} could not be added.")
105 if verbose:
106 print(f"Added {file}")
109 if __name__ == '__main__':
110 import argparse
111 parser = argparse.ArgumentParser()
112 parser.add_argument("--verbose", help="Print reverted files.", action='store_true')
113 args = parser.parse_args()
114 need_revert = check_diff(get_diff(), args.verbose)
115 revert_files(need_revert, args.verbose)
116 add_untracked(args.verbose)