Metadata-Version: 2.4
Name: django-makemessages-rs
Version: 0.3.0
Classifier: Development Status :: 4 - Beta
Classifier: Framework :: Django
Classifier: Framework :: Django :: 4.2
Classifier: Framework :: Django :: 5.0
Classifier: Framework :: Django :: 5.1
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Rust
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Internationalization
Classifier: Topic :: Software Development :: Localization
Summary: A fast Rust alternative to Django's makemessages command
Keywords: django,makemessages,i18n,l10n,internationalization,localization,gettext,translation,po,rust
License: MIT
Requires-Python: >=3.9
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
Project-URL: Homepage, https://github.com/zxzinn/django-makemessages-rs
Project-URL: Issues, https://github.com/zxzinn/django-makemessages-rs/issues
Project-URL: Repository, https://github.com/zxzinn/django-makemessages-rs

# django-makemessages-rs

[![PyPI](https://img.shields.io/pypi/v/django-makemessages-rs)](https://pypi.org/project/django-makemessages-rs/)
[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](https://opensource.org/licenses/MIT)

A fast Rust alternative to Django's `makemessages` command. Produces byte-identical `.po` file output compared to [django-extended-makemessages](https://pypi.org/project/django-extended-makemessages/).

Tested against a ~2000 file Django project with ~3000 translatable strings across 5 locales:

| Tool | Time |
|------|------|
| `django-extended-makemessages` | ~21s |
| `django-makemessages-rs` | ~0.3s |

## Install

```
pip install django-makemessages-rs
```

Platform wheels are available for macOS (arm64, x86_64) and Linux (x86_64, aarch64).

## Usage

```bash
django-makemessages-rs \
  -l en -l zh_Hant -l zh_Hans -l ko -l ja \
  --ignore .venv --ignore node_modules \
  --no-location --no-flags --sort-output \
  --no-fuzzy-matching --keep-header \
  --locale-dir locale
```

### CI check mode

Use `--check` to verify translation files are in sync with source code. Exits with code 1 if any `.po` file would change:

```bash
django-makemessages-rs \
  -l en -l zh_Hant \
  --ignore .venv --ignore node_modules \
  --no-location --no-flags --sort-output \
  --no-fuzzy-matching --keep-header \
  --locale-dir locale \
  --check
```

### Options

```
-l, --locale <LOCALES>       Locales to generate (required, repeatable)
-i, --ignore <PATTERNS>      Patterns to ignore (directories/files)
-d, --domain <DOMAIN>        Domain name [default: django]
-e, --extension <EXTS>       File extensions to examine [default: html txt py]
    --root <PATH>            Root directory to scan [default: .]
    --locale-dir <PATH>      Locale directory [default: locale]
    --no-location            Don't write #: filename:line lines
    --no-flags               Don't write #, flags lines
    --sort-output            Generate sorted output
    --no-fuzzy-matching      Do not use fuzzy matching
    --keep-header            Keep the existing .po file header
    --no-obsolete            Remove obsolete message strings
    --no-wrap                Don't break long message lines
    --check                  Exit with error if .po files would change (dry-run)
    --timing                 Show timing information
```

## How it works

1. Walks the project tree using [ignore](https://crates.io/crates/ignore) (same engine as ripgrep)
2. Extracts translatable strings from `.py` and `.html`/`.txt` templates in parallel using [rayon](https://crates.io/crates/rayon)
3. Merges extracted strings with existing `.po` files, preserving translations
4. Writes updated `.po` files

The extractor handles:
- Python `gettext()`, `ngettext()`, `pgettext()`, `npgettext()` and the `_()` alias
- Django template tags: `{% trans %}`, `{% translate %}`, `{% blocktrans %}`, `{% blocktranslate %}`
- `{% blocktrans trimmed %}` whitespace collapsing
- `{% blocktrans %}...{% plural %}...{% endblocktrans %}` plural forms
- Python implicit string concatenation (`_("foo" "bar")`)
- Template variable substitution (`{{ var }}` to `%(var)s`)
- Literal `%` escaping to `%%`

No Django settings or `DJANGO_SETTINGS_MODULE` required — runs as a standalone CLI.

## Pre-commit / Git hooks integration

Add to your `pyproject.toml` dev dependencies:

```toml
"django-makemessages-rs"
```

Then in your pre-commit script:

```bash
uv run django-makemessages-rs \
  -l en -l zh_Hant \
  --ignore .venv --ignore node_modules \
  --no-location --no-flags --sort-output \
  --no-fuzzy-matching --keep-header \
  --locale-dir locale
```

## License

MIT

