195 lines
6.4 KiB
Python
Executable File
195 lines
6.4 KiB
Python
Executable File
#!/usr/bin/env python
|
|
|
|
import os
|
|
import subprocess
|
|
import jinja2
|
|
import click
|
|
|
|
DEVNULL = open(os.devnull, 'w')
|
|
ISSUE_TEMPLATE = """\
|
|
# This is a Bug Report
|
|
## Problem
|
|
Outdated files in the {{ r_commit }} branch.
|
|
|
|
### {{ files_to_be_modified | count }} files to be modified
|
|
{% for m_file in files_to_be_modified -%}
|
|
1. [ ] {{ m_file.fileindex }} `{{ m_file.filepath }}` {{ m_file.stat }}
|
|
{% endfor %}
|
|
|
|
### {{ files_to_be_renamed | count }} files to be renamed
|
|
{% for r_file in files_to_be_renamed -%}
|
|
1. [ ] {{ r_file.fileindex }} {{ r_file.diff_status_letter }} `{{ r_file.src_filepath }}` -> `{{ r_file.dest_filepath }}`
|
|
{% endfor %}
|
|
|
|
### {{ files_to_be_deleted | count }} files to be deleted
|
|
{% for d_file in files_to_be_deleted -%}
|
|
1. [ ] {{ d_file.fileindex }} `{{ d_file.filepath }}`
|
|
{% endfor %}
|
|
|
|
## Proposed Solution
|
|
|
|
{% if files_to_be_modified %}
|
|
|
|
Use `git diff` to check what is changed in the upstream. And apply the upstream changes manually
|
|
to the `{{ l10n_lang_path }}` of `{{ r_commit }}` branch.
|
|
|
|
For example:
|
|
```
|
|
# checkout `{{ r_commit }}`
|
|
...
|
|
# check what is updated in the upstream
|
|
git diff {{ l_commit }} {{ r_commit }} -- {{ files_to_be_modified.0.filepath }}
|
|
# apply changes to {{ l10n_lang_path }}
|
|
vi {{ files_to_be_modified.0.filepath | replace(src_lang_path, l10n_lang_path) }}
|
|
...
|
|
# commit and push
|
|
...
|
|
# make PR to `{{ r_commit }}`
|
|
```
|
|
|
|
{% endif %}
|
|
|
|
## Pages to Update
|
|
|
|
Pages in {{ l10n_lang_path }}
|
|
|
|
"""
|
|
|
|
files_to_be_deleted = []
|
|
files_to_be_renamed = []
|
|
files_to_be_modified = []
|
|
|
|
index_to_be_deleted = 0
|
|
index_to_be_renamed = 0
|
|
index_to_be_modified = 0
|
|
|
|
def git_diff(filepath, l_commit, r_commit, stat=False):
|
|
cmd = ["git", "diff", l_commit, r_commit, "--", filepath]
|
|
|
|
if stat:
|
|
cmd = ["git", "diff", l_commit, r_commit, "--stat", "--", filepath]
|
|
|
|
return subprocess.check_output(cmd).decode("UTF-8").strip()
|
|
|
|
|
|
def git_exists(path, filepath):
|
|
cmd = ["git", "cat-file", "-e", "{}:{}".format(path, filepath)]
|
|
ret_code = subprocess.call(cmd, stderr=DEVNULL)
|
|
return ret_code == 0
|
|
|
|
|
|
def process_diff_status(diff_status, l_commit, r_commit, src_lang_path,
|
|
l10n_lang_path):
|
|
status_letter = diff_status[0]
|
|
filepath = diff_status[1]
|
|
|
|
size_xs = 10
|
|
size_s = 30
|
|
size_m = 100
|
|
size_l = 500
|
|
size_xl = 1000
|
|
|
|
if git_exists(r_commit, filepath.replace(src_lang_path, l10n_lang_path)):
|
|
if status_letter == 'D':
|
|
global index_to_be_deleted
|
|
index_to_be_deleted += 1
|
|
fileindex = "D" + str(index_to_be_deleted) + '. '
|
|
deleted = {"fileindex": fileindex,
|
|
"filepath": filepath }
|
|
files_to_be_deleted.append(deleted)
|
|
elif status_letter.startswith('R'):
|
|
global index_to_be_renamed
|
|
index_to_be_renamed += 1
|
|
fileindex = "R" + str(index_to_be_renamed) + '. '
|
|
replaced = {"fileindex": fileindex,
|
|
"diff_status_letter": diff_status[0],
|
|
"src_filepath": diff_status[1],
|
|
"dest_filepath": diff_status[2]}
|
|
files_to_be_renamed.append(replaced)
|
|
elif status_letter == 'M':
|
|
global index_to_be_modified
|
|
index_to_be_modified += 1
|
|
diff_string = git_diff(filepath, l_commit, r_commit, stat=True)
|
|
diff_string_tmp= diff_string.split("|")
|
|
diff_string_r = diff_string_tmp[1]
|
|
|
|
res = [int(i) for i in diff_string_r.split() if i.isdigit()]
|
|
if len(res) < 4 :
|
|
res.append(0)
|
|
|
|
insertions = res[2]
|
|
deletions = res[3]
|
|
|
|
bold_condition = size_m
|
|
if insertions < size_xs :
|
|
insertion_size = "XS"
|
|
elif insertions < size_s :
|
|
insertion_size = "S"
|
|
elif insertions < size_m :
|
|
insertion_size = "M"
|
|
elif insertions < size_l :
|
|
insertion_size = "L"
|
|
elif insertions < size_xl :
|
|
insertion_size = "XL"
|
|
else :
|
|
insertion_size = "XXL"
|
|
|
|
stat_output = str(insertions) + "(+" + insertion_size + ") " + str(deletions) + "(-)"
|
|
|
|
if insertions >= bold_condition :
|
|
fileindex = "**M" + str(index_to_be_modified) + ".** "
|
|
stat_output = "**" + stat_output + "**"
|
|
else :
|
|
fileindex = "M" + str(index_to_be_modified) + ". "
|
|
|
|
stat_output = " | " + stat_output
|
|
|
|
modified = {"fileindex": fileindex,
|
|
"filepath": filepath,
|
|
"stat": stat_output,
|
|
"diff": git_diff(filepath, l_commit, r_commit)}
|
|
files_to_be_modified.append(modified)
|
|
|
|
|
|
def git_diff_name_status(l_commit, r_commit, src_lang_path, l10n_lang_path):
|
|
cmd = ["git", "diff", l_commit, r_commit, "--name-status", "--",
|
|
src_lang_path]
|
|
name_status_output = subprocess.check_output(cmd).strip()
|
|
for line in name_status_output.decode('utf-8').splitlines():
|
|
diff_status = line.split()
|
|
process_diff_status(diff_status, l_commit, r_commit, src_lang_path,
|
|
l10n_lang_path)
|
|
|
|
|
|
@click.command()
|
|
@click.argument("l10n-lang")
|
|
@click.argument("l-commit")
|
|
@click.argument("r-commit")
|
|
@click.option("--src-lang", help="Source language", default="en")
|
|
def main(l10n_lang, src_lang, l_commit, r_commit):
|
|
"""
|
|
This script generates a report of outdated contents in `content/<l10n-lang>`
|
|
directory by comparing two l10n team milestone branches.
|
|
|
|
L10n team owners can open a GitHub issue with the report generated by this
|
|
script when they start a new team milestone.
|
|
|
|
ex: `scripts/diff_l10n_branches.py ko dev-1.15-ko.3 dev-1.15-ko.4`
|
|
"""
|
|
l10n_lang_path = "content/" + l10n_lang
|
|
src_lang_path = "content/" + src_lang
|
|
git_diff_name_status(l_commit, r_commit, src_lang_path,
|
|
l10n_lang_path)
|
|
issue_template = jinja2.Template(ISSUE_TEMPLATE)
|
|
ret = issue_template.render(l_commit=l_commit, r_commit=r_commit,
|
|
src_lang_path=src_lang_path,
|
|
l10n_lang_path=l10n_lang_path,
|
|
files_to_be_deleted=files_to_be_deleted,
|
|
files_to_be_modified=files_to_be_modified,
|
|
files_to_be_renamed=files_to_be_renamed)
|
|
print(ret)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|