[agent/codex:gpt-5.4-mini] Read ~/spec/code/core/go/i18n/RFC.md fully. Find ONE feature... #39

Merged
Virgil merged 1 commit from agent/read---spec-code-core-go-i18n-rfc-md-ful into dev 2026-04-01 23:06:15 +00:00
3 changed files with 82 additions and 14 deletions

View file

@ -110,6 +110,43 @@ func TestInit_LoadsRegisteredLocales(t *testing.T) {
assert.Equal(t, "loaded on init", got)
}
func TestInit_ReDetectsRegisteredLocales(t *testing.T) {
t.Setenv("LANG", "de_DE.UTF-8")
registeredLocalesMu.Lock()
savedLocales := registeredLocales
savedLoaded := localesLoaded
registeredLocales = nil
localesLoaded = false
registeredLocalesMu.Unlock()
defaultOnce = sync.Once{}
defaultService.Store(nil)
defer func() {
registeredLocalesMu.Lock()
registeredLocales = savedLocales
localesLoaded = savedLoaded
registeredLocalesMu.Unlock()
defaultService.Store(nil)
defaultOnce = sync.Once{}
}()
fs := fstest.MapFS{
"locales/de.json": &fstest.MapFile{
Data: []byte(`{"hello": "hallo"}`),
},
}
RegisterLocales(fs, "locales")
require.NoError(t, Init())
svc := Default()
require.NotNil(t, svc)
assert.Contains(t, svc.Language(), "de")
assert.Equal(t, "hallo", svc.T("hello"))
}
func TestLoadRegisteredLocales_Good(t *testing.T) {
svc, err := New()
require.NoError(t, err)

View file

@ -105,8 +105,11 @@ func detectLanguage(supported []language.Tag) string {
return ""
}
matcher := language.NewMatcher(supported)
bestMatch, _, confidence := matcher.Match(parsedLang)
bestMatch, bestIndex, confidence := matcher.Match(parsedLang)
if confidence >= language.Low {
if bestIndex >= 0 && bestIndex < len(supported) {
return supported[bestIndex].String()
}
return bestMatch.String()
}
return ""

View file

@ -16,16 +16,17 @@ import (
// Service provides grammar-aware internationalisation.
type Service struct {
loader Loader
messages map[string]map[string]Message // lang -> key -> message
currentLang string
fallbackLang string
availableLangs []language.Tag
mode Mode
debug bool
formality Formality
handlers []KeyHandler
mu sync.RWMutex
loader Loader
messages map[string]map[string]Message // lang -> key -> message
currentLang string
fallbackLang string
languageExplicit bool
availableLangs []language.Tag
mode Mode
debug bool
formality Formality
handlers []KeyHandler
mu sync.RWMutex
}
// Option configures a Service during construction.
@ -222,11 +223,16 @@ func (s *Service) SetLanguage(lang string) error {
return log.E("Service.SetLanguage", "no languages available", nil)
}
matcher := language.NewMatcher(s.availableLangs)
bestMatch, _, confidence := matcher.Match(requestedLang)
bestMatch, bestIndex, confidence := matcher.Match(requestedLang)
if confidence == language.No {
return log.E("Service.SetLanguage", "unsupported language: "+lang, nil)
}
s.currentLang = bestMatch.String()
if bestIndex >= 0 && bestIndex < len(s.availableLangs) {
s.currentLang = s.availableLangs[bestIndex].String()
} else {
s.currentLang = bestMatch.String()
}
s.languageExplicit = true
return nil
}
@ -571,6 +577,7 @@ func (s *Service) AddLoader(loader Loader) error {
}
s.mu.Unlock()
}
s.autoDetectLanguage()
return nil
}
@ -578,7 +585,17 @@ func (s *Service) AddLoader(loader Loader) error {
// Deprecated: Use AddLoader(NewFSLoader(fsys, dir)) instead for proper grammar handling.
func (s *Service) LoadFS(fsys fs.FS, dir string) error {
s.mu.Lock()
defer s.mu.Unlock()
defer func() {
s.mu.Unlock()
if s.languageExplicit {
return
}
if detected := detectLanguage(s.availableLangs); detected != "" {
s.mu.Lock()
s.currentLang = detected
s.mu.Unlock()
}
}()
entries, err := fs.ReadDir(fsys, dir)
if err != nil {
return log.E("Service.LoadFS", "read locales directory", err)
@ -605,3 +622,14 @@ func (s *Service) LoadFS(fsys fs.FS, dir string) error {
}
return nil
}
func (s *Service) autoDetectLanguage() {
s.mu.Lock()
defer s.mu.Unlock()
if s.languageExplicit {
return
}
if detected := detectLanguage(s.availableLangs); detected != "" {
s.currentLang = detected
}
}