Skip to content

Releases: DABH/localizer

v0.6.0

Choose a tag to compare

@DABH DABH released this 03 Oct 06:38
381bd9f

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): Writer with 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

Choose a tag to compare

@DABH DABH released this 03 Oct 05:31
5bdb58b

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 cp1252 stdout on Windows, for one): output stays English instead of raising UnicodeEncodeError; LOCALIZER_DEBUG=1 says why, and PYTHONUTF8=1 allows 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.typed ships 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

Choose a tag to compare

@DABH DABH released this 29 Sep 01:32

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/%v captures 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 DisableFlagParsing commands.
  • Validation: an unterminated {{, bidi isolates and overrides and other formatting controls, a \r the 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) with ModeOutput, ModeHelp, ModeError, and Reset() for tests.
  • macOS: the preferences plist parser is bounds-checked and only reads regular files up to 8 MiB. catalog.ParseFast matches encoding/json exactly (surrogates, trailing data, duplicate keys).
  • LOCALIZER_DUMP creates 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 .git or .github components), adopts only pull requests from the same repository, pushes with the github-token input, and retries its polling.
  • Third-party actions are pinned by SHA; releases are published only from tags whose commit is on main and 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.yml validation 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

Choose a tag to compare

@DABH DABH released this 28 Sep 01:00

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

Choose a tag to compare

@DABH DABH released this 28 Sep 00:19

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.format fields, printf-style verbs and Rich markup, specified once in testdata/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.