Created
February 18, 2025 22:11
-
-
Save ahmadsoe/944c873edeabb6f757b6f28d954faa17 to your computer and use it in GitHub Desktop.
ARB File Merger Tool
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
""" | |
ARB File Merger Tool | |
=================== | |
Merges multiple ARB files within a directory (recursive) into their respective | |
locale-specific `app_[locale].arb` files. | |
Usage: | |
python arb_merger.py <directory> | |
""" | |
import json | |
import os | |
import sys | |
from pathlib import Path | |
from typing import Dict, Set | |
def load_arb_file(file_path: Path) -> Dict: | |
"""Load and parse an ARB file.""" | |
with open(file_path, 'r', encoding='utf-8') as f: | |
return json.load(f) | |
def get_locale_from_filename(filename: str) -> str: | |
"""Extract locale from filename (e.g., 'something_en.arb' -> 'en').""" | |
return filename.split('_')[-1].replace('.arb', '') | |
def find_arb_files(directory: Path) -> Dict[str, list[Path]]: | |
"""Find all ARB files and group them by locale.""" | |
arb_files: Dict[str, list[Path]] = {} | |
for file_path in directory.rglob('*.arb'): | |
if file_path.name.startswith('app_'): | |
continue # Skip main app ARB files | |
locale = get_locale_from_filename(file_path.name) | |
if locale not in arb_files: | |
arb_files[locale] = [] | |
arb_files[locale].append(file_path) | |
return arb_files | |
def merge_arb_files(files: list[Path]) -> Dict: | |
"""Merge multiple ARB files into one, checking for conflicts.""" | |
merged = {} | |
conflicts: Dict[str, Set[str]] = {} | |
for file_path in files: | |
data = load_arb_file(file_path) | |
for key, value in data.items(): | |
if key.startswith('@'): | |
# Handle metadata | |
if key not in merged: | |
merged[key] = value | |
continue | |
if key in merged: | |
if key not in conflicts: | |
conflicts[key] = {str(file_path)} | |
conflicts[key].add(str(file_path)) | |
merged[key] = value | |
# Add metadata if exists | |
metadata_key = f'@{key}' | |
if metadata_key in data: | |
merged[metadata_key] = data[metadata_key] | |
# Report conflicts | |
if conflicts: | |
print("\nWarning: Found key conflicts:") | |
for key, files in conflicts.items(): | |
print(f"Key '{key}' appears in multiple files:") | |
for file in files: | |
print(f" - {file}") | |
print("\nUsing last encountered value for each conflict.") | |
return merged | |
def save_merged_arb(data: Dict, output_file: Path): | |
"""Save merged ARB data to a file.""" | |
with open(output_file, 'w', encoding='utf-8') as f: | |
json.dump(data, f, indent=2, ensure_ascii=False) | |
def main(): | |
if len(sys.argv) != 2: | |
print("Usage: python arb_merger.py <directory>") | |
sys.exit(1) | |
directory = Path(sys.argv[1]) | |
if not directory.exists(): | |
print(f"Error: Directory '{directory}' does not exist") | |
sys.exit(1) | |
print(f"Scanning directory: {directory}") | |
arb_files = find_arb_files(directory) | |
if not arb_files: | |
print("No ARB files found to merge!") | |
sys.exit(0) | |
# Process each locale | |
for locale, files in arb_files.items(): | |
print(f"\nProcessing {len(files)} files for locale '{locale}'...") | |
# Define output file in the root of the l10n directory | |
output_file = directory / f"app_{locale}.arb" | |
if not files: | |
print(f"No files to merge for locale '{locale}'") | |
continue | |
merged_data = merge_arb_files(files) | |
# Add locale metadata if not present | |
if "@@locale" not in merged_data: | |
merged_data["@@locale"] = locale | |
save_merged_arb(merged_data, output_file) | |
print(f"Merged ARB saved to: {output_file}") | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment