- Auto-fixed 4,496 lint issues (import sorting, modern syntax, etc.) - Added ignore rules for patterns intentional in this codebase: E402 (late imports), E712 (SQLAlchemy filters), B904 (raise from), SIM108/SIM105/SIM117 (readability preferences) - Added per-file ignores for tests and scripts - Excluded broken scripts/rename_terminology.py (has curly quotes) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
127 lines
4.0 KiB
Python
127 lines
4.0 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Add I18n.loadModule() calls to JS files that use I18n.t().
|
|
This ensures module translations are loaded before use.
|
|
"""
|
|
|
|
import re
|
|
from pathlib import Path
|
|
|
|
PROJECT_ROOT = Path(__file__).parent.parent
|
|
MODULES_DIR = PROJECT_ROOT / "app" / "modules"
|
|
|
|
# Pattern to find I18n.t('module.xxx') calls and extract module name
|
|
I18N_PATTERN = re.compile(r"I18n\.t\(['\"](\w+)\.")
|
|
|
|
|
|
def find_modules_used(content: str) -> set[str]:
|
|
"""Find all modules referenced in I18n.t() calls."""
|
|
return set(I18N_PATTERN.findall(content))
|
|
|
|
|
|
def add_module_loading(js_file: Path):
|
|
"""Add I18n.loadModule() calls to a JS file."""
|
|
content = js_file.read_text(encoding="utf-8")
|
|
|
|
# Find modules used in this file
|
|
modules = find_modules_used(content)
|
|
if not modules:
|
|
return False
|
|
|
|
# Check if already has module loading
|
|
if "I18n.loadModule(" in content:
|
|
return False
|
|
|
|
# Find the init() method and add loading there
|
|
# Look for common patterns:
|
|
# 1. init() { ... }
|
|
# 2. async init() { ... }
|
|
|
|
init_patterns = [
|
|
# Pattern for "init() {" or "async init() {"
|
|
(r"((?:async\s+)?init\s*\(\s*\)\s*\{)", "init"),
|
|
# Pattern for "mounted() {" (Vue style)
|
|
(r"(mounted\s*\(\s*\)\s*\{)", "mounted"),
|
|
]
|
|
|
|
for pattern, method_name in init_patterns:
|
|
match = re.search(pattern, content)
|
|
if match:
|
|
# Generate loading code
|
|
load_calls = "\n".join(f" await I18n.loadModule('{m}');" for m in sorted(modules))
|
|
|
|
# If init is not async, we need to make it async
|
|
full_match = match.group(1)
|
|
if "async" not in full_match:
|
|
# Make init async
|
|
new_init = full_match.replace(f"{method_name}()", f"async {method_name}()")
|
|
content = content.replace(full_match, new_init)
|
|
full_match = new_init
|
|
|
|
# Add loading after the opening brace
|
|
insert_code = f"\n // Load i18n translations\n{load_calls}\n"
|
|
content = content.replace(full_match, full_match + insert_code)
|
|
|
|
js_file.write_text(content, encoding="utf-8")
|
|
return True
|
|
|
|
# If no init found, add at file level (for simpler scripts)
|
|
# This handles files that don't use Alpine components
|
|
if "function " in content or "const " in content:
|
|
# Find first function definition
|
|
func_match = re.search(r"^(function\s+\w+\s*\([^)]*\)\s*\{)", content, re.MULTILINE)
|
|
if func_match:
|
|
load_calls = "\n".join(f" await I18n.loadModule('{m}');" for m in sorted(modules))
|
|
|
|
# Make function async if needed
|
|
full_match = func_match.group(1)
|
|
if "async" not in full_match:
|
|
new_func = full_match.replace("function ", "async function ")
|
|
content = content.replace(full_match, new_func)
|
|
full_match = new_func
|
|
|
|
insert_code = f"\n // Load i18n translations\n{load_calls}\n"
|
|
content = content.replace(full_match, full_match + insert_code)
|
|
|
|
js_file.write_text(content, encoding="utf-8")
|
|
return True
|
|
|
|
return False
|
|
|
|
|
|
def main():
|
|
print("=" * 70)
|
|
print("Adding I18n.loadModule() to JS files")
|
|
print("=" * 70)
|
|
|
|
updated = 0
|
|
skipped = 0
|
|
|
|
# Find all JS files with I18n.t() calls
|
|
for js_file in MODULES_DIR.rglob("*.js"):
|
|
content = js_file.read_text(encoding="utf-8")
|
|
if "I18n.t(" not in content:
|
|
continue
|
|
|
|
modules = find_modules_used(content)
|
|
if not modules:
|
|
continue
|
|
|
|
rel_path = js_file.relative_to(PROJECT_ROOT)
|
|
|
|
if add_module_loading(js_file):
|
|
print(f" Updated: {rel_path} (modules: {', '.join(sorted(modules))})")
|
|
updated += 1
|
|
else:
|
|
print(f" Skipped: {rel_path} (already has loading or no init method)")
|
|
skipped += 1
|
|
|
|
print()
|
|
print(f"Updated: {updated} files")
|
|
print(f"Skipped: {skipped} files")
|
|
print("=" * 70)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|