go-commons
Peças de Go compartilhadas entre os produtos da Seventeen Tails
— Argus, Roger e o que vier.
Cada pacote aqui é genérico de propósito: nada de regra de negócio, nada de segredo,
nada específico de um produto. O que é de produto fica no produto.
go get github.com/seventeen-tails/go-commons
i18n
Motor de internacionalização: carrega arquivos JSON de tradução, resolve o idioma do
usuário e devolve as strings prontas para a UI.
O motor não embute tradução nenhuma — os arquivos vêm do produto. É essa inversão que
torna o pacote compartilhável: o mecanismo é comum, o vocabulário é de cada um.
//go:embed locales
var locales embed.FS
sub, _ := fs.Sub(locales, "locales")
bundle, err := i18n.Load(sub, dataDir) // dataDir "" = só os embutidos
loc := bundle.Resolve(cookieDoUsuario, r.Header.Get("Accept-Language"))
msgs := bundle.Messages(loc) // map[chave]texto, fallback já aplicado
O padrão de idiomas da casa
Todo sistema da Seventeen Tails tem pelo menos en, pt-BR e es, e o
fallback é sempre o inglês.
Fallback na língua de casa só parece certo pra quem mora nela: com fallback em português,
um usuário espanhol veria a página prometer o idioma dele e entregar outro. Por isso o
inglês é o canônico — toda chave nasce em en.json, e chave faltando cai nele em vez
de sumir da tela.
Cadeia de resolução
en → idioma base (pt) → locale pedido (pt-BR) → override de runtime.
O mais específico ganha. Um fr.json largado em <dataDir>/i18n/ cria um idioma novo
sem recompilar, e herda do inglês tudo que não traduzir — é como se corrige uma string
em campo, sem release.
O que o produto precisa fazer
- Entregar
locales/en.json, locales/pt-BR.json, locales/es.json (JSON plano,
{"chave": "texto"}; a chave _name carrega o nome do idioma para o seletor).
- Escrever os testes de paridade. Eles não moram aqui porque dependem de como cada
produto usa as chaves (atributo em HTML, chamada em JS, template em Go), mas são o que
segura a dívida: toda chave usada existe no
en.json, os três idiomas têm exatamente o
mesmo conjunto de chaves, e não há chave órfã. Sem isso a tradução apodrece calada —
alguém chumba uma string num fim de tarde e ninguém percebe.
O Roger tem um exemplo pronto em internal/web/i18n_coverage_test.go.
Licença: MIT (ver LICENSE).