Repository navigation
Releases: DABH/localizer
Release list
v0.6.0
Two more Go frameworks. English output is unchanged; existing catalogs need no migration.
kong
github.com/DABH/localizer/kongx: one extra option localizes a kong application.
ctx := kong.Parse(&cli, kong.Name("yourcli"), kong.Description("..."), kongx.Localize(locales.FS))It translates the help of every command, flag and argument (help:"..." tags, kong.Description, group titles), kong's own headings and hints (Usage:, Flags:, Commands:, Arguments:, Run "yourcli --help" for more information.) and the parse errors it prints, with the error label of the yourcli: error: … line. Built-in translations ship for the seven languages. Guide: https://locale.dev/guides/kong/
urfave/cli v3
github.com/DABH/localizer/urfave: one line before Run localizes a urfave/cli v3 application.
urfave.Localize(cmd, locales.FS)
err := cmd.Run(context.Background(), os.Args)It translates every command's Usage, UsageText, Description, ArgsUsage, Category and deprecation text, every flag's usage, category, default text and deprecation text, the help templates (headings and usage-line tokens), the help, --help, --version and completion texts, the (default: X) suffix, the version line, and the usage errors and cli.Exit messages written to the error writers. The package changes urfave/cli's package-level templates and hooks for the process; the guide lists them. Guide: https://locale.dev/guides/urfave/
Runtime
localizer.WriterMode(w, mode):Writerwith an explicit mode, for adapters that wrap a framework's help or error writer.- Built-in catalogs are organized per framework (
internal/builtin/<framework>/); an application sees the union.
Service
The onboarding pull request now recognizes kong and urfave/cli repositories: the extractor reads kong help tags and kong.Description, urfave Command and flag fields and cli.Exit messages; the patcher adds the kong option or the urfave statement, or tells the maintainer the one line when the call site is ambiguous.
Examples
examples/kong-demo and examples/urfave-demo next to the Cobra examples/demo.
v0.5.3: Python runtime fixes and Go 1.25
Runtime fixes from the post-launch review. English output is unchanged; catalogs need no migration.
Python runtime
- Fails open when the terminal or pipe can't encode a translation (a
cp1252stdout on Windows, for one): output stays English instead of raisingUnicodeEncodeError;LOCALIZER_DEBUG=1says why, andPYTHONUTF8=1allows it. localize()no longer imports Rich and Typer's rendering helpers up front: hooks attach the moment the framework imports those modules, so startup drops from about 55 ms to about 5 ms on the example app.- rich-click commands and groups are localized like Click's.
py.typedships in the wheel; the dump file is created exclusively and skipped for root or setuid processes; the macOS preferences file is read only when it is a regular file, in binary mode on every platform.
Go runtime
- The module now requires Go 1.25 and takes cobra 1.10.2, pflag 1.0.10, x/text 0.41.0 and x/sys 0.47.0.
Repository
- Dependabot keeps the Go, Python, site and Actions dependencies current; CI tests the minimum Go version; releases need the maintainer's approval before publishing to PyPI.
v0.5.2: a hardening release
A hardening release from a full review of the runtime, the Action and the Python package. English output is unchanged; catalogs need no migration.
Go runtime
- Help texts spanning several lines (Cobra's
completion --help, for one) are matched as a whole before line splitting, so they render correctly in every built-in language. - Placeholder captures are checked before they're translated again: prose no longer gets spliced into translations in error output,
%w/%vcaptures are exempt, and a capture that ends a sentence is left alone in help. - Fails open everywhere: a panic in
Init,Localize, a help or usage hook or a writer falls back to the original behavior, and a translated template that doesn't parse is never installed. - Commands with their own help or usage function are wrapped too; flag deprecation notices are translated; the completion walk skips
DisableFlagParsingcommands. - Validation: an unterminated
{{, bidi isolates and overrides and other formatting controls, a\rthe source doesn't have, or a changed first backquoted span make an entry invalid;50% off-style space-flag verbs are prose. - The memo cache is bounded (1 MiB, entries up to 1 KiB).
- New API:
Translate(s, mode)withModeOutput,ModeHelp,ModeError, andReset()for tests. - macOS: the preferences plist parser is bounds-checked and only reads regular files up to 8 MiB.
catalog.ParseFastmatchesencoding/jsonexactly (surrogates, trailing data, duplicate keys). LOCALIZER_DUMPcreates its file exclusively and is ignored for root and setuid processes.
Python runtime
- Matching is bounded (no regex backtracking on large outputs), Rich tags are validated as an ordered, balanced sequence, and Typer/Click rendering fails open to the English help.
- Multi-line docstring help is translated on Python 3.12 and older; Typer's bundled Click gets translated prompt and confirmation messages; state is restored per render and safe across threads and a second
localize(). localize(language="")auto-detects;t()falls back to a pattern translation.- Packaging: a dev dependency group, the built wheel is tested in CI on Python 3.11–3.13 and Typer 0.26; the alias README documents the upgrade from
localizer-py.
GitHub Action and workflows
- The Action writes only allowlisted paths (never
.gitor.githubcomponents), adopts only pull requests from the same repository, pushes with thegithub-tokeninput, and retries its polling. - Third-party actions are pinned by SHA; releases are published only from tags whose commit is on
mainand whose tests passed.
Docs
- Precise wording on what is and isn't translated, on human edits and invalid entries, the language lookup order,
LOCALIZER_DEBUG, the.localizer.ymlvalidation rules and the service's subprocessors, plus the Action snippets pinned to this release (pull request #18).
The conformance corpus (shared by both runtimes) gained Go-syntax placeholder vectors, round-trip vectors and engine cases with built-in catalogs.
v0.5.1: the Python runtime is published as localizer
The PyPI name localizer was handed over by the maintainer of the unrelated project that held it, so the Python runtime is now published under it: pip install localizer (import name unchanged). localizer-py, the name of the first release, stays on PyPI as a metadata-only alias that depends on localizer, so existing installs and lock files keep working. Docs, README and AGENTS.md updated; the Go module and the Action are unchanged from v0.5.0.
v0.5.0: Python CLIs
Localizer now localizes Python CLIs built with Typer, Click or argparse, alongside Go CLIs built with Cobra.
Python runtime: localizer-py
pip install localizer-py (import name localizer; Python 3.10+, no dependencies). Note: the PyPI project named localizer is unrelated.
localizer.localize(app, "yourcli.locales"), one line before the app runs, renders help, option descriptions, the framework's own messages and errors, and prompts in the user's language. Works with Click 8.1+, Typer 0.17+ (including the Click copy bundled since Typer 0.26) and argparse. Translation happens when help and errors render, on copies of your command objects, so plugin and lazily registered commands are covered and the originals are never modified.- Helpers for your own messages:
t,tf,error,translate,lang. The same environment controls as the Go runtime (LOCALIZER_LANG,off,qps,LOCALIZER_DEBUG,LOCALIZER_DUMP) and identical language selection. - Built-in translations of Click's, Typer's and argparse's own strings for ja, zh-Hans, ko, es, fr, de and pt-BR.
- Placeholder grammar for
str.formatfields, printf-style verbs and Rich markup, specified once intestdata/conformance/and satisfied by both runtimes. - Every hook fails open: any internal error leaves the CLI in English.
Service
The GitHub App and the Action detect the repository language (or take language: from .localizer.yml), extract strings from Python source statically (f-strings become templates such as Plugin {name} is not installed: {0}), and onboard Python repositories: the locales package, the one line, and the localizer-py dependency. extract.funcs accepts keyword-argument names for Python; extract.skip_log_levels unset now means debug and trace for Go and every level for Python.
Docs
One Getting Started with a Go/Python switch; AGENTS.md gives coding agents the integration recipe; llms.txt indexes the docs.
Demo
DABH/snowflake-cli: the Snowflake CLI (Typer, ~1,700 strings) in Japanese and German.
Go
github.com/DABH/localizer@v0.5.0 has no API changes for Cobra users. msgfmt gains the Python placeholder syntax (Syntax, ExtractSyntax, CompileSyntax, PseudoSyntax), engine gains NewSyntax/NewPseudoSyntax, and catalog.File gains the optional format field. Action: DABH/localizer/action@v0.5.0.