Validate a translation JSON file. Args: file_path: Path to translation file Returns: Validation result with status and errors
(file_path: Path)
| 496 | |
| 497 | |
| 498 | def validate_translation_file(file_path: Path) -> Dict[str, Any]: |
| 499 | """Validate a translation JSON file. |
| 500 | |
| 501 | Args: |
| 502 | file_path: Path to translation file |
| 503 | |
| 504 | Returns: |
| 505 | Validation result with status and errors |
| 506 | """ |
| 507 | result = {"valid": True, "errors": [], "warnings": [], "key_count": 0} |
| 508 | |
| 509 | try: |
| 510 | import json |
| 511 | |
| 512 | if not file_path.exists(): |
| 513 | result["valid"] = False |
| 514 | result["errors"].append("File does not exist") |
| 515 | return result |
| 516 | |
| 517 | with open(file_path, "r", encoding="utf-8") as f: |
| 518 | data = json.load(f) |
| 519 | |
| 520 | # Count keys recursively |
| 521 | def count_keys(obj): |
| 522 | count = 0 |
| 523 | if isinstance(obj, dict): |
| 524 | for key, value in obj.items(): |
| 525 | if isinstance(value, dict): |
| 526 | count += count_keys(value) |
| 527 | else: |
| 528 | count += 1 |
| 529 | return count |
| 530 | |
| 531 | result["key_count"] = count_keys(data) |
| 532 | |
| 533 | # Check for empty values |
| 534 | def check_empty_values(obj, prefix=""): |
| 535 | for key, value in obj.items(): |
| 536 | current_key = f"{prefix}.{key}" if prefix else key |
| 537 | if isinstance(value, dict): |
| 538 | check_empty_values(value, current_key) |
| 539 | elif not value or (isinstance(value, str) and not value.strip()): |
| 540 | result["warnings"].append(f"Empty value for key: {current_key}") |
| 541 | |
| 542 | check_empty_values(data) |
| 543 | |
| 544 | except json.JSONDecodeError as e: |
| 545 | result["valid"] = False |
| 546 | result["errors"].append(f"Invalid JSON: {str(e)}") |
| 547 | except Exception as e: |
| 548 | result["valid"] = False |
| 549 | result["errors"].append(f"Error reading file: {str(e)}") |
| 550 | |
| 551 | return result |
| 552 | |
| 553 | |
| 554 | def get_missing_translations(base_language: str = "en-US") -> Dict[str, List[str]]: |
nothing calls this directly
no test coverage detected