lazygit/pkg/i18n/i18n.go
Stefan Haller b78aa54439 Use dario.cat/mergo instead of github.com/imdario/mergo
It's the new canonical location as of 1.0.0, the old one is deprecated and stuck
on 0.3.something.
2025-04-09 11:23:55 +02:00

127 lines
3 KiB
Go

package i18n
import (
"embed"
"encoding/json"
"fmt"
"io/fs"
"strings"
"dario.cat/mergo"
"github.com/cloudfoundry/jibber_jabber"
"github.com/go-errors/errors"
"github.com/samber/lo"
"github.com/sirupsen/logrus"
)
func NewTranslationSetFromConfig(log *logrus.Entry, configLanguage string) (*TranslationSet, error) {
languageCodes, err := getSupportedLanguageCodes()
if err != nil {
return nil, err
}
if configLanguage == "auto" {
language := detectLanguage(jibber_jabber.DetectIETF)
for _, languageCode := range languageCodes {
if strings.HasPrefix(language, languageCode) {
return newTranslationSet(log, languageCode)
}
}
// Detecting a language that we don't have a translation for is not an
// error, we'll just use English.
return EnglishTranslationSet(), nil
}
if configLanguage == "en" {
return EnglishTranslationSet(), nil
}
for _, key := range languageCodes {
if key == configLanguage {
return newTranslationSet(log, configLanguage)
}
}
// Configuring a language that we don't have a translation for *is* an
// error, though.
return nil, errors.New("Language not found: " + configLanguage)
}
func newTranslationSet(log *logrus.Entry, language string) (*TranslationSet, error) {
log.Info("language: " + language)
baseSet := EnglishTranslationSet()
if language != "en" {
translationSet, err := readLanguageFile(language)
if err != nil {
return nil, err
}
err = mergo.Merge(baseSet, *translationSet, mergo.WithOverride)
if err != nil {
return nil, err
}
}
return baseSet, nil
}
//go:embed translations/*.json
var embedFS embed.FS
// getSupportedLanguageCodes gets all the supported language codes.
// Note: this doesn't include "en"
func getSupportedLanguageCodes() ([]string, error) {
dirEntries, err := embedFS.ReadDir("translations")
if err != nil {
return nil, err
}
return lo.Map(dirEntries, func(entry fs.DirEntry, _ int) string {
return strings.TrimSuffix(entry.Name(), ".json")
}), nil
}
func readLanguageFile(languageCode string) (*TranslationSet, error) {
jsonData, err := embedFS.ReadFile(fmt.Sprintf("translations/%s.json", languageCode))
if err != nil {
return nil, err
}
var translationSet TranslationSet
err = json.Unmarshal(jsonData, &translationSet)
if err != nil {
return nil, err
}
return &translationSet, nil
}
// GetTranslationSets gets all the translation sets, keyed by language code
// This includes "en".
func GetTranslationSets() (map[string]*TranslationSet, error) {
languageCodes, err := getSupportedLanguageCodes()
if err != nil {
return nil, err
}
result := make(map[string]*TranslationSet)
result["en"] = EnglishTranslationSet()
for _, languageCode := range languageCodes {
translationSet, err := readLanguageFile(languageCode)
if err != nil {
return nil, err
}
result[languageCode] = translationSet
}
return result, nil
}
// detectLanguage extracts user language from environment
func detectLanguage(langDetector func() (string, error)) string {
if userLang, err := langDetector(); err == nil {
return userLang
}
return "C"
}