2021-04-13 10:45:05 +02:00
|
|
|
# Copyright: Ankitects Pty Ltd and contributors
|
|
|
|
# License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
2020-11-11 12:06:51 +01:00
|
|
|
#
|
|
|
|
# A helper script to update commit references to the latest translations,
|
|
|
|
# and copy source files to the translation repos. Requires access to the
|
|
|
|
# i18n repos to run.
|
|
|
|
|
|
|
|
import os
|
2021-04-14 10:22:02 +02:00
|
|
|
import re
|
|
|
|
import subprocess
|
2020-11-11 12:22:20 +01:00
|
|
|
import sys
|
2021-04-14 10:22:02 +02:00
|
|
|
from dataclasses import dataclass
|
|
|
|
from hashlib import sha256
|
2020-11-11 12:06:51 +01:00
|
|
|
from typing import Optional, Tuple
|
2021-04-14 10:22:02 +02:00
|
|
|
|
2020-12-23 12:27:35 +01:00
|
|
|
import requests
|
2020-11-11 12:06:51 +01:00
|
|
|
|
2020-11-22 06:37:18 +01:00
|
|
|
root = os.environ["BUILD_WORKSPACE_DIRECTORY"]
|
|
|
|
repos_bzl = os.path.join(root, "repos.bzl")
|
|
|
|
working_folder = os.path.join(root, "..", "anki-i18n")
|
2020-11-11 12:06:51 +01:00
|
|
|
|
|
|
|
if not os.path.exists(working_folder):
|
|
|
|
os.mkdir(working_folder)
|
|
|
|
|
|
|
|
|
|
|
|
@dataclass
|
|
|
|
class Module:
|
|
|
|
name: str
|
|
|
|
repo: str
|
|
|
|
# (source ftl folder, i18n templates folder)
|
|
|
|
ftl: Optional[Tuple[str, str]] = None
|
|
|
|
|
|
|
|
def folder(self) -> str:
|
|
|
|
return os.path.join(working_folder, self.name)
|
|
|
|
|
|
|
|
|
|
|
|
modules = [
|
|
|
|
Module(
|
|
|
|
name="core",
|
|
|
|
repo="git@github.com:ankitects/anki-core-i18n",
|
2020-11-22 06:37:18 +01:00
|
|
|
ftl=(os.path.join(root, "ftl", "core"), "core/templates"),
|
2020-11-11 12:06:51 +01:00
|
|
|
),
|
|
|
|
Module(
|
|
|
|
name="qtftl",
|
|
|
|
repo="git@github.com:ankitects/anki-desktop-ftl",
|
2020-11-22 06:37:18 +01:00
|
|
|
ftl=(os.path.join(root, "ftl", "qt"), "desktop/templates"),
|
2020-11-11 12:06:51 +01:00
|
|
|
),
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
def update_repo(module: Module):
|
|
|
|
subprocess.run(["git", "pull"], cwd=module.folder(), check=True)
|
|
|
|
|
|
|
|
|
|
|
|
def clone_repo(module: Module):
|
|
|
|
subprocess.run(
|
|
|
|
["git", "clone", module.repo, module.name], cwd=working_folder, check=True
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
def update_git_repos():
|
|
|
|
for module in modules:
|
|
|
|
if os.path.exists(module.folder()):
|
|
|
|
update_repo(module)
|
|
|
|
else:
|
|
|
|
clone_repo(module)
|
|
|
|
|
|
|
|
|
|
|
|
@dataclass
|
|
|
|
class GitInfo:
|
|
|
|
sha1: str
|
2020-12-23 12:27:35 +01:00
|
|
|
zip_sha256: str
|
|
|
|
|
|
|
|
|
|
|
|
def git_url_to_zip_url(repo: str, commit: str) -> str:
|
|
|
|
repo = repo.replace("git@github.com:", "https://github.com/")
|
|
|
|
return f"{repo}/archive/{commit}.zip"
|
|
|
|
|
|
|
|
|
|
|
|
def get_zip_sha(zip_url: str) -> str:
|
|
|
|
resp = requests.get(zip_url)
|
|
|
|
resp.raise_for_status()
|
|
|
|
return sha256(resp.content).hexdigest()
|
2020-11-11 12:06:51 +01:00
|
|
|
|
|
|
|
|
|
|
|
def module_git_info(module: Module) -> GitInfo:
|
|
|
|
folder = module.folder()
|
2020-12-23 12:27:35 +01:00
|
|
|
sha1 = subprocess.check_output(
|
2020-11-11 12:06:51 +01:00
|
|
|
["git", "log", "-n", "1", "--pretty=format:%H"], cwd=folder
|
2020-12-23 12:27:35 +01:00
|
|
|
).decode("utf8")
|
|
|
|
zip_url = git_url_to_zip_url(module.repo, sha1)
|
|
|
|
zip_sha = get_zip_sha(zip_url)
|
|
|
|
|
|
|
|
return GitInfo(
|
|
|
|
sha1=sha1,
|
|
|
|
zip_sha256=zip_sha,
|
2020-11-11 12:06:51 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
|
2020-11-18 04:43:25 +01:00
|
|
|
def update_repos_bzl():
|
2020-11-11 12:06:51 +01:00
|
|
|
# gather changes
|
|
|
|
entries = {}
|
|
|
|
for module in modules:
|
|
|
|
git = module_git_info(module)
|
|
|
|
prefix = f"{module.name}_i18n_"
|
|
|
|
entries[prefix + "commit"] = git.sha1
|
2020-12-23 12:27:35 +01:00
|
|
|
entries[prefix + "zip_csum"] = git.zip_sha256
|
2020-11-11 12:06:51 +01:00
|
|
|
|
|
|
|
# apply
|
|
|
|
out = []
|
|
|
|
path = repos_bzl
|
2020-12-23 12:27:35 +01:00
|
|
|
reg = re.compile(r'(\s+)(\S+_(?:commit|zip_csum)) = "(.*)"')
|
2020-11-11 12:06:51 +01:00
|
|
|
for line in open(path).readlines():
|
|
|
|
if m := reg.match(line):
|
|
|
|
(indent, key, _oldvalue) = m.groups()
|
|
|
|
value = entries[key]
|
|
|
|
line = f'{indent}{key} = "{value}"\n'
|
|
|
|
out.append(line)
|
|
|
|
else:
|
|
|
|
out.append(line)
|
|
|
|
open(path, "w").writelines(out)
|
|
|
|
|
2021-01-14 01:15:52 +01:00
|
|
|
commit_if_changed(root, update_label="translations")
|
2020-11-11 12:06:51 +01:00
|
|
|
|
|
|
|
|
2021-01-14 01:15:52 +01:00
|
|
|
def commit_if_changed(folder: str, update_label: str):
|
2020-11-11 12:06:51 +01:00
|
|
|
status = subprocess.run(["git", "diff", "--exit-code"], cwd=folder, check=False)
|
|
|
|
if status.returncode == 0:
|
|
|
|
# no changes
|
|
|
|
return
|
|
|
|
subprocess.run(
|
2021-01-14 01:15:52 +01:00
|
|
|
["git", "commit", "-a", "-m", "update " + update_label], cwd=folder, check=True
|
2020-11-11 12:06:51 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
def update_ftl_templates():
|
|
|
|
for module in modules:
|
|
|
|
if ftl := module.ftl:
|
|
|
|
(source, dest) = ftl
|
|
|
|
dest = os.path.join(module.folder(), dest)
|
|
|
|
subprocess.run(
|
2020-11-18 07:17:19 +01:00
|
|
|
[
|
|
|
|
"rsync",
|
|
|
|
"-ai",
|
|
|
|
"--delete",
|
|
|
|
"--no-perms",
|
|
|
|
"--no-times",
|
|
|
|
source + "/",
|
|
|
|
dest + "/",
|
|
|
|
],
|
2020-11-11 12:06:51 +01:00
|
|
|
check=True,
|
|
|
|
)
|
2021-01-14 01:15:52 +01:00
|
|
|
commit_if_changed(module.folder(), update_label="templates")
|
2020-11-11 12:06:51 +01:00
|
|
|
|
|
|
|
|
2020-11-11 12:22:20 +01:00
|
|
|
def push_i18n_changes():
|
2020-11-11 12:06:51 +01:00
|
|
|
for module in modules:
|
|
|
|
subprocess.run(["git", "push"], cwd=module.folder(), check=True)
|
|
|
|
|
|
|
|
|
|
|
|
update_git_repos()
|
|
|
|
update_ftl_templates()
|
2020-11-11 12:22:20 +01:00
|
|
|
push_i18n_changes()
|
2020-11-18 04:43:25 +01:00
|
|
|
update_repos_bzl()
|