langs/i18n: Fix warning regression in i18n - hugo - [fork] hugo port for 9front
 (HTM) git clone git@git.drkhsh.at/hugo.git
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) Submodules
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit ececd1b122c741567a80acd8d60ccd6356fa5323
 (DIR) parent b0ca723eb2639cde9f5b2d60e2649cce523292e3
 (HTM) Author: Bjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
       Date:   Sun,  2 May 2021 14:06:16 +0200
       
       langs/i18n: Fix warning regression in i18n
       
       Fix this by
       
       1. Making sure that only numerical values are treated as plural counts
       2. Making sure that `i18n.pluralFormNotFoundError` is not logged as a warning if `other` resolved.
       
       Note that 2. isn't a new problem, but became visible because of the plural improvements in Hugo `0.83.0`.
       
       Fixes #8492
       
       Diffstat:
         M langs/i18n/i18n.go                  |      24 ++++++++++++++++++++----
         M langs/i18n/i18n_test.go             |      25 +++++++++++++++++++++----
       
       2 files changed, 41 insertions(+), 8 deletions(-)
       ---
 (DIR) diff --git a/langs/i18n/i18n.go b/langs/i18n/i18n.go
       @@ -14,6 +14,7 @@
        package i18n
        
        import (
       +        "fmt"
                "reflect"
                "strings"
        
       @@ -89,10 +90,22 @@ func (t Translator) initFuncs(bndl *i18n.Bundle) {
                                        PluralCount:  pluralCount,
                                })
        
       -                        if err == nil && currentLang == translatedLang {
       +                        sameLang := currentLang == translatedLang
       +
       +                        if err == nil && sameLang {
                                        return translated
                                }
        
       +                        if err != nil && sameLang && translated != "" {
       +                                // See #8492
       +                                // TODO(bep) this needs to be improved/fixed upstream,
       +                                // but currently we get an error even if the fallback to
       +                                // "other" succeeds.
       +                                if fmt.Sprintf("%T", err) == "i18n.pluralFormNotFoundError" {
       +                                        return translated
       +                                }
       +                        }
       +
                                if _, ok := err.(*i18n.MessageNotFoundErr); !ok {
                                        t.logger.Warnf("Failed to get translated string for language %q and ID %q: %s", currentLangStr, translationID, err)
                                }
       @@ -120,9 +133,12 @@ func (c intCount) Count() int {
        const countFieldName = "Count"
        
        // getPluralCount gets the plural count as a string (floats) or an integer.
       +// If v is nil, nil is returned.
        func getPluralCount(v interface{}) interface{} {
                if v == nil {
       -                return 0
       +                // i18n called without any argument, make sure it does not
       +                // get any plural count.
       +                return nil
                }
        
                switch v := v.(type) {
       @@ -171,11 +187,11 @@ func toPluralCountValue(in interface{}) interface{} {
                                return in
                        }
                        // A non-numeric value.
       -                return 0
       +                return nil
                default:
                        if i, err := cast.ToIntE(in); err == nil {
                                return i
                        }
       -                return 0
       +                return nil
                }
        }
 (DIR) diff --git a/langs/i18n/i18n_test.go b/langs/i18n/i18n_test.go
       @@ -359,6 +359,20 @@ other = "{{ . }} hours"`,
                                },
                        },
                        {
       +                        name: "Other only",
       +                        lang: "en",
       +                        id:   "hour",
       +                        templ: `
       +[hour]
       +other = "{{ with . }}{{ . }}{{ end }} hours"`,
       +                        variants: []types.KeyValue{
       +                                {Key: 1, Value: "1 hours"},
       +                                {Key: "1", Value: "1 hours"},
       +                                {Key: 2, Value: "2 hours"},
       +                                {Key: nil, Value: " hours"},
       +                        },
       +                },
       +                {
                                name: "Polish",
                                lang: "pl",
                                id:   "day",
       @@ -381,6 +395,7 @@ other = "{{ . }} miesiąca"
        
                        c.Run(test.name, func(c *qt.C) {
                                cfg := getConfig()
       +                        cfg.Set("enableMissingTranslationPlaceholders", true)
                                fs := hugofs.NewMem(cfg)
        
                                err := afero.WriteFile(fs.Source, filepath.Join("i18n", test.lang+".toml"), []byte(test.templ), 0755)
       @@ -388,6 +403,7 @@ other = "{{ . }} miesiąca"
        
                                tp := NewTranslationProvider()
                                depsCfg := newDepsConfig(tp, cfg, fs)
       +                        depsCfg.Logger = loggers.NewWarningLogger()
                                d, err := deps.New(depsCfg)
                                c.Assert(err, qt.IsNil)
                                c.Assert(d.LoadResources(), qt.IsNil)
       @@ -396,6 +412,7 @@ other = "{{ . }} miesiąca"
        
                                for _, variant := range test.variants {
                                        c.Assert(f(test.id, variant.Key), qt.Equals, variant.Value, qt.Commentf("input: %v", variant.Key))
       +                                c.Assert(int(depsCfg.Logger.LogCounters().WarnCounter.Count()), qt.Equals, 0)
                                }
        
                        })
       @@ -434,12 +451,12 @@ func TestGetPluralCount(t *testing.T) {
                c.Assert(getPluralCount(map[string]interface{}{"Count": "32.5"}), qt.Equals, "32.5")
                c.Assert(getPluralCount(map[string]interface{}{"count": 32}), qt.Equals, 32)
                c.Assert(getPluralCount(map[string]interface{}{"Count": "32"}), qt.Equals, "32")
       -        c.Assert(getPluralCount(map[string]interface{}{"Counts": 32}), qt.Equals, 0)
       -        c.Assert(getPluralCount("foo"), qt.Equals, 0)
       +        c.Assert(getPluralCount(map[string]interface{}{"Counts": 32}), qt.Equals, nil)
       +        c.Assert(getPluralCount("foo"), qt.Equals, nil)
                c.Assert(getPluralCount(countField{Count: 22}), qt.Equals, 22)
                c.Assert(getPluralCount(countField{Count: 1.5}), qt.Equals, "1.5")
                c.Assert(getPluralCount(&countField{Count: 22}), qt.Equals, 22)
       -        c.Assert(getPluralCount(noCountField{Counts: 23}), qt.Equals, 0)
       +        c.Assert(getPluralCount(noCountField{Counts: 23}), qt.Equals, nil)
                c.Assert(getPluralCount(countMethod{}), qt.Equals, "32.5")
                c.Assert(getPluralCount(&countMethod{}), qt.Equals, "32.5")
        
       @@ -448,7 +465,7 @@ func TestGetPluralCount(t *testing.T) {
                c.Assert(getPluralCount(1234.0), qt.Equals, "1234.0")
                c.Assert(getPluralCount("1234"), qt.Equals, "1234")
                c.Assert(getPluralCount("0.5"), qt.Equals, "0.5")
       -        c.Assert(getPluralCount(nil), qt.Equals, 0)
       +        c.Assert(getPluralCount(nil), qt.Equals, nil)
        }
        
        func prepareTranslationProvider(t testing.TB, test i18nTest, cfg config.Provider) *TranslationProvider {