A command-line tool to streamline the process of updating language files for Minecraft Java Edition modpacks.
Project description
UpLang
Minecraft Modpack Language File Synchronizer
A command-line tool to streamline the process of updating language files for Minecraft Java Edition modpacks.
Overview
UpLang automates the synchronization of language files between Minecraft mods and localization resource packs. It's designed specifically for modpack maintainers who need to keep their Chinese (zh_cn) translations up-to-date as mods are updated.
Key Features
- Automatic Detection: Scans mod JARs and extracts language files
- Smart Synchronization: Identifies added, modified, and deleted translation keys
- Format Preservation: Maintains JSON key order and formatting (blank lines, indentation)
- Intelligent Translation: Prioritizes mod-provided Chinese translations, falls back to English
- Hash-based Caching: Only processes mods with changed language files
- Parallel Processing: Multi-threaded mod processing for large modpacks
- Forge/Fabric/NeoForge Support: Works with all major mod loaders
Installation
From PyPI (Recommended)
pip install uplang
From Source
git clone https://github.com/QianFuv/UpLang.git
cd UpLang
pip install -e .
Development Installation
pip install -e ".[dev]"
Quick Start
Basic Usage
Synchronize language files from mods to a resource pack:
uplang sync /path/to/mods /path/to/resourcepack
Check Differences (Dry Run)
Preview changes without modifying files:
uplang check /path/to/mods /path/to/resourcepack
List All Mods
View all mods and their language files:
uplang list /path/to/mods
Commands
uplang sync
Synchronize language files from mods to resource pack.
uplang sync <mods_dir> <resourcepack_dir> [OPTIONS]
Options:
--dry-run: Simulate without modifying files--force: Ignore cache, process all mods--parallel <n>: Number of parallel workers (default: 4)
Example:
uplang sync ./mods ./resourcepack --parallel 8
uplang check
Check differences without synchronizing (equivalent to sync --dry-run).
uplang check <mods_dir> <resourcepack_dir>
uplang list
List all mods and their language files.
uplang list <mods_dir>
Example Output:
Example Mod (examplemod) v1.0.0
Type: forge
JAR: examplemod-1.0.0.jar
en_us.json: 42 keys
zh_cn.json: 38 keys
uplang extract
Extract language files from a single mod JAR.
uplang extract <mod_jar> <output_dir>
Example:
uplang extract ./mods/examplemod-1.0.0.jar ./extracted
uplang diff
Show detailed differences for a single mod.
uplang diff <mod_jar> <resourcepack_dir>
Example Output:
Mod: Example Mod (examplemod) v1.0.0
English: +5 ~3 -2
Added keys (5):
+ item.examplemod.new_item: New Item
+ block.examplemod.new_block: New Block
...
Modified keys (3):
~ item.examplemod.sword:
Old: Iron Sword
New: Steel Sword
...
Deleted keys (2):
- item.examplemod.old_item
...
uplang stats
Show translation statistics for the resource pack.
uplang stats <resourcepack_dir>
Example Output:
Total mods: 150
Total English keys: 12,543
Total Chinese keys: 12,543
Translated keys: 10,234
Translation coverage: 81.6%
uplang clean
Remove language files for mods that no longer exist (interactive).
uplang clean <resourcepack_dir>
uplang cache clear
Clear the cache to force full synchronization.
uplang cache clear <resourcepack_dir>
Global Options
Available for all commands:
--verbose,-v: Enable verbose output--quiet,-q: Quiet mode (errors only)--no-color: Disable colored output--log-file <path>: Write logs to file--version: Show version information--help: Show help message
Example:
uplang sync ./mods ./resourcepack --verbose --log-file sync.log
Environment Variables
UpLang supports configuration via environment variables with the UPLANG_ prefix:
Global Options
UPLANG_VERBOSE=1: Enable verbose outputUPLANG_QUIET=1: Enable quiet modeUPLANG_NO_COLOR=1: Disable colored outputUPLANG_LOG_FILE=/path/to/log: Set log file path
Command-Specific Options
Environment variables can also be used for command options using the format UPLANG_<COMMAND>_<OPTION>:
UPLANG_SYNC_PARALLEL=8: Set parallel workers for sync commandUPLANG_SYNC_FORCE=1: Force sync, ignore cacheUPLANG_SYNC_DRY_RUN=1: Enable dry-run mode
Example:
# Set verbose mode and log file via environment
export UPLANG_VERBOSE=1
export UPLANG_LOG_FILE=~/uplang.log
# Run sync with 8 parallel workers
UPLANG_SYNC_PARALLEL=8 uplang sync ./mods ./resourcepack
How It Works
Synchronization Logic
- Scan Mods: UpLang scans all JAR files in the mods directory
- Extract Language Files: Extracts
en_us.jsonandzh_cn.jsonfrom each mod - Check Cache: Uses hash-based cache to skip unchanged mods
- Compare: Identifies added, modified, and deleted keys
- Synchronize English: Updates resource pack's
en_us.jsonwith mod's English file - Synchronize Chinese: For each key:
- If key is new/modified: Use mod's Chinese translation if available, otherwise use English
- If key is deleted: Remove from resource pack
- Preserve Format: Maintains original key order and JSON formatting
Cache System
UpLang uses a hash-based cache (.uplang_cache.json) to track mod changes:
{
"version": "0.3.0",
"last_updated": "2025-11-02T10:30:00",
"mods": {
"examplemod": {
"jar_name": "examplemod-1.0.0.jar",
"en_us_hash": "abc123...",
"zh_cn_hash": "def456...",
"last_sync": "2025-11-02T10:30:00"
}
}
}
Only mods with changed language files are processed, making subsequent syncs very fast.
Architecture
src/uplang/
├── __init__.py # Package metadata, version
├── __main__.py # Entry point (python -m uplang)
├── cli.py # CLI commands and interface
├── core/
│ ├── __init__.py
│ ├── scanner.py # Scan JAR files in mods directory
│ ├── extractor.py # Extract language files from JARs
│ ├── comparator.py # Compare language files (set operations)
│ ├── synchronizer.py # Synchronize language files
│ └── cache.py # Hash-based change detection
├── models/
│ ├── __init__.py
│ ├── mod.py # Mod data class
│ ├── language_file.py # Language file data class
│ └── sync_result.py # Sync operation result
├── utils/
│ ├── __init__.py
│ ├── json_handler.py # JSON read/write with format preservation
│ ├── hash_utils.py # Hash calculation utilities
│ ├── path_utils.py # Path and filename utilities
│ └── output.py # Console output (colors, formatting)
└── exceptions.py # Custom exception hierarchy
Development
Running Tests
pytest
With coverage:
pytest --cov=uplang --cov-report=html
Code Quality
UpLang follows these standards:
- Language: English for all code (variables, functions, comments)
- Documentation: Docstrings only, no inline comments
- Architecture: Low coupling, high extensibility
- Type Hints: Full type annotations
Examples
Example 1: Initial Setup
# First time setup - sync all mods
uplang sync ./mods ./resourcepack --force
# Output:
# UpLang v0.3.0 - Language File Synchronizer
# Mods directory: ./mods
# Resource pack: ./resourcepack
#
# Scanning mods...
# Found 120 mods
#
# Synchronizing with 4 parallel workers...
# examplemod: +42 ~0 -0
# anothermod: +156 ~12 -3
# ...
#
# Synchronization Summary
# ==================================================
# Total mods: 120
# Synchronized: 120
# Skipped: 0
# Failed: 0
#
# Total changes:
# Added keys: 8,432
# Modified keys: 234
# Deleted keys: 56
# ==================================================
Example 2: Update After Mod Update
# After updating some mods
uplang sync ./mods ./resourcepack
# Output:
# ...
# Synchronizing with 4 parallel workers...
# examplemod: +5 ~3 -2
# anothermod: skipped (no changes)
# thirdmod: skipped (no changes)
# ...
#
# Synchronization Summary
# ==================================================
# Total mods: 120
# Synchronized: 1
# Skipped: 119
# Failed: 0
#
# Total changes:
# Added keys: 5
# Modified keys: 3
# Deleted keys: 2
# ==================================================
Example 3: Check Before Syncing
# Preview changes
uplang check ./mods ./resourcepack
# Output shows what would change without modifying files
Troubleshooting
Issue: "No en_us.json found in mod"
Some mods don't include language files in the JAR. This is normal and can be ignored.
Issue: "Failed to parse JSON"
The language file may have invalid JSON syntax. UpLang will skip the file and log the error.
Issue: Cache not working
Clear the cache and resync:
uplang cache clear ./resourcepack
uplang sync ./mods ./resourcepack
Contributing
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests for new functionality
- Submit a pull request
License
This project is licensed under the MIT License. See LICENSE for details.
Acknowledgments
- Built with Click for CLI
- Uses ruamel.yaml for format-preserving JSON handling
- Colorized output with Colorama
Support
- Issues: GitHub Issues
- Email: qianfuv@qq.com
Made with ❤️ for the Minecraft modding community
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file uplang-0.3.2.tar.gz.
File metadata
- Download URL: uplang-0.3.2.tar.gz
- Upload date:
- Size: 17.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4c13692031c3d9407584f19361f5e692041a7aeae0b43311a8eedb1b8528af93
|
|
| MD5 |
c5fb178a03db3133f9d22acfcf3b3467
|
|
| BLAKE2b-256 |
d634cf3a51a3af0766f095486f3f7ababa1cccb71a782a8dddcc00ef04ec5039
|
Provenance
The following attestation bundles were made for uplang-0.3.2.tar.gz:
Publisher:
publish-to-pypi.yml on QianFuv/UpLang
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
uplang-0.3.2.tar.gz -
Subject digest:
4c13692031c3d9407584f19361f5e692041a7aeae0b43311a8eedb1b8528af93 - Sigstore transparency entry: 710793091
- Sigstore integration time:
-
Permalink:
QianFuv/UpLang@f8bafddbfeef24a92cd13f133281decfaf32f209 -
Branch / Tag:
refs/tags/0.3.2 - Owner: https://github.com/QianFuv
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-to-pypi.yml@f8bafddbfeef24a92cd13f133281decfaf32f209 -
Trigger Event:
release
-
Statement type:
File details
Details for the file uplang-0.3.2-py3-none-any.whl.
File metadata
- Download URL: uplang-0.3.2-py3-none-any.whl
- Upload date:
- Size: 24.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a6cd0a7a423324ca1cbf3c48b4071241269e4f73ce3684372ae194cc06296bcb
|
|
| MD5 |
a4317d6171ddd8c408a19220b842f128
|
|
| BLAKE2b-256 |
a1dddce24e016ee50cd61a8c018445f8457ab6c1127c9aad0d698cca04548882
|
Provenance
The following attestation bundles were made for uplang-0.3.2-py3-none-any.whl:
Publisher:
publish-to-pypi.yml on QianFuv/UpLang
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
uplang-0.3.2-py3-none-any.whl -
Subject digest:
a6cd0a7a423324ca1cbf3c48b4071241269e4f73ce3684372ae194cc06296bcb - Sigstore transparency entry: 710793124
- Sigstore integration time:
-
Permalink:
QianFuv/UpLang@f8bafddbfeef24a92cd13f133281decfaf32f209 -
Branch / Tag:
refs/tags/0.3.2 - Owner: https://github.com/QianFuv
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-to-pypi.yml@f8bafddbfeef24a92cd13f133281decfaf32f209 -
Trigger Event:
release
-
Statement type: