Skip to content

Commit

Permalink
Check translation files for errors
Browse files Browse the repository at this point in the history
  • Loading branch information
thomasddn committed Feb 7, 2025
1 parent 609e759 commit d879c29
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 0 deletions.
31 changes: 31 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,37 @@ jobs:
pip install -r requirements.txt
pip install -r requirements.test.txt
translations:
name: Check translations
runs-on: ubuntu-latest
needs:
- info
- prepare
steps:
- name: Check out code
uses: actions/[email protected]

- name: Set up Python ${{ env.DEFAULT_PYTHON }}
id: python
uses: actions/[email protected]
with:
python-version: ${{ env.DEFAULT_PYTHON }}

- name: Restore Python ${{ env.DEFAULT_PYTHON }} virtual environment
id: cache-venv
uses: actions/cache/[email protected]
with:
path: venv
fail-on-cache-miss: true
key: >-
${{ runner.os }}-${{ steps.python.outputs.python-version }}-venv-${{ needs.info.outputs.python_cache_key }}
- name: Run translations check
run: |
. venv/bin/activate
python --version
python scripts/check_translations.py --ignore-errors
mypy:
name: Check mypy
runs-on: ubuntu-latest
Expand Down
1 change: 1 addition & 0 deletions scripts/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""Scripts."""
71 changes: 71 additions & 0 deletions scripts/check_translations.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
"""Check translation files for errors."""

import json
from pathlib import Path
import sys

BASE_TRANSLATION = Path("custom_components/volvo_cars/strings.json")
TRANSLATIONS_DIR = Path("custom_components/volvo_cars/translations")


def _flatten_items(data: dict, parent: str = "") -> dict:
"""Return a dict mapping dot-separated keys to their values."""
items = {}
for key, value in data.items():
full_key = f"{parent}::{key}" if parent else key
if isinstance(value, dict):
items.update(_flatten_items(value, full_key))
else:
items[full_key] = value
return items


def _load_json(path: Path) -> dict:
with path.open(encoding="utf-8") as f:
return json.load(f)


def _is_empty(value) -> bool:
return value is None or (isinstance(value, str) and not value.strip())


def main():
"""Check the translation files for errors."""

ignore_errors = "--ignore-errors" in sys.argv
errors = 0

base_data = _load_json(BASE_TRANSLATION)
base_items = _flatten_items(base_data)
base_keys = set(base_items.keys())

for file in TRANSLATIONS_DIR.glob("*.json"):
print(f"--- {file.name} ---")

translation_data = _load_json(file)
trans_items = _flatten_items(translation_data)
trans_keys = set(trans_items.keys())

missing = base_keys - trans_keys
orphaned = trans_keys - base_keys
empty_values = [k for k, v in trans_items.items() if _is_empty(v)]

if missing:
print(" Missing keys:", sorted(missing))
errors = errors + len(missing)

if orphaned:
print(" Orphaned keys:", sorted(orphaned))
errors = errors + len(orphaned)

if empty_values:
print(" Empty values:", sorted(empty_values))
errors = errors + len(empty_values)

print()

sys.exit(0) if ignore_errors else sys.exit(1 if errors > 0 else 0)


if __name__ == "__main__":
main()

0 comments on commit d879c29

Please sign in to comment.