Fix CodeRabbit findings #11

Merged
Snider merged 1 commit from agent/fix-coderabbit-findings--verify-each-aga into dev 2026-03-24 11:33:20 +00:00
3 changed files with 31 additions and 6 deletions

View file

@ -4,6 +4,7 @@ package i18n
import (
"context"
"fmt"
"io/fs"
"sync"
@ -65,7 +66,9 @@ func NewCoreService(opts ServiceOptions) func(*core.Core) (any, error) {
}
if opts.Language != "" {
_ = svc.SetLanguage(opts.Language)
if langErr := svc.SetLanguage(opts.Language); langErr != nil {
return nil, fmt.Errorf("i18n: invalid language %q: %w", opts.Language, langErr)
}
}
svc.SetMode(opts.Mode)

View file

@ -14,13 +14,28 @@ func GetGrammarData(lang string) *GrammarData {
return grammarCache[lang]
}
// SetGrammarData sets the grammar data for a language.
// SetGrammarData sets the grammar data for a language, replacing any existing data.
func SetGrammarData(lang string, data *GrammarData) {
grammarCacheMu.Lock()
defer grammarCacheMu.Unlock()
grammarCache[lang] = data
}
// MergeGrammarData merges grammar data into the existing data for a language.
// New entries are added; existing entries are overwritten per-key.
func MergeGrammarData(lang string, data *GrammarData) {
grammarCacheMu.Lock()
defer grammarCacheMu.Unlock()
existing := grammarCache[lang]
if existing == nil {
grammarCache[lang] = data
return
}
maps.Copy(existing.Verbs, data.Verbs)
maps.Copy(existing.Nouns, data.Nouns)
maps.Copy(existing.Words, data.Words)
}
// IrregularVerbs returns a copy of the irregular verb forms map.
func IrregularVerbs() map[string]VerbForms {
result := make(map[string]VerbForms, len(irregularVerbs))

View file

@ -139,7 +139,9 @@ func Init() error {
}
svc, err := New()
if err == nil {
defaultService.Store(svc)
// CAS prevents overwriting a concurrent SetDefault call that
// raced between the Load check above and this store.
defaultService.CompareAndSwap(nil, svc)
}
defaultErr = err
})
@ -170,6 +172,10 @@ func SetDefault(s *Service) {
// //go:embed *.json
// var localeFS embed.FS
// func init() { i18n.AddLoader(i18n.NewFSLoader(localeFS, ".")) }
//
// Note: When using the Core framework, NewCoreService creates a fresh Service
// and calls SetDefault, so init-time AddLoader calls are superseded. In that
// context, packages should implement LocaleProvider instead.
func AddLoader(loader Loader) {
svc := Default()
if svc == nil {
@ -196,7 +202,7 @@ func (s *Service) loadJSON(lang string, data []byte) error {
s.messages[lang] = messages
}
if len(grammarData.Verbs) > 0 || len(grammarData.Nouns) > 0 || len(grammarData.Words) > 0 {
SetGrammarData(lang, grammarData)
MergeGrammarData(lang, grammarData)
}
return nil
}
@ -476,9 +482,10 @@ func (s *Service) AddLoader(loader Loader) error {
s.messages[lang][k] = v
}
// Merge grammar data into the global grammar store
// Merge grammar data into the global grammar store (merge, not replace,
// so that multiple loaders contribute entries for the same language).
if grammar != nil && (len(grammar.Verbs) > 0 || len(grammar.Nouns) > 0 || len(grammar.Words) > 0) {
SetGrammarData(lang, grammar)
MergeGrammarData(lang, grammar)
}
tag := language.Make(lang)