File: i18n.go

package info (click to toggle)
lazygit 0.50.0%2Bds1-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 6,808 kB
  • sloc: sh: 128; makefile: 76
file content (127 lines) | stat: -rw-r--r-- 3,107 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
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"
}