Rename script

This commit is contained in:
Nicola Benaglia 2025-05-23 18:55:17 +02:00
parent 9e681c2b39
commit 3e587c4141

108
scripts/i18n_checker.py Normal file
View File

@ -0,0 +1,108 @@
import os
import re
import json
import csv
import argparse
# Customize as needed
I18N_FUNCTIONS = ['t', 'i18next.t']
FILE_EXTENSIONS = ['.tsx', '.ts']
EXCLUDED_DIRS = ['node_modules', 'build', 'dist']
# Regex patterns
STRING_LITERAL_REGEX = re.compile(r'(?<!t\()\s*["\']([A-Z][^"\']{2,})["\']')
JSX_TEXT_REGEX = re.compile(r'>\s*([A-Z][a-z].*?)\s*<')
def is_excluded(path):
return any(excluded in path for excluded in EXCLUDED_DIRS)
def is_ignorable(text, line):
if re.fullmatch(r'[A-Z0-9_]+', text):
if re.search(r'\b(case|action|status)\b', line, re.IGNORECASE):
return True
return False
def is_console_log_line(line):
return any(kw in line for kw in ['console.log', 'console.error', 'console.warn'])
def find_untranslated_strings(file_path):
issues = []
with open(file_path, 'r', encoding='utf-8') as f:
content = f.read()
lines = content.splitlines()
for idx, line in enumerate(lines, start=1):
if is_console_log_line(line):
continue # Skip entire line if it's a console log statement
# Match suspicious string literals
for match in STRING_LITERAL_REGEX.finditer(line):
string = match.group(1).strip()
if is_ignorable(string, line):
continue
if not any(fn + '(' in line[:match.start()] for fn in I18N_FUNCTIONS):
issues.append({
'file': file_path,
'line': idx,
'type': 'StringLiteral',
'text': string
})
# Match JSX text nodes
for match in JSX_TEXT_REGEX.finditer(line):
text = match.group(1).strip()
if is_ignorable(text, line):
continue
if not text.startswith('{t('):
issues.append({
'file': file_path,
'line': idx,
'type': 'JSXText',
'text': text
})
return issues
def scan_directory(directory):
all_issues = []
for root, _, files in os.walk(directory):
if is_excluded(root):
continue
for file in files:
if any(file.endswith(ext) for ext in FILE_EXTENSIONS):
file_path = os.path.join(root, file)
issues = find_untranslated_strings(file_path)
all_issues.extend(issues)
return all_issues
def save_report(results, output_file):
_, ext = os.path.splitext(output_file)
if ext.lower() == '.json':
with open(output_file, 'w', encoding='utf-8') as f:
json.dump(results, f, indent=2)
elif ext.lower() == '.csv':
with open(output_file, 'w', newline='', encoding='utf-8') as f:
writer = csv.DictWriter(f, fieldnames=['file', 'line', 'type', 'text'])
writer.writeheader()
for row in results:
writer.writerow(row)
else:
raise ValueError("Unsupported output format. Use .json or .csv")
def main():
parser = argparse.ArgumentParser(description='Detect untranslated strings in React (.tsx) files.')
parser.add_argument('-path', default='../src/', help='Path to the source directory (e.g. ./src)')
parser.add_argument('-o', '--output', default='./i18n_report.json', help='Report output file (.json or .csv)')
args = parser.parse_args()
results = scan_directory(args.path)
if results:
save_report(results, args.output)
print(f"⚠️ Found {len(results)} potential untranslated strings. Report saved to {args.output}")
else:
print("✅ No obvious untranslated strings found.")
if __name__ == "__main__":
main()