localizer

package module
v0.4.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 27, 2026 License: NCSA Imports: 16 Imported by: 0

README

Localizer

Localizer renders a Go CLI's own strings (help text, flag descriptions, messages, errors) in the user's language. Translations are produced by AI, kept in sync automatically through pull requests, and compiled into your binary. Localization adds no network calls and no noticeable startup cost.

Documentation: https://locale.dev/

import (
	"github.com/DABH/localizer"
	"example.com/yourcli/locales"
)

func main() {
	root := newRootCmd()
	localizer.Localize(root, locales.FS) // ← the whole integration for Cobra CLIs
	if err := root.Execute(); err != nil {
		os.Exit(1)
	}
}
$ LANG=ja_JP.UTF-8 taskctl add --help
タスクを追加します。

使い方:
  taskctl add <title> [flags]

フラグ:
      --due string       期限 (YYYY-MM-DD 形式)。
  -h, --help             add のヘルプ
      --priority level   タスクの優先度: level は low、normal、high のいずれかです。 (デフォルト: "normal")

locales/embed.go embeds one JSON catalog per language (ja.json, de.json, …), keyed by the exact English source string. The hosted Localizer service keeps the catalogs up to date. On every push that changes user-facing strings, it translates the new ones and opens or updates one pull request. Connect it with:

  • the Localizer GitHub Action. Your workflow authenticates with its short-lived GitHub OIDC token, so there's no API key, and Localizer never gets write access to your repository; or
  • the Localizer GitHub App. Install it and merge the pull requests it opens.

The first pull request sets everything up, including the line above. The hosted service is in private preview: see Getting started.

Catalogs are plain JSON that you can also write or edit by hand. Localizer never overwrites an existing translation.

What gets translated

With the one line above: every command's Short, Long, Example and deprecation text, all flag descriptions, help and usage headings, Cobra's built-in help and completion commands, shell-completion descriptions, and the errors Cobra prints (unknown commands and flags, argument counts, required flags, …).

Your own runtime messages go through a few helpers at your output chokepoints:

Helper Use
localizer.T(s) Translate a string. For a format string, call it before formatting.
localizer.Sprintf(format, args...) fmt.Sprintf with a translated format.
localizer.Error(err) Translate an error chain for display. Server text stays as it is.
localizer.Writer(w) An io.Writer that translates CLI strings written through it.

Dynamic data (server responses, IDs, JSON and YAML output) is never translated. Only strings found in your catalog change, and anything else passes through untouched.

Language selection

LOCALIZER_LANG (or an app-specific variable added with localizer.WithEnvVar) → LC_ALL → LC_MESSAGES → LANG (with GNU LANGUAGE) → the OS setting (macOS preferred languages, Windows display language) → English. C and POSIX locales keep English, so scripts stay stable. LOCALIZER_LANG=off disables localization. LOCALIZER_LANG=qps pseudo-localizes every known string, which is handy for spotting strings that don't go through Localizer yet.

Try it

go run ./examples/demo --help
LANG=ja_JP.UTF-8 go run ./examples/demo add --help
LANG=ja_JP.UTF-8 go run ./examples/demo done 9
LOCALIZER_LANG=qps go run ./examples/demo --help

Repository layout

Path What
/ The runtime library: the only package your CLI imports. Dependencies: cobra, pflag, x/text, x/sys.
catalog/, engine/, msgfmt/ Catalog format, lookup engine, and format-string and template parsing, exported for tools.
internal/ Locale detection, and built-in translations of Cobra's own strings.
action/ The GitHub Action.
examples/demo/ A small Cobra CLI that uses Localizer.
site/ The documentation site, published with GitHub Pages.

Security

See the security model. Report vulnerabilities privately as described in SECURITY.md.

Contributing

Contributions are welcome. Before your first pull request can be merged, you'll be asked to sign the Contributor Assignment Agreement; a bot comments on the pull request with instructions. See CONTRIBUTING.md.

License

Copyright (c) 2026 Snizyx Software LLC. Licensed under the University of Illinois/NCSA Open Source License.

Documentation

Overview

Package localizer renders a CLI's own strings (help, flag descriptions, messages, errors) in the user's language, using translation catalogs that are committed to the repository and embedded in the binary.

Typical integration is one line before executing a Cobra root command:

localizer.Localize(rootCmd, locales.FS)

where locales.FS is an embed.FS holding "<language>.json" catalogs (see the catalog format in the docs). Localization never makes network calls; strings without a translation, and all dynamic data such as server responses, are printed unchanged.

Environment controls:

LOCALIZER_LANG=ja      force a language (a list like "ja:en" is allowed)
LOCALIZER_LANG=en|off  disable localization
LOCALIZER_LANG=qps     pseudo-localize every known string (QA: shows what flows through Localizer)
LOCALIZER_DEBUG=1      report untranslated help strings on stderr
LOCALIZER_DUMP=<file>  write every help string in the command tree, with hit/miss, as JSON

Index

Constants

View Source
const EnvLang = "LOCALIZER_LANG"

