Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 40 additions & 40 deletions dev/i18n/check_translations_completeness.py
Original file line number Diff line number Diff line change
Expand Up @@ -285,34 +285,25 @@ def get_outdated_entries_for_language(
return outdated


def count_todo_and_total(obj):
"""Recursively count TODO: translate entries and total entries in a dict or list."""
todo = 0
total = 0
def count_todos(obj) -> int:
"""Count TODO: translate entries in a dict or list."""
if isinstance(obj, dict):
for v in obj.values():
t, n = count_todo_and_total(v)
todo += t
total += n
elif isinstance(obj, list):
for v in obj:
t, n = count_todo_and_total(v)
todo += t
total += n
else:
total = 1
if isinstance(obj, str) and obj.strip().startswith("TODO: translate"):
todo = 1
return todo, total
return sum(count_todos(v) for v in obj.values())
if isinstance(obj, list):
return sum(count_todos(v) for v in obj)
if isinstance(obj, str) and obj.strip().startswith("TODO: translate"):
return 1
return 0


def print_translation_progress(console, locale_files, missing_counts, summary):
from rich.table import Table

tables = defaultdict(lambda: Table(show_lines=True))
all_files = set()
for lf in locale_files:
all_files.update(lf.files)

has_todos = False

for lf in sorted(locale_files):
lang = lf.locale
if lang == "en":
Expand All @@ -325,7 +316,8 @@ def print_translation_progress(console, locale_files, missing_counts, summary):
table.add_column("TODOs", style="magenta")
table.add_column("Translated", style="green")
table.add_column("Total", style="bold")
table.add_column("Percent", style="bold")
table.add_column("Coverage", style="bold")
table.add_column("Completion", style="bold")
total_missing = 0
total_extra = 0
total_todos = 0
Expand All @@ -347,19 +339,15 @@ def print_translation_progress(console, locale_files, missing_counts, summary):
file_missing = missing_counts.get(filename, {}).get(lang, 0)
file_extra = len(summary.get(filename, LocaleSummary({}, {})).extra_keys.get(lang, []))

# Count TODOs
def count_todos(obj):
if isinstance(obj, dict):
return sum(count_todos(v) for v in obj.values())
if isinstance(obj, list):
return sum(count_todos(v) for v in obj)
if isinstance(obj, str) and obj.strip().startswith("TODO: translate"):
return 1
return 0

file_todos = count_todos(data)
if file_todos > 0:
has_todos = True
file_translated = file_total - file_missing
percent = 100 * file_translated / file_total if file_total else 100
# Coverage: translated / total
file_coverage_percent = 100 * file_translated / file_total if file_total else 100
# Complete percent: (translated - todos) / translated
file_actual_translated = file_translated - file_todos
complete_percent = 100 * file_actual_translated / file_translated if file_translated else 100
style = (
"bold green"
if file_missing == 0 and file_extra == 0 and file_todos == 0
Expand All @@ -372,7 +360,9 @@ def count_todos(obj):
file_extra = len(summary.get(filename, LocaleSummary({}, {})).extra_keys.get(lang, []))
file_todos = 0
file_translated = 0
percent = 0
file_actual_translated = 0
file_coverage_percent = 0
complete_percent = 0
style = "red"
table.add_row(
f"[bold reverse]{filename}[/bold reverse]",
Expand All @@ -381,28 +371,38 @@ def count_todos(obj):
str(file_todos),
str(file_translated),
str(file_total),
f"{percent:.1f}%",
f"{file_coverage_percent:.1f}%",
f"{complete_percent:.1f}%",
style=style,
)
total_missing += file_missing
total_extra += file_extra
total_todos += file_todos
total_translated += file_translated
total_total += file_total
percent = 100 * total_translated / total_total if total_total else 100

# Calculate totals for this language
total_coverage_percent = 100 * total_translated / total_total if total_total else 100
total_actual_translated = total_translated - total_todos
total_complete_percent = 100 * total_actual_translated / total_translated if total_translated else 100

table.add_row(
"All files",
str(total_missing),
str(total_extra),
str(total_todos),
str(total_translated),
str(total_total),
f"{percent:.1f}%",
style="red" if percent < 100 else "bold green",
f"{total_coverage_percent:.1f}%",
f"{total_complete_percent:.1f}%",
style="red" if total_complete_percent < 100 else "bold green",
)

for _lang, table in tables.items():
console.print(table)

return has_todos


@click.command()
@click.option(
Expand Down Expand Up @@ -450,14 +450,14 @@ def cli(language: str | None = None, add_missing: bool = False):
else:
lang_diff = print_language_summary(locale_files, summary, console)
found_difference = found_difference or lang_diff
print_translation_progress(
has_todos = print_translation_progress(
console,
[lf for lf in locale_files if language is None or lf.locale == language],
missing_counts,
summary,
)
if not found_difference:
console.print("[green]All translations are complete and consistent![green]")
if not found_difference and not has_todos:
console.print("[green]All translations are complete and consistent![/green]")
if found_difference:
sys.exit(1)

Expand Down