... |
... |
@@ -15,7 +15,7 @@ arg_parser.add_argument( |
15
|
15
|
"current_branch", metavar="<current-branch>", help="branch for the newest version"
|
16
|
16
|
)
|
17
|
17
|
arg_parser.add_argument(
|
18
|
|
- "filenames", metavar="<filenames>", help="name of the translation files"
|
|
18
|
+ "files", metavar="<files>", help="JSON specifying the translation files"
|
19
|
19
|
)
|
20
|
20
|
arg_parser.add_argument("outname", metavar="<json>", help="name of the json output")
|
21
|
21
|
|
... |
... |
@@ -67,6 +67,14 @@ def git_lines(git_args: list[str]) -> list[str]: |
67
|
67
|
return [line for line in git_text(git_args).split("\n") if line]
|
68
|
68
|
|
69
|
69
|
|
|
70
|
+class TranslationFile:
|
|
71
|
+ """Represents a translation file."""
|
|
72
|
+
|
|
73
|
+ def __init__(self, path: str, content: str) -> None:
|
|
74
|
+ self.path = path
|
|
75
|
+ self.content = content
|
|
76
|
+
|
|
77
|
+
|
70
|
78
|
class BrowserBranch:
|
71
|
79
|
"""Represents a browser git branch."""
|
72
|
80
|
|
... |
... |
@@ -134,11 +142,27 @@ class BrowserBranch: |
134
|
142
|
def __gt__(self, other: "BrowserBranch") -> bool:
|
135
|
143
|
return self._ordered > other._ordered
|
136
|
144
|
|
137
|
|
- def get_file_content(self, filename: str) -> str | None:
|
|
145
|
+ def _matching_dirs(self, path: str, dir_list: list[str]) -> bool:
|
|
146
|
+ """Test that a path is contained in the list of dirs.
|
|
147
|
+
|
|
148
|
+ :param path: The path to check.
|
|
149
|
+ :param dir_list: The list of directories to check against.
|
|
150
|
+ :returns: Whether the path matches.
|
|
151
|
+ """
|
|
152
|
+ for dir_path in dir_list:
|
|
153
|
+ if os.path.commonpath([dir_path, path]) == dir_path:
|
|
154
|
+ return True
|
|
155
|
+ return False
|
|
156
|
+
|
|
157
|
+ def get_file(
|
|
158
|
+ self, filename: str, search_dirs: list[str] | None
|
|
159
|
+ ) -> TranslationFile | None:
|
138
|
160
|
"""Fetch the file content for the named file in this branch.
|
139
|
161
|
|
140
|
162
|
:param filename: The name of the file to fetch the content for.
|
141
|
|
- :returns: The file content, or `None` if no file could be found.
|
|
163
|
+ :param search_dirs: The directories to restrict the search to, or None
|
|
164
|
+ to search for the file anywhere.
|
|
165
|
+ :returns: The file, or `None` if no file could be found.
|
142
|
166
|
"""
|
143
|
167
|
if self._file_paths is None:
|
144
|
168
|
if not self._is_head:
|
... |
... |
@@ -152,7 +176,10 @@ class BrowserBranch: |
152
|
176
|
)
|
153
|
177
|
|
154
|
178
|
matching = [
|
155
|
|
- path for path in self._file_paths if os.path.basename(path) == filename
|
|
179
|
+ path
|
|
180
|
+ for path in self._file_paths
|
|
181
|
+ if os.path.basename(path) == filename
|
|
182
|
+ and (search_dirs is None or self._matching_dirs(path, search_dirs))
|
156
|
183
|
]
|
157
|
184
|
if not matching:
|
158
|
185
|
return None
|
... |
... |
@@ -161,7 +188,9 @@ class BrowserBranch: |
161
|
188
|
|
162
|
189
|
path = matching[0]
|
163
|
190
|
|
164
|
|
- return git_text(["cat-file", "blob", f"{self._ref}:{path}"])
|
|
191
|
+ return TranslationFile(
|
|
192
|
+ path=path, content=git_text(["cat-file", "blob", f"{self._ref}:{path}"])
|
|
193
|
+ )
|
165
|
194
|
|
166
|
195
|
|
167
|
196
|
def get_stable_branch(
|
... |
... |
@@ -254,48 +283,63 @@ if os.environ.get("TRANSLATION_INCLUDE_LEGACY", "") != "true": |
254
|
283
|
|
255
|
284
|
files_list = []
|
256
|
285
|
|
257
|
|
-for translation_branch, name in (
|
258
|
|
- part.strip().split(":", 1) for part in args.filenames.split(" ") if part.strip()
|
259
|
|
-):
|
260
|
|
- current_content = current_branch.get_file_content(name)
|
261
|
|
- stable_content = stable_branch.get_file_content(name)
|
|
286
|
+for file_dict in json.loads(args.files):
|
|
287
|
+ name = file_dict["name"]
|
|
288
|
+ where_dirs = file_dict.get("where", None)
|
|
289
|
+ current_file = current_branch.get_file(name, where_dirs)
|
|
290
|
+ stable_file = stable_branch.get_file(name, where_dirs)
|
262
|
291
|
|
263
|
|
- if current_content is None and stable_content is None:
|
|
292
|
+ if current_file is None and stable_file is None:
|
264
|
293
|
# No file in either branch.
|
265
|
294
|
logger.warning(f"{name} does not exist in either the current or stable branch")
|
266
|
|
- elif current_content is None:
|
|
295
|
+ elif current_file is None:
|
267
|
296
|
logger.warning(f"{name} deleted in the current branch")
|
268
|
|
- elif stable_content is None:
|
|
297
|
+ elif stable_file is None:
|
269
|
298
|
logger.warning(f"{name} does not exist in the stable branch")
|
|
299
|
+ elif current_file.path != stable_file.path:
|
|
300
|
+ logger.warning(
|
|
301
|
+ f"{name} has different paths in the current and stable branch. "
|
|
302
|
+ f"{current_file.path} : {stable_file.path}"
|
|
303
|
+ )
|
270
|
304
|
|
271
|
305
|
content = combine_files(
|
272
|
306
|
name,
|
273
|
|
- current_content,
|
274
|
|
- stable_content,
|
|
307
|
+ None if current_file is None else current_file.content,
|
|
308
|
+ None if stable_file is None else stable_file.content,
|
275
|
309
|
f"Will be unused in Tor Browser {current_branch.browser_version}!",
|
276
|
310
|
)
|
277
|
311
|
|
278
|
312
|
if legacy_branch:
|
279
|
|
- legacy_content = legacy_branch.get_file_content(name)
|
280
|
|
- if (
|
281
|
|
- legacy_content is not None
|
282
|
|
- and current_content is None
|
283
|
|
- and stable_content is None
|
284
|
|
- ):
|
|
313
|
+ legacy_file = legacy_branch.get_file(name, where_dirs)
|
|
314
|
+ if legacy_file is not None and current_file is None and stable_file is None:
|
285
|
315
|
logger.warning(f"{name} still exists in the legacy branch")
|
286
|
|
- elif legacy_content is None:
|
|
316
|
+ elif legacy_file is None:
|
287
|
317
|
logger.warning(f"{name} does not exist in the legacy branch")
|
|
318
|
+ elif stable_file is not None and legacy_file.path != stable_file.path:
|
|
319
|
+ logger.warning(
|
|
320
|
+ f"{name} has different paths in the stable and legacy branch. "
|
|
321
|
+ f"{stable_file.path} : {legacy_file.path}"
|
|
322
|
+ )
|
|
323
|
+ elif current_file is not None and legacy_file.path != current_file.path:
|
|
324
|
+ logger.warning(
|
|
325
|
+ f"{name} has different paths in the current and legacy branch. "
|
|
326
|
+ f"{current_file.path} : {legacy_file.path}"
|
|
327
|
+ )
|
|
328
|
+
|
288
|
329
|
content = combine_files(
|
289
|
330
|
name,
|
290
|
331
|
content,
|
291
|
|
- legacy_content,
|
|
332
|
+ legacy_file.content,
|
292
|
333
|
f"Unused in Tor Browser {stable_branch.browser_version}!",
|
293
|
334
|
)
|
294
|
335
|
|
295
|
336
|
files_list.append(
|
296
|
337
|
{
|
297
|
338
|
"name": name,
|
298
|
|
- "branch": translation_branch,
|
|
339
|
+ # If "directory" is unspecified, we place the file directly beneath
|
|
340
|
+ # en-US/ in the translation repository. i.e. "".
|
|
341
|
+ "directory": file_dict.get("directory", ""),
|
|
342
|
+ "branch": file_dict["branch"],
|
299
|
343
|
"content": content,
|
300
|
344
|
}
|
301
|
345
|
)
|