This is an automated email from the ASF dual-hosted git repository.

potiuk pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/airflow.git


The following commit(s) were added to refs/heads/main by this push:
     new fa602298f4b Feat: Improve check translations script with Coverage and 
Completion metrics (#53524)
fa602298f4b is described below

commit fa602298f4b7f3f2f178d7f01ea3f590ed98c053
Author: Yeonguk Choo <[email protected]>
AuthorDate: Sat Jul 19 19:54:08 2025 +0900

    Feat: Improve check translations script with Coverage and Completion 
metrics (#53524)
---
 dev/i18n/check_translations_completeness.py | 80 ++++++++++++++---------------
 1 file changed, 40 insertions(+), 40 deletions(-)

diff --git a/dev/i18n/check_translations_completeness.py 
b/dev/i18n/check_translations_completeness.py
index b8d5437d631..4f62ddeead2 100755
--- a/dev/i18n/check_translations_completeness.py
+++ b/dev/i18n/check_translations_completeness.py
@@ -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":
@@ -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
@@ -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
@@ -372,7 +360,9 @@ def print_translation_progress(console, locale_files, 
missing_counts, summary):
                 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]",
@@ -381,7 +371,8 @@ def print_translation_progress(console, locale_files, 
missing_counts, summary):
                 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
@@ -389,7 +380,12 @@ def print_translation_progress(console, locale_files, 
missing_counts, summary):
             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),
@@ -397,12 +393,16 @@ def print_translation_progress(console, locale_files, 
missing_counts, summary):
             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(
@@ -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)
 

Reply via email to