mirror of
https://github.com/spf13/cobra
synced 2025-04-27 17:17:20 +00:00
Supports rfc4646 language tags in env vars. If region is detected (en-US, fr-CA), will try to load regional files first.
94 lines
2.4 KiB
Go
94 lines
2.4 KiB
Go
package cobra
|
|
|
|
import (
|
|
"embed"
|
|
"fmt"
|
|
"github.com/BurntSushi/toml"
|
|
"github.com/nicksnyder/go-i18n/v2/i18n"
|
|
"golang.org/x/text/language"
|
|
"os"
|
|
)
|
|
|
|
var defaultLanguage = language.English
|
|
|
|
// envVariablesHoldingLocale is sorted by decreasing priority
|
|
// These environment variables are expected to hold a parsable locale (fr_FR, es, en-US, …)
|
|
var envVariablesHoldingLocale = []string{
|
|
"LANGUAGE",
|
|
"LC_ALL",
|
|
"LANG",
|
|
}
|
|
|
|
// localeFS points to an embedded filesystem of TOML translation files
|
|
//
|
|
//go:embed translations/*.toml
|
|
var localeFS embed.FS
|
|
|
|
// Localizer can be used to fetch localized messages
|
|
var localizer *i18n.Localizer
|
|
|
|
func i18nError() string {
|
|
return localizeMessage(&i18n.Message{
|
|
ID: "Error",
|
|
Description: "prefix of error messages",
|
|
Other: "Error",
|
|
})
|
|
}
|
|
|
|
func i18nExclusiveFlagsValidationError() string {
|
|
return localizeMessage(&i18n.Message{
|
|
ID: "ExclusiveFlagsValidationError",
|
|
Description: "error shown when multiple exclusive flags are provided (group flags, offending flags)",
|
|
Other: "if any flags in the group [%v] are set none of the others can be; %v were all set",
|
|
})
|
|
}
|
|
|
|
// … lots more translations here
|
|
|
|
func localizeMessage(message *i18n.Message) string {
|
|
localizedValue, err := localizer.Localize(&i18n.LocalizeConfig{
|
|
DefaultMessage: message,
|
|
})
|
|
if err != nil {
|
|
return message.Other
|
|
}
|
|
|
|
return localizedValue
|
|
}
|
|
|
|
func loadTranslationFiles(bundle *i18n.Bundle, langs []string) {
|
|
for _, lang := range langs {
|
|
_, _ = bundle.LoadMessageFileFS(localeFS, fmt.Sprintf("translations/main.%s.toml", lang))
|
|
}
|
|
}
|
|
|
|
func detectLangs() []string {
|
|
var detectedLangs []string
|
|
for _, envKey := range envVariablesHoldingLocale {
|
|
lang := os.Getenv(envKey)
|
|
if lang != "" {
|
|
detectedLang := language.Make(lang)
|
|
appendLang(&detectedLangs, detectedLang)
|
|
}
|
|
}
|
|
appendLang(&detectedLangs, defaultLanguage)
|
|
|
|
return detectedLangs
|
|
}
|
|
|
|
func appendLang(langs *[]string, lang language.Tag) {
|
|
langString := lang.String()
|
|
langBase, _ := lang.Base()
|
|
*langs = append(*langs, langString)
|
|
*langs = append(*langs, langBase.ISO3())
|
|
*langs = append(*langs, langBase.String())
|
|
}
|
|
|
|
func init() {
|
|
bundle := i18n.NewBundle(defaultLanguage)
|
|
bundle.RegisterUnmarshalFunc("toml", toml.Unmarshal)
|
|
detectedLangs := detectLangs()
|
|
//fmt.Println("Detected languages", detectedLangs)
|
|
loadTranslationFiles(bundle, detectedLangs)
|
|
localizer = i18n.NewLocalizer(bundle, detectedLangs...)
|
|
}
|