Skip to content

Instantly share code, notes, and snippets.

@ahmadsoe
Created February 18, 2025 22:11
Show Gist options
  • Save ahmadsoe/944c873edeabb6f757b6f28d954faa17 to your computer and use it in GitHub Desktop.
Save ahmadsoe/944c873edeabb6f757b6f28d954faa17 to your computer and use it in GitHub Desktop.
ARB File Merger Tool
#!/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