EnvLang is the environment variable that overrides language detection for every Localizer-enabled CLI.

Variables

This section is empty.

Functions

func Error

func Error(err error) string

Error returns err's message translated for display: CLI-authored parts of a wrapped error chain are translated, server-supplied text is left as is. It returns "" for a nil error.

func Errorf

func Errorf(format string, args ...any) error

Errorf is fmt.Errorf with a translated format. %w wrapping is preserved. Prefer translating errors when they are displayed (Error) if code elsewhere inspects error strings.

func Init

func Init(catalogs fs.FS, opts ...Option) string

Init detects the user's language and loads the matching catalog from catalogs, enabling T, Sprintf, Errorf, Error and Writer. It returns the selected language, or "" when output stays in English. Most Cobra applications call Localize instead, which calls Init. Init can be called again to switch catalogs.

func Lang

func Lang() string

Lang returns the active language tag ("qps" for pseudo-localization), or "" when output is English.

func Localize

func Localize(root *cobra.Command, catalogs fs.FS, opts ...Option)

Localize translates a Cobra command tree in place: every command's Short, Long, Example and deprecation text, every flag description, command group titles, the usage/help/version templates, Cobra's built-in help and completion commands, and the errors Cobra prints. Call it right before root.Execute(), after the application has added all commands and flags.

The first call detects the user's language (see Init); later calls — for example on a tree rebuilt by an interactive shell — reuse that decision. When output stays in English, Localize changes nothing.

func Sprintf

func Sprintf(format string, args ...any) string

Sprintf formats according to the translation of format.

func T

func T(s string) string

T returns the translation of s, or s unchanged. For a format string, call T before formatting: fmt.Sprintf(localizer.T(format), args...) — or use Sprintf.

func Writer

func Writer(w io.Writer) io.Writer

Writer returns a writer that translates CLI strings written to w, one Write call at a time (so prompts without a trailing newline are passed through immediately). It returns w itself when output is not being localized. The returned writer exposes w's Fd method, if any, for terminal detection.

Types

type Dump

type Dump struct {
	Language string      `json:"language,omitempty"`
	Entries  []DumpEntry `json:"entries"`
}

Dump is the LOCALIZER_DUMP file format.

type DumpEntry

type DumpEntry struct {
	Kind       string `json:"kind"` // short, long, example, deprecated, group, flag, flag_deprecated
	Command    string `json:"command"`
	Flag       string `json:"flag,omitempty"`
	Text       string `json:"text"`
	Translated *bool  `json:"translated,omitempty"` // nil when no language is active
}

DumpEntry is one help string found in a command tree (LOCALIZER_DUMP output).

type Option

type Option func(*config)

Option configures Localize and Init.

func WithEnvVar

func WithEnvVar(name string) Option

WithEnvVar adds an application-specific override variable (for example "CONFLUENT_LANG") that is consulted before LOCALIZER_LANG and the system locale.

func WithLanguage

func WithLanguage(tag string) Option

WithLanguage forces a language (for example from a --lang flag). "en" or "off" disables localization.

func WithoutErrWriter

func WithoutErrWriter() Option

WithoutErrWriter keeps Localize from wrapping the root command's error writer. Cobra's own error messages are then printed in English.

Directories

Path Synopsis
Package catalog reads and writes Localizer translation catalogs: one JSON file per language, named "<BCP 47 tag>.json", mapping each English source string to its translation.
Package catalog reads and writes Localizer translation catalogs: one JSON file per language, named "<BCP 47 tag>.json", mapping each English source string to its translation.
Package engine looks up translations for strings a CLI prints: exact catalog hits, reverse-matched format strings, and composite text split into paragraphs, lines and "label: message" parts.
Package engine looks up translations for strings a CLI prints: exact catalog hits, reverse-matched format strings, and composite text split into paragraphs, lines and "label: message" parts.
examples
demo command
Command taskctl is a tiny Cobra CLI that demonstrates Localizer.
Command taskctl is a tiny Cobra CLI that demonstrates Localizer.
demo/locales
Package locales holds taskctl's translation catalogs, maintained by Localizer.
Package locales holds taskctl's translation catalogs, maintained by Localizer.
internal
builtin
Package builtin embeds Localizer's own translations of the strings Cobra and pflag print (help headings, the help/completion commands, argument and flag errors).
Package builtin embeds Localizer's own translations of the strings Cobra and pflag print (help headings, the help/completion commands, argument and flag errors).
locale
Package locale works out which language the user wants: explicit overrides, the POSIX locale environment, then the operating system's preferred languages.
Package locale works out which language the user wants: explicit overrides, the POSIX locale environment, then the operating system's preferred languages.
Package msgfmt understands the two kinds of placeholders that appear in CLI strings: Go fmt verbs ("Created %s \"%s\".") and text/template actions ("{{.CommandPath}}").
Package msgfmt understands the two kinds of placeholders that appear in CLI strings: Go fmt verbs ("Created %s \"%s\".") and text/template actions ("{{.CommandPath}}").

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL