]> git.maquefel.me Git - brevno-suite/hugo/commitdiff
Revise the deprecation logging
authorBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Thu, 26 Oct 2023 07:38:13 +0000 (09:38 +0200)
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Thu, 26 Oct 2023 18:41:19 +0000 (20:41 +0200)
This introduces a more automatic way of increasing the log levels for deprecation log statements based on the version it was deprecated.

The thresholds are a little arbitrary, but

* We log INFO for 6 releases
* We log WARN for another 6 releases
* THen ERROR (failing the build)

This should give theme authors plenty of time to catch up without having the log filled with warnings.

12 files changed:
commands/commandeer.go
common/hugo/hugo.go
common/hugo/hugo_test.go
common/hugo/version.go
config/allconfig/allconfig.go
helpers/general.go
hugolib/hugo_sites_build.go
hugolib/page__meta.go
hugolib/site_new.go
source/fileInfo.go
tpl/collections/collections.go
tpl/lang/lang.go

index b4f250a32aa24b7153665fc735e1e2ca569b3e10..c3e2019b514d91a4386729ea279c557b52be64e0 100644 (file)
@@ -38,6 +38,7 @@ import (
 
        "github.com/gohugoio/hugo/common/hstrings"
        "github.com/gohugoio/hugo/common/htime"
+       "github.com/gohugoio/hugo/common/hugo"
        "github.com/gohugoio/hugo/common/loggers"
        "github.com/gohugoio/hugo/common/paths"
        "github.com/gohugoio/hugo/config"
@@ -50,9 +51,7 @@ import (
        "github.com/spf13/cobra"
 )
 
-var (
-       errHelp = errors.New("help requested")
-)
+var errHelp = errors.New("help requested")
 
 // Execute executes a command.
 func Execute(args []string) error {
@@ -182,11 +181,9 @@ func (r *rootCommand) ConfigFromConfig(key int32, oldConf *commonConfig) (*commo
                        cfg:     oldConf.cfg,
                        fs:      fs,
                }, nil
-
        })
 
        return cc, err
-
 }
 
 func (r *rootCommand) ConfigFromProvider(key int32, cfg config.Provider) (*commonConfig, error) {
@@ -211,7 +208,7 @@ func (r *rootCommand) ConfigFromProvider(key int32, cfg config.Provider) (*commo
                if !cfg.IsSet("workingDir") {
                        cfg.Set("workingDir", dir)
                } else {
-                       if err := os.MkdirAll(cfg.GetString("workingDir"), 0777); err != nil {
+                       if err := os.MkdirAll(cfg.GetString("workingDir"), 0o777); err != nil {
                                return nil, fmt.Errorf("failed to create workingDir: %w", err)
                        }
                }
@@ -303,7 +300,6 @@ func (r *rootCommand) ConfigFromProvider(key int32, cfg config.Provider) (*commo
        })
 
        return cc, err
-
 }
 
 func (r *rootCommand) HugFromConfig(conf *commonConfig) (*hugolib.HugoSites, error) {
@@ -348,7 +344,6 @@ func (r *rootCommand) Run(ctx context.Context, cd *simplecobra.Commandeer, args
                err := b.build()
                return err
        }()
-
        if err != nil {
                return err
        }
@@ -434,12 +429,13 @@ func (r *rootCommand) createLogger(running bool) (loggers.Logger, error) {
                }
        } else {
                if r.verbose {
-                       helpers.Deprecated("--verbose", "use --logLevel info", false)
+                       hugo.Deprecate("--verbose", "use --logLevel info", "v0.114.0")
+                       hugo.Deprecate("--verbose", "use --logLevel info", "v0.114.0")
                        level = logg.LevelInfo
                }
 
                if r.debug {
-                       helpers.Deprecated("--debug", "use --logLevel debug", false)
+                       hugo.Deprecate("--debug", "use --logLevel debug", "v0.114.0")
                        level = logg.LevelDebug
                }
        }
@@ -453,7 +449,6 @@ func (r *rootCommand) createLogger(running bool) (loggers.Logger, error) {
        }
 
        return loggers.New(optsLogger), nil
-
 }
 
 func (r *rootCommand) Reset() {
@@ -519,7 +514,6 @@ func applyLocalFlagsBuildConfig(cmd *cobra.Command, r *rootCommand) {
        _ = cmd.Flags().SetAnnotation("cacheDir", cobra.BashCompSubdirsInDir, []string{})
        cmd.Flags().StringP("contentDir", "c", "", "filesystem path to content directory")
        _ = cmd.Flags().SetAnnotation("theme", cobra.BashCompSubdirsInDir, []string{"themes"})
-
 }
 
 // Flags needed to do a build (used by hugo and hugo server commands)
@@ -558,7 +552,6 @@ func applyLocalFlagsBuild(cmd *cobra.Command, r *rootCommand) {
        cmd.Flags().StringSlice("disableKinds", []string{}, "disable different kind of pages (home, RSS etc.)")
        cmd.Flags().Bool("minify", false, "minify any supported output format (HTML, XML etc.)")
        _ = cmd.Flags().SetAnnotation("destination", cobra.BashCompSubdirsInDir, []string{})
-
 }
 
 func (r *rootCommand) timeTrack(start time.Time, name string) {
index 1138cf2acb6012dce7995c1c6af178d48338aa47..f6eb72d8f49c2694438507cb49b17fc6b973d200 100644 (file)
@@ -22,14 +22,15 @@ import (
        "sort"
        "strings"
        "sync"
+       "time"
 
        godartsassv1 "github.com/bep/godartsass"
+       "github.com/bep/logg"
        "github.com/mitchellh/mapstructure"
 
-       "time"
-
        "github.com/bep/godartsass/v2"
        "github.com/gohugoio/hugo/common/hexec"
+       "github.com/gohugoio/hugo/common/loggers"
        "github.com/gohugoio/hugo/hugofs/files"
 
        "github.com/spf13/afero"
@@ -183,8 +184,10 @@ type buildInfo struct {
        *debug.BuildInfo
 }
 
-var bInfo *buildInfo
-var bInfoInit sync.Once
+var (
+       bInfo     *buildInfo
+       bInfoInit sync.Once
+)
 
 func getBuildInfo() *buildInfo {
        bInfoInit.Do(func() {
@@ -211,7 +214,6 @@ func getBuildInfo() *buildInfo {
                                bInfo.GoArch = s.Value
                        }
                }
-
        })
 
        return bInfo
@@ -255,7 +257,7 @@ func GetDependencyListNonGo() []string {
        }
 
        if dartSass := dartSassVersion(); dartSass.ProtocolVersion != "" {
-               var dartSassPath = "github.com/sass/dart-sass-embedded"
+               dartSassPath := "github.com/sass/dart-sass-embedded"
                if IsDartSassV2() {
                        dartSassPath = "github.com/sass/dart-sass"
                }
@@ -346,3 +348,45 @@ var (
 func IsDartSassV2() bool {
        return !strings.Contains(DartSassBinaryName, "embedded")
 }
+
+// Deprecate informs about a deprecation starting at the given version.
+//
+// A deprecation typically needs a simple change in the template, but doing so will make the template incompatible with older versions.
+// Theme maintainers generally want
+// 1. No warnings or errors in the console when building a Hugo site.
+// 2. Their theme to work for at least the last few Hugo versions.
+func Deprecate(item, alternative string, version string) {
+       level := deprecationLogLevelFromVersion(version)
+       DeprecateLevel(item, alternative, version, level)
+}
+
+// DeprecateLevel informs about a deprecation logging at the given level.
+func DeprecateLevel(item, alternative, version string, level logg.Level) {
+       var msg string
+       if level == logg.LevelError {
+               msg = fmt.Sprintf("%s was deprecated in Hugo %s and will be removed in Hugo %s. %s", item, version, CurrentVersion.Next().ReleaseVersion(), alternative)
+       } else {
+               msg = fmt.Sprintf("%s was deprecated in Hugo %s and will be removed in a future release. %s", item, version, alternative)
+       }
+
+       loggers.Log().Logger().WithLevel(level).Logf(msg)
+}
+
+// We ususally do about one minor version a month.
+// We want people to run at least the current and previous version without any warnings.
+// We want people who don't update Hugo that often to see the warnings and errors before we remove the feature.
+func deprecationLogLevelFromVersion(ver string) logg.Level {
+       from := MustParseVersion(ver)
+       to := CurrentVersion
+       minorDiff := to.Minor - from.Minor
+       switch {
+       case minorDiff >= 12:
+               // Start failing the build after about a year.
+               return logg.LevelError
+       case minorDiff >= 6:
+               // Start printing warnings after about six months.
+               return logg.LevelWarn
+       default:
+               return logg.LevelInfo
+       }
+}
index 5b4a6f9ad200e5e12a5a5c4383e75c038584a4dd..e252dffbe927c3f790b10233bab929416d7e172e 100644 (file)
@@ -17,6 +17,7 @@ import (
        "fmt"
        "testing"
 
+       "github.com/bep/logg"
        qt "github.com/frankban/quicktest"
 )
 
@@ -49,6 +50,20 @@ func TestHugoInfo(t *testing.T) {
        c.Assert(devHugoInfo.IsServer(), qt.Equals, true)
 }
 
+func TestDeprecationLogLevelFromVersion(t *testing.T) {
+       c := qt.New(t)
+
+       c.Assert(deprecationLogLevelFromVersion("0.55.0"), qt.Equals, logg.LevelError)
+       ver := CurrentVersion
+       c.Assert(deprecationLogLevelFromVersion(ver.String()), qt.Equals, logg.LevelInfo)
+       ver.Minor -= 1
+       c.Assert(deprecationLogLevelFromVersion(ver.String()), qt.Equals, logg.LevelInfo)
+       ver.Minor -= 6
+       c.Assert(deprecationLogLevelFromVersion(ver.String()), qt.Equals, logg.LevelWarn)
+       ver.Minor -= 6
+       c.Assert(deprecationLogLevelFromVersion(ver.String()), qt.Equals, logg.LevelError)
+}
+
 type testConfig struct {
        environment string
        running     bool
index 3bb6472e2fad481f4b0a86f8c4bdda745e96608b..6cabfdbb964ca1f9b9fc63690168b4c514abfe16 100644 (file)
@@ -67,8 +67,11 @@ func (h VersionString) String() string {
 
 // Compare implements the compare.Comparer interface.
 func (h VersionString) Compare(other any) int {
-       v := MustParseVersion(h.String())
-       return compareVersions(v, other)
+       return compareVersions(h.Version(), other)
+}
+
+func (h VersionString) Version() Version {
+       return MustParseVersion(h.String())
 }
 
 // Eq implements the compare.Eqer interface.
@@ -264,7 +267,6 @@ func compareFloatWithVersion(v1 float64, v2 Version) int {
 
        if v1maj > v2.Major {
                return 1
-
        }
 
        if v1maj < v2.Major {
@@ -276,7 +278,6 @@ func compareFloatWithVersion(v1 float64, v2 Version) int {
        }
 
        return -1
-
 }
 
 func GoMinorVersion() int {
index 134df1f5c25c2b3168a023f2f33ec66391b3f03f..9f0d73ecda36ee0f7d465a05e78975340683e208 100644 (file)
@@ -27,6 +27,7 @@ import (
        "time"
 
        "github.com/gohugoio/hugo/cache/filecache"
+       "github.com/gohugoio/hugo/common/hugo"
        "github.com/gohugoio/hugo/common/loggers"
        "github.com/gohugoio/hugo/common/maps"
        "github.com/gohugoio/hugo/common/urls"
@@ -784,7 +785,7 @@ func fromLoadConfigResult(fs afero.Fs, logger loggers.Logger, res config.LoadCon
                                        // We accidentally allowed it in the past, so we need to support it a little longer,
                                        // But log a warning.
                                        if _, found := params[kk]; !found {
-                                               helpers.Deprecated(fmt.Sprintf("config: languages.%s.%s: custom params on the language top level", k, kk), fmt.Sprintf("Put the value below [languages.%s.params]. See https://gohugo.io/content-management/multilingual/#changes-in-hugo-01120", k), false)
+                                               hugo.Deprecate(fmt.Sprintf("config: languages.%s.%s: custom params on the language top level", k, kk), fmt.Sprintf("Put the value below [languages.%s.params]. See https://gohugo.io/content-management/multilingual/#changes-in-hugo-01120", k), "v0.112.0")
                                                params[kk] = vv
                                        }
                                }
index e484b92f09602d05a836e434de7da20407d47b3f..281414b2a5fcbf0d95432ce38a3b6eb5e69a2cd3 100644 (file)
@@ -27,9 +27,6 @@ import (
        "unicode"
        "unicode/utf8"
 
-       "github.com/gohugoio/hugo/common/hugo"
-       "github.com/gohugoio/hugo/common/loggers"
-
        "github.com/spf13/afero"
 
        "github.com/jdkato/prose/transform"
@@ -246,19 +243,6 @@ func compareStringSlices(a, b []string) bool {
        return true
 }
 
-// Deprecated informs about a deprecation, but only once for a given set of arguments' values.
-// If the err flag is enabled, it logs as an ERROR (will exit with -1) and the text will
-// point at the next Hugo release.
-// The idea is two remove an item in two Hugo releases to give users and theme authors
-// plenty of time to fix their templates.
-func Deprecated(item, alternative string, err bool) {
-       if err {
-               loggers.Log().Errorf("%s is deprecated and will be removed in Hugo %s. %s", item, hugo.CurrentVersion.Next().ReleaseVersion(), alternative)
-       } else {
-               loggers.Log().Warnf("%s is deprecated and will be removed in a future release. %s", item, alternative)
-       }
-}
-
 // SliceToLower goes through the source slice and lowers all values.
 func SliceToLower(s []string) []string {
        if s == nil {
index 27fde5822ebd9ebcab4a257c1cdc75ba127f0b52..72b5fe7718c6879577bc71c5746ee3e2e8073a39 100644 (file)
@@ -25,7 +25,6 @@ import (
 
        "github.com/bep/logg"
        "github.com/gohugoio/hugo/hugofs/files"
-       "github.com/gohugoio/hugo/langs"
        "github.com/gohugoio/hugo/publisher"
        "github.com/gohugoio/hugo/tpl"
 
@@ -40,14 +39,8 @@ import (
        "github.com/gohugoio/hugo/output"
 
        "github.com/fsnotify/fsnotify"
-       "github.com/gohugoio/hugo/helpers"
 )
 
-func init() {
-       // To avoid circular dependencies, we set this here.
-       langs.DeprecationFunc = helpers.Deprecated
-}
-
 // Build builds all sites. If filesystem events are provided,
 // this is considered to be a potential partial rebuild.
 func (h *HugoSites) Build(config BuildCfg, events ...fsnotify.Event) error {
index 1c4f13d3bbe6ff99909faad5f7a95b15db3ece34..0dd2369045fc5aa65f4fbd1948ad16c1b83bb671 100644 (file)
@@ -130,7 +130,7 @@ func (p *pageMeta) Aliases() []string {
 }
 
 func (p *pageMeta) Author() page.Author {
-       helpers.Deprecated(".Author", "Use taxonomies.", false)
+       hugo.Deprecate(".Author", "Use taxonomies.", "v0.98.0")
        authors := p.Authors()
 
        for _, author := range authors {
@@ -140,7 +140,7 @@ func (p *pageMeta) Author() page.Author {
 }
 
 func (p *pageMeta) Authors() page.AuthorList {
-       helpers.Deprecated(".Authors", "Use taxonomies.", true)
+       hugo.Deprecate(".Author", "Use taxonomies.", "v0.112.0")
        return nil
 }
 
@@ -226,7 +226,7 @@ func (p *pageMeta) Path() string {
        {{ $path = .Path }}
   {{ end }}
 `
-               helpers.Deprecated(".Path when the page is backed by a file", "We plan to use Path for a canonical source path and you probably want to check the source is a file. To get the current behaviour, you can use a construct similar to the one below:\n"+example, false)
+               p.s.Log.Warnln(".Path when the page is backed by a file is deprecated. We plan to use Path for a canonical source path and you probably want to check the source is a file. To get the current behaviour, you can use a construct similar to the one below:\n" + example)
 
        }
 
index b35de79ef28be3e44759795089be4ebd3161631b..127b0e296b9b80c65dbd45f637b0e9dc20693fff 100644 (file)
@@ -31,7 +31,6 @@ import (
        "github.com/gohugoio/hugo/config"
        "github.com/gohugoio/hugo/config/allconfig"
        "github.com/gohugoio/hugo/deps"
-       "github.com/gohugoio/hugo/helpers"
        "github.com/gohugoio/hugo/identity"
        "github.com/gohugoio/hugo/langs"
        "github.com/gohugoio/hugo/langs/i18n"
@@ -48,9 +47,7 @@ import (
        "github.com/gohugoio/hugo/tpl/tplimpl"
 )
 
-var (
-       _ page.Site = (*Site)(nil)
-)
+var _ page.Site = (*Site)(nil)
 
 type Site struct {
        conf     *allconfig.Config
@@ -236,7 +233,6 @@ func NewHugoSites(cfg deps.DepsCfg) (*HugoSites, error) {
        }
 
        return h, err
-
 }
 
 func newHugoSitesNew(cfg deps.DepsCfg, d *deps.Deps, sites []*Site) (*HugoSites, error) {
@@ -358,7 +354,7 @@ func newHugoSitesNew(cfg deps.DepsCfg, d *deps.Deps, sites []*Site) (*HugoSites,
 // Returns true if we're running in a server.
 // Deprecated: use hugo.IsServer instead
 func (s *Site) IsServer() bool {
-       helpers.Deprecated(".Site.IsServer", "Use hugo.IsServer instead.", false)
+       hugo.Deprecate(".Site.IsServer", "Use hugo.IsServer instead.", "v0.120.0")
        return s.conf.Internal.Running
 }
 
@@ -377,7 +373,7 @@ func (s *Site) Copyright() string {
 }
 
 func (s *Site) RSSLink() template.URL {
-       helpers.Deprecated("Site.RSSLink", "Use the Output Format's Permalink method instead, e.g. .OutputFormats.Get \"RSS\".Permalink", false)
+       hugo.Deprecate("Site.RSSLink", "Use the Output Format's Permalink method instead, e.g. .OutputFormats.Get \"RSS\".Permalink", "v0.114.0")
        rssOutputFormat := s.home.OutputFormats().Get("rss")
        return template.URL(rssOutputFormat.Permalink())
 }
@@ -449,13 +445,13 @@ func (s *Site) Social() map[string]string {
 
 // Deprecated: Use .Site.Config.Services.Disqus.Shortname instead
 func (s *Site) DisqusShortname() string {
-       helpers.Deprecated(".Site.DisqusShortname", "Use .Site.Config.Services.Disqus.Shortname instead.", false)
+       hugo.Deprecate(".Site.DisqusShortname", "Use .Site.Config.Services.Disqus.Shortname instead.", "v0.120.0")
        return s.Config().Services.Disqus.Shortname
 }
 
 // Deprecated: Use .Site.Config.Services.GoogleAnalytics.ID instead
 func (s *Site) GoogleAnalytics() string {
-       helpers.Deprecated(".Site.GoogleAnalytics", "Use .Site.Config.Services.GoogleAnalytics.ID instead.", false)
+       hugo.Deprecate(".Site.GoogleAnalytics", "Use .Site.Config.Services.GoogleAnalytics.ID instead.", "v0.120.0")
        return s.Config().Services.GoogleAnalytics.ID
 }
 
index c58a0c3b90822bf1c09fc69cf88a50dde4a6f94e..60c6e6ea80b0d062edb9ed5362216551210972a2 100644 (file)
@@ -21,6 +21,7 @@ import (
        "time"
 
        "github.com/bep/gitmap"
+       "github.com/gohugoio/hugo/common/hugo"
        "github.com/gohugoio/hugo/common/paths"
 
        "github.com/gohugoio/hugo/hugofs/files"
@@ -63,7 +64,6 @@ type fileOverlap interface {
 }
 
 type FileWithoutOverlap interface {
-
        // Filename gets the full path and filename to the file.
        Filename() string
 
@@ -102,7 +102,6 @@ type FileWithoutOverlap interface {
 
 // FileInfo describes a source file.
 type FileInfo struct {
-
        // Absolute filename to the file on disk.
        filename string
 
@@ -143,7 +142,7 @@ func (fi *FileInfo) Dir() string { return fi.relDir }
 
 // Extension is an alias to Ext().
 func (fi *FileInfo) Extension() string {
-       helpers.Deprecated(".File.Extension", "Use .File.Ext instead. ", false)
+       hugo.Deprecate(".File.Extension", "Use .File.Ext instead.", "v0.96.0")
        return fi.Ext()
 }
 
index 2f7eb745bbab1cc9d5bd50cb4e7684e796c6b128..279dbb169282b02c8a9c4fcf1a633819293d5f30 100644 (file)
@@ -28,10 +28,10 @@ import (
        "errors"
 
        "github.com/gohugoio/hugo/common/collections"
+       "github.com/gohugoio/hugo/common/hugo"
        "github.com/gohugoio/hugo/common/maps"
        "github.com/gohugoio/hugo/common/types"
        "github.com/gohugoio/hugo/deps"
-       "github.com/gohugoio/hugo/helpers"
        "github.com/gohugoio/hugo/langs"
        "github.com/gohugoio/hugo/tpl/compare"
        "github.com/spf13/cast"
@@ -200,7 +200,7 @@ func (ns *Namespace) Dictionary(values ...any) (map[string]any, error) {
 // empty string.
 // Deprecated: Use the index function instead.
 func (ns *Namespace) EchoParam(c, k any) any {
-       helpers.Deprecated("collections.EchoParam", "Use the index function instead.", false)
+       hugo.Deprecate("collections.EchoParam", "Use the index function instead.", "v0.120.0")
        av, isNil := indirect(reflect.ValueOf(c))
        if isNil {
                return ""
index e83f70710b25e203b1547723be42a8cbb957a22a..92b3aa8ff2f9403d942936f78a24c92cbf03e068 100644 (file)
@@ -16,19 +16,18 @@ package lang
 
 import (
        "context"
+       "errors"
        "fmt"
        "math"
        "strconv"
        "strings"
 
-       "errors"
-
        "github.com/gohugoio/locales"
        translators "github.com/gohugoio/localescompressed"
 
        "github.com/gohugoio/hugo/common/hreflect"
+       "github.com/gohugoio/hugo/common/hugo"
        "github.com/gohugoio/hugo/deps"
-       "github.com/gohugoio/hugo/helpers"
        "github.com/spf13/cast"
 )
 
@@ -243,7 +242,7 @@ func (ns *Namespace) FormatNumberCustom(precision, number any, options ...any) (
 
 // Deprecated: Use lang.FormatNumberCustom instead.
 func (ns *Namespace) NumFmt(precision, number any, options ...any) (string, error) {
-       helpers.Deprecated("lang.NumFmt", "Use lang.FormatNumberCustom instead.", false)
+       hugo.Deprecate("lang.NumFmt", "Use lang.FormatNumberCustom instead.", "v0.120.0")
        return ns.FormatNumberCustom(precision, number, options...)
 }