libpod/container_internal: Split locale at the first dot, etc.
We're going to feed this into Go's BCP 47 language parser. Language
tags have the form [1]:
language
["-" script]
["-" region]
*("-" variant)
*("-" extension)
["-" privateuse]
and locales have the form [2]:
[language[_territory][.codeset][@modifier]]
The modifier is useful for collation, but Go's language-based API
[3] does not provide a way for us to supply it. This code converts
our locale to a BCP 47 language by stripping the dot and later and
replacing the first underscore, if any, with a hyphen. This will
avoid errors like [4]:
WARN[0000] failed to parse language "en_US.UTF-8": language: tag is not well-formed
when feeding language.Parse(...).
[1]: https://tools.ietf.org/html/bcp47#section-2.1
[2]: http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html#tag_08_02
[3]: https://github.com/golang/go/issues/25340
[4]: https://github.com/containers/libpod/issues/2494
Signed-off-by: W. Trevor King <wking@tremily.us>
This commit is contained in:
parent
40f7843945
commit
69cb8639b4
|
|
@ -34,8 +34,8 @@ const (
|
|||
)
|
||||
|
||||
var (
|
||||
// localeToLanguage maps from locale values to language tags.
|
||||
localeToLanguage = map[string]string{
|
||||
// localeToLanguageMap maps from locale values to language tags.
|
||||
localeToLanguageMap = map[string]string{
|
||||
"": "und-u-va-posix",
|
||||
"c": "und-u-va-posix",
|
||||
"posix": "und-u-va-posix",
|
||||
|
|
@ -1281,6 +1281,16 @@ func (c *Container) saveSpec(spec *spec.Spec) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// localeToLanguage translates POSIX locale strings to BCP 47 language tags.
|
||||
func localeToLanguage(locale string) string {
|
||||
locale = strings.Replace(strings.SplitN(locale, ".", 2)[0], "_", "-", 1)
|
||||
langString, ok := localeToLanguageMap[strings.ToLower(locale)]
|
||||
if !ok {
|
||||
langString = locale
|
||||
}
|
||||
return langString
|
||||
}
|
||||
|
||||
// Warning: precreate hooks may alter 'config' in place.
|
||||
func (c *Container) setupOCIHooks(ctx context.Context, config *spec.Spec) (extensionStageHooks map[string][]spec.Hook, err error) {
|
||||
var locale string
|
||||
|
|
@ -1296,11 +1306,7 @@ func (c *Container) setupOCIHooks(ctx context.Context, config *spec.Spec) (exten
|
|||
}
|
||||
}
|
||||
|
||||
langString, ok := localeToLanguage[strings.ToLower(locale)]
|
||||
if !ok {
|
||||
langString = locale
|
||||
}
|
||||
|
||||
langString := localeToLanguage(locale)
|
||||
lang, err := language.Parse(langString)
|
||||
if err != nil {
|
||||
logrus.Warnf("failed to parse language %q: %s", langString, err)
|
||||
|
|
|
|||
|
|
@ -17,6 +17,54 @@ import (
|
|||
// hookPath is the path to an example hook executable.
|
||||
var hookPath string
|
||||
|
||||
func TestLocaleToLanguage(t *testing.T) {
|
||||
for _, testCase := range []struct {
|
||||
locale string
|
||||
language string
|
||||
}{
|
||||
{
|
||||
locale: "",
|
||||
language: "und-u-va-posix",
|
||||
},
|
||||
{
|
||||
locale: "C",
|
||||
language: "und-u-va-posix",
|
||||
},
|
||||
{
|
||||
locale: "POSIX",
|
||||
language: "und-u-va-posix",
|
||||
},
|
||||
{
|
||||
locale: "c",
|
||||
language: "und-u-va-posix",
|
||||
},
|
||||
{
|
||||
locale: "en",
|
||||
language: "en",
|
||||
},
|
||||
{
|
||||
locale: "en_US",
|
||||
language: "en-US",
|
||||
},
|
||||
{
|
||||
locale: "en.UTF-8",
|
||||
language: "en",
|
||||
},
|
||||
{
|
||||
locale: "en_US.UTF-8",
|
||||
language: "en-US",
|
||||
},
|
||||
{
|
||||
locale: "does-not-exist",
|
||||
language: "does-not-exist",
|
||||
},
|
||||
} {
|
||||
t.Run(testCase.locale, func(t *testing.T) {
|
||||
assert.Equal(t, testCase.language, localeToLanguage(testCase.locale))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestPostDeleteHooks(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
dir, err := ioutil.TempDir("", "libpod_test_")
|
||||
|
|
|
|||
Loading…
Reference in New Issue