mirror of
https://github.com/gohugoio/hugo.git
synced 2024-11-21 20:46:30 -05:00
parent
282f1aa3db
commit
f55d2f4376
19 changed files with 170 additions and 71 deletions
|
@ -58,7 +58,7 @@ func (s *staticSyncer) syncsStaticEvents(staticEvents []fsnotify.Event) error {
|
||||||
syncer.DestFs = c.Fs.Destination
|
syncer.DestFs = c.Fs.Destination
|
||||||
|
|
||||||
// prevent spamming the log on changes
|
// prevent spamming the log on changes
|
||||||
logger := helpers.NewDistinctFeedbackLogger()
|
logger := helpers.NewDistinctErrorLogger()
|
||||||
|
|
||||||
for _, ev := range staticEvents {
|
for _, ev := range staticEvents {
|
||||||
// Due to our approach of layering both directories and the content's rendered output
|
// Due to our approach of layering both directories and the content's rendered output
|
||||||
|
|
|
@ -22,6 +22,7 @@ import (
|
||||||
type IgnorableLogger interface {
|
type IgnorableLogger interface {
|
||||||
Logger
|
Logger
|
||||||
Errorsf(statementID, format string, v ...interface{})
|
Errorsf(statementID, format string, v ...interface{})
|
||||||
|
Apply(logger Logger) IgnorableLogger
|
||||||
}
|
}
|
||||||
|
|
||||||
type ignorableLogger struct {
|
type ignorableLogger struct {
|
||||||
|
@ -55,3 +56,10 @@ ignoreErrors = [%q]`, statementID)
|
||||||
|
|
||||||
l.Errorf(format, v...)
|
l.Errorf(format, v...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (l ignorableLogger) Apply(logger Logger) IgnorableLogger {
|
||||||
|
return ignorableLogger{
|
||||||
|
Logger: logger,
|
||||||
|
statements: l.statements,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -59,6 +59,8 @@ type Logger interface {
|
||||||
Println(v ...interface{})
|
Println(v ...interface{})
|
||||||
PrintTimerIfDelayed(start time.Time, name string)
|
PrintTimerIfDelayed(start time.Time, name string)
|
||||||
Debug() *log.Logger
|
Debug() *log.Logger
|
||||||
|
Debugf(format string, v ...interface{})
|
||||||
|
Debugln(v ...interface{})
|
||||||
Info() *log.Logger
|
Info() *log.Logger
|
||||||
Infof(format string, v ...interface{})
|
Infof(format string, v ...interface{})
|
||||||
Infoln(v ...interface{})
|
Infoln(v ...interface{})
|
||||||
|
@ -108,6 +110,14 @@ func (l *logger) Debug() *log.Logger {
|
||||||
return l.DEBUG
|
return l.DEBUG
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (l *logger) Debugf(format string, v ...interface{}) {
|
||||||
|
l.DEBUG.Printf(format, v...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *logger) Debugln(v ...interface{}) {
|
||||||
|
l.DEBUG.Println(v...)
|
||||||
|
}
|
||||||
|
|
||||||
func (l *logger) Infof(format string, v ...interface{}) {
|
func (l *logger) Infof(format string, v ...interface{}) {
|
||||||
l.INFO.Printf(format, v...)
|
l.INFO.Printf(format, v...)
|
||||||
}
|
}
|
||||||
|
|
11
deps/deps.go
vendored
11
deps/deps.go
vendored
|
@ -34,10 +34,7 @@ type Deps struct {
|
||||||
Log loggers.Logger `json:"-"`
|
Log loggers.Logger `json:"-"`
|
||||||
|
|
||||||
// Used to log errors that may repeat itself many times.
|
// Used to log errors that may repeat itself many times.
|
||||||
DistinctErrorLog *helpers.DistinctLogger
|
LogDistinct loggers.Logger
|
||||||
|
|
||||||
// Used to log warnings that may repeat itself many times.
|
|
||||||
DistinctWarningLog *helpers.DistinctLogger
|
|
||||||
|
|
||||||
// The templates to use. This will usually implement the full tpl.TemplateManager.
|
// The templates to use. This will usually implement the full tpl.TemplateManager.
|
||||||
tmpl tpl.TemplateHandler
|
tmpl tpl.TemplateHandler
|
||||||
|
@ -266,14 +263,12 @@ func New(cfg DepsCfg) (*Deps, error) {
|
||||||
ignoreErrors := cast.ToStringSlice(cfg.Cfg.Get("ignoreErrors"))
|
ignoreErrors := cast.ToStringSlice(cfg.Cfg.Get("ignoreErrors"))
|
||||||
ignorableLogger := loggers.NewIgnorableLogger(logger, ignoreErrors...)
|
ignorableLogger := loggers.NewIgnorableLogger(logger, ignoreErrors...)
|
||||||
|
|
||||||
distinctErrorLogger := helpers.NewDistinctLogger(logger.Error())
|
logDistinct := helpers.NewDistinctLogger(logger)
|
||||||
distinctWarnLogger := helpers.NewDistinctLogger(logger.Warn())
|
|
||||||
|
|
||||||
d := &Deps{
|
d := &Deps{
|
||||||
Fs: fs,
|
Fs: fs,
|
||||||
Log: ignorableLogger,
|
Log: ignorableLogger,
|
||||||
DistinctErrorLog: distinctErrorLogger,
|
LogDistinct: logDistinct,
|
||||||
DistinctWarningLog: distinctWarnLogger,
|
|
||||||
templateProvider: cfg.TemplateProvider,
|
templateProvider: cfg.TemplateProvider,
|
||||||
translationProvider: cfg.TranslationProvider,
|
translationProvider: cfg.TranslationProvider,
|
||||||
WithTemplate: cfg.WithTemplate,
|
WithTemplate: cfg.WithTemplate,
|
||||||
|
|
|
@ -31,3 +31,22 @@ Both functions return an empty string, so the messages are only printed to the c
|
||||||
```
|
```
|
||||||
|
|
||||||
Note that `errorf` and `warnf` support all the formatting verbs of the [fmt](https://golang.org/pkg/fmt/) package.
|
Note that `errorf` and `warnf` support all the formatting verbs of the [fmt](https://golang.org/pkg/fmt/) package.
|
||||||
|
|
||||||
|
## Suppress errors
|
||||||
|
|
||||||
|
Some times it may make sense to let the user suppress an ERROR and make the build succeed.
|
||||||
|
|
||||||
|
You can do this by using the `erroridf` function. This functions takes an error ID as the first arument.
|
||||||
|
|
||||||
|
|
||||||
|
``
|
||||||
|
{{ erroridf "my-custom-error" "You should consider fixing this."}}
|
||||||
|
```
|
||||||
|
|
||||||
|
This will produce:
|
||||||
|
|
||||||
|
```
|
||||||
|
ERROR 2021/06/07 17:47:38 You should consider fixing this.
|
||||||
|
If you feel that this should not be logged as an ERROR, you can ignore it by adding this to your site config:
|
||||||
|
ignoreErrors = ["my-custom-error"]
|
||||||
|
```
|
||||||
|
|
|
@ -29,6 +29,8 @@ import (
|
||||||
"unicode"
|
"unicode"
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
|
|
||||||
|
"github.com/gohugoio/hugo/common/loggers"
|
||||||
|
|
||||||
"github.com/mitchellh/hashstructure"
|
"github.com/mitchellh/hashstructure"
|
||||||
|
|
||||||
"github.com/gohugoio/hugo/hugofs"
|
"github.com/gohugoio/hugo/hugofs"
|
||||||
|
@ -40,7 +42,6 @@ import (
|
||||||
"github.com/jdkato/prose/transform"
|
"github.com/jdkato/prose/transform"
|
||||||
|
|
||||||
bp "github.com/gohugoio/hugo/bufferpool"
|
bp "github.com/gohugoio/hugo/bufferpool"
|
||||||
jww "github.com/spf13/jwalterweatherman"
|
|
||||||
"github.com/spf13/pflag"
|
"github.com/spf13/pflag"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -253,8 +254,8 @@ type LogPrinter interface {
|
||||||
|
|
||||||
// DistinctLogger ignores duplicate log statements.
|
// DistinctLogger ignores duplicate log statements.
|
||||||
type DistinctLogger struct {
|
type DistinctLogger struct {
|
||||||
|
loggers.Logger
|
||||||
sync.RWMutex
|
sync.RWMutex
|
||||||
getLogger func() LogPrinter
|
|
||||||
m map[string]bool
|
m map[string]bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -270,52 +271,105 @@ func (l *DistinctLogger) Reset() {
|
||||||
func (l *DistinctLogger) Println(v ...interface{}) {
|
func (l *DistinctLogger) Println(v ...interface{}) {
|
||||||
// fmt.Sprint doesn't add space between string arguments
|
// fmt.Sprint doesn't add space between string arguments
|
||||||
logStatement := strings.TrimSpace(fmt.Sprintln(v...))
|
logStatement := strings.TrimSpace(fmt.Sprintln(v...))
|
||||||
l.print(logStatement)
|
l.printIfNotPrinted("println", logStatement, func() {
|
||||||
|
l.Logger.Println(logStatement)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Printf will log the string returned from fmt.Sprintf given the arguments,
|
// Printf will log the string returned from fmt.Sprintf given the arguments,
|
||||||
// but not if it has been logged before.
|
// but not if it has been logged before.
|
||||||
// Note: A newline is appended.
|
|
||||||
func (l *DistinctLogger) Printf(format string, v ...interface{}) {
|
func (l *DistinctLogger) Printf(format string, v ...interface{}) {
|
||||||
logStatement := fmt.Sprintf(format, v...)
|
logStatement := fmt.Sprintf(format, v...)
|
||||||
l.print(logStatement)
|
l.printIfNotPrinted("printf", logStatement, func() {
|
||||||
|
l.Logger.Printf(format, v...)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *DistinctLogger) print(logStatement string) {
|
func (l *DistinctLogger) Debugf(format string, v ...interface{}) {
|
||||||
|
logStatement := fmt.Sprintf(format, v...)
|
||||||
|
l.printIfNotPrinted("debugf", logStatement, func() {
|
||||||
|
l.Logger.Debugf(format, v...)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *DistinctLogger) Debugln(v ...interface{}) {
|
||||||
|
logStatement := fmt.Sprint(v...)
|
||||||
|
l.printIfNotPrinted("debugln", logStatement, func() {
|
||||||
|
l.Logger.Debugln(v...)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *DistinctLogger) Infof(format string, v ...interface{}) {
|
||||||
|
logStatement := fmt.Sprintf(format, v...)
|
||||||
|
l.printIfNotPrinted("info", logStatement, func() {
|
||||||
|
l.Logger.Infof(format, v...)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *DistinctLogger) Infoln(v ...interface{}) {
|
||||||
|
logStatement := fmt.Sprint(v...)
|
||||||
|
l.printIfNotPrinted("infoln", logStatement, func() {
|
||||||
|
l.Logger.Infoln(v...)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *DistinctLogger) Warnf(format string, v ...interface{}) {
|
||||||
|
logStatement := fmt.Sprintf(format, v...)
|
||||||
|
l.printIfNotPrinted("warnf", logStatement, func() {
|
||||||
|
l.Logger.Warnf(format, v...)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
func (l *DistinctLogger) Warnln(v ...interface{}) {
|
||||||
|
logStatement := fmt.Sprint(v...)
|
||||||
|
l.printIfNotPrinted("warnln", logStatement, func() {
|
||||||
|
l.Logger.Warnln(v...)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
func (l *DistinctLogger) Errorf(format string, v ...interface{}) {
|
||||||
|
logStatement := fmt.Sprint(v...)
|
||||||
|
l.printIfNotPrinted("errorf", logStatement, func() {
|
||||||
|
l.Logger.Errorf(format, v...)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *DistinctLogger) Errorln(v ...interface{}) {
|
||||||
|
logStatement := fmt.Sprint(v...)
|
||||||
|
l.printIfNotPrinted("errorln", logStatement, func() {
|
||||||
|
l.Logger.Errorln(v...)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *DistinctLogger) hasPrinted(key string) bool {
|
||||||
l.RLock()
|
l.RLock()
|
||||||
if l.m[logStatement] {
|
defer l.RUnlock()
|
||||||
l.RUnlock()
|
_, found := l.m[key]
|
||||||
|
return found
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *DistinctLogger) printIfNotPrinted(level, logStatement string, print func()) {
|
||||||
|
key := level + logStatement
|
||||||
|
if l.hasPrinted(key) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
l.RUnlock()
|
|
||||||
|
|
||||||
l.Lock()
|
l.Lock()
|
||||||
if !l.m[logStatement] {
|
print()
|
||||||
l.getLogger().Println(logStatement)
|
l.m[key] = true
|
||||||
l.m[logStatement] = true
|
|
||||||
}
|
|
||||||
l.Unlock()
|
l.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewDistinctErrorLogger creates a new DistinctLogger that logs ERRORs
|
// NewDistinctErrorLogger creates a new DistinctLogger that logs ERRORs
|
||||||
func NewDistinctErrorLogger() *DistinctLogger {
|
func NewDistinctErrorLogger() loggers.Logger {
|
||||||
return &DistinctLogger{m: make(map[string]bool), getLogger: func() LogPrinter { return jww.ERROR }}
|
return &DistinctLogger{m: make(map[string]bool), Logger: loggers.NewErrorLogger()}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewDistinctLogger creates a new DistinctLogger that logs to the provided logger.
|
// NewDistinctLogger creates a new DistinctLogger that logs to the provided logger.
|
||||||
func NewDistinctLogger(logger LogPrinter) *DistinctLogger {
|
func NewDistinctLogger(logger loggers.Logger) loggers.Logger {
|
||||||
return &DistinctLogger{m: make(map[string]bool), getLogger: func() LogPrinter { return logger }}
|
return &DistinctLogger{m: make(map[string]bool), Logger: logger}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewDistinctWarnLogger creates a new DistinctLogger that logs WARNs
|
// NewDistinctWarnLogger creates a new DistinctLogger that logs WARNs
|
||||||
func NewDistinctWarnLogger() *DistinctLogger {
|
func NewDistinctWarnLogger() loggers.Logger {
|
||||||
return &DistinctLogger{m: make(map[string]bool), getLogger: func() LogPrinter { return jww.WARN }}
|
return &DistinctLogger{m: make(map[string]bool), Logger: loggers.NewWarningLogger()}
|
||||||
}
|
|
||||||
|
|
||||||
// NewDistinctFeedbackLogger creates a new DistinctLogger that can be used
|
|
||||||
// to give feedback to the user while not spamming with duplicates.
|
|
||||||
func NewDistinctFeedbackLogger() *DistinctLogger {
|
|
||||||
return &DistinctLogger{m: make(map[string]bool), getLogger: func() LogPrinter { return jww.FEEDBACK }}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -324,16 +378,13 @@ var (
|
||||||
|
|
||||||
// DistinctWarnLog can be used to avoid spamming the logs with warnings.
|
// DistinctWarnLog can be used to avoid spamming the logs with warnings.
|
||||||
DistinctWarnLog = NewDistinctWarnLogger()
|
DistinctWarnLog = NewDistinctWarnLogger()
|
||||||
|
|
||||||
// DistinctFeedbackLog can be used to avoid spamming the logs with info messages.
|
|
||||||
DistinctFeedbackLog = NewDistinctFeedbackLogger()
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// InitLoggers resets the global distinct loggers.
|
// InitLoggers resets the global distinct loggers.
|
||||||
func InitLoggers() {
|
func InitLoggers() {
|
||||||
DistinctErrorLog.Reset()
|
DistinctErrorLog.Reset()
|
||||||
DistinctWarnLog.Reset()
|
DistinctWarnLog.Reset()
|
||||||
DistinctFeedbackLog.Reset()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Deprecated informs about a deprecation, but only once for a given set of arguments' values.
|
// Deprecated informs about a deprecation, but only once for a given set of arguments' values.
|
||||||
|
|
|
@ -79,7 +79,7 @@ func (s *Site) writeDestAlias(path, permalink string, outputFormat output.Format
|
||||||
func (s *Site) publishDestAlias(allowRoot bool, path, permalink string, outputFormat output.Format, p page.Page) (err error) {
|
func (s *Site) publishDestAlias(allowRoot bool, path, permalink string, outputFormat output.Format, p page.Page) (err error) {
|
||||||
handler := newAliasHandler(s.Tmpl(), s.Log, allowRoot)
|
handler := newAliasHandler(s.Tmpl(), s.Log, allowRoot)
|
||||||
|
|
||||||
s.Log.Debug().Println("creating alias:", path, "redirecting to", permalink)
|
s.Log.Debugln("creating alias:", path, "redirecting to", permalink)
|
||||||
|
|
||||||
targetPath, err := handler.targetPathAlias(path)
|
targetPath, err := handler.targetPathAlias(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -28,7 +28,6 @@ var (
|
||||||
// implementations have no value on their own.
|
// implementations have no value on their own.
|
||||||
|
|
||||||
// Slice is not meant to be used externally. It's a bridge function
|
// Slice is not meant to be used externally. It's a bridge function
|
||||||
// for the template functions. See collections.Slice.
|
|
||||||
func (p *pageState) Slice(items interface{}) (interface{}, error) {
|
func (p *pageState) Slice(items interface{}) (interface{}, error) {
|
||||||
return page.ToPages(items)
|
return page.ToPages(items)
|
||||||
}
|
}
|
||||||
|
|
|
@ -579,7 +579,8 @@ func (h *HugoSites) resetLogs() {
|
||||||
h.Log.Reset()
|
h.Log.Reset()
|
||||||
loggers.GlobalErrorCounter.Reset()
|
loggers.GlobalErrorCounter.Reset()
|
||||||
for _, s := range h.Sites {
|
for _, s := range h.Sites {
|
||||||
s.Deps.DistinctErrorLog = helpers.NewDistinctLogger(h.Log.Error())
|
s.Deps.Log.Reset()
|
||||||
|
s.Deps.LogDistinct.Reset()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -102,7 +102,7 @@ func newPageFromMeta(
|
||||||
meta map[string]interface{},
|
meta map[string]interface{},
|
||||||
metaProvider *pageMeta) (*pageState, error) {
|
metaProvider *pageMeta) (*pageState, error) {
|
||||||
if metaProvider.f == nil {
|
if metaProvider.f == nil {
|
||||||
metaProvider.f = page.NewZeroFile(metaProvider.s.DistinctWarningLog)
|
metaProvider.f = page.NewZeroFile(metaProvider.s.LogDistinct)
|
||||||
}
|
}
|
||||||
|
|
||||||
ps, err := newPageBase(metaProvider)
|
ps, err := newPageBase(metaProvider)
|
||||||
|
|
|
@ -1007,7 +1007,7 @@ func (s *Site) processPartial(config *BuildCfg, init func(config *BuildCfg) erro
|
||||||
|
|
||||||
changeIdentities := make(identity.Identities)
|
changeIdentities := make(identity.Identities)
|
||||||
|
|
||||||
s.Log.Debug().Printf("Rebuild for events %q", events)
|
s.Log.Debugf("Rebuild for events %q", events)
|
||||||
|
|
||||||
h := s.h
|
h := s.h
|
||||||
|
|
||||||
|
@ -1026,7 +1026,7 @@ func (s *Site) processPartial(config *BuildCfg, init func(config *BuildCfg) erro
|
||||||
sourceFilesChanged = make(map[string]bool)
|
sourceFilesChanged = make(map[string]bool)
|
||||||
|
|
||||||
// prevent spamming the log on changes
|
// prevent spamming the log on changes
|
||||||
logger = helpers.NewDistinctFeedbackLogger()
|
logger = helpers.NewDistinctErrorLogger()
|
||||||
)
|
)
|
||||||
|
|
||||||
var cachePartitions []string
|
var cachePartitions []string
|
||||||
|
@ -1385,7 +1385,7 @@ func (s *Site) getMenusFromConfig() navigation.Menus {
|
||||||
s.Log.Errorln(err)
|
s.Log.Errorln(err)
|
||||||
} else {
|
} else {
|
||||||
for _, entry := range m {
|
for _, entry := range m {
|
||||||
s.Log.Debug().Printf("found menu: %q, in site config\n", name)
|
s.Log.Debugf("found menu: %q, in site config\n", name)
|
||||||
|
|
||||||
menuEntry := navigation.MenuEntry{Menu: name}
|
menuEntry := navigation.MenuEntry{Menu: name}
|
||||||
ime, err := maps.ToStringMapE(entry)
|
ime, err := maps.ToStringMapE(entry)
|
||||||
|
@ -1646,7 +1646,7 @@ func (s *Site) lookupLayouts(layouts ...string) tpl.Template {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Site) renderAndWriteXML(statCounter *uint64, name string, targetPath string, d interface{}, templ tpl.Template) error {
|
func (s *Site) renderAndWriteXML(statCounter *uint64, name string, targetPath string, d interface{}, templ tpl.Template) error {
|
||||||
s.Log.Debug().Printf("Render XML for %q to %q", name, targetPath)
|
s.Log.Debugf("Render XML for %q to %q", name, targetPath)
|
||||||
renderBuffer := bp.GetBuffer()
|
renderBuffer := bp.GetBuffer()
|
||||||
defer bp.PutBuffer(renderBuffer)
|
defer bp.PutBuffer(renderBuffer)
|
||||||
|
|
||||||
|
@ -1668,7 +1668,7 @@ func (s *Site) renderAndWriteXML(statCounter *uint64, name string, targetPath st
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Site) renderAndWritePage(statCounter *uint64, name string, targetPath string, p *pageState, templ tpl.Template) error {
|
func (s *Site) renderAndWritePage(statCounter *uint64, name string, targetPath string, p *pageState, templ tpl.Template) error {
|
||||||
s.Log.Debug().Printf("Render %s to %q", name, targetPath)
|
s.Log.Debugf("Render %s to %q", name, targetPath)
|
||||||
renderBuffer := bp.GetBuffer()
|
renderBuffer := bp.GetBuffer()
|
||||||
defer bp.PutBuffer(renderBuffer)
|
defer bp.PutBuffer(renderBuffer)
|
||||||
|
|
||||||
|
|
|
@ -389,13 +389,13 @@ func (s *Site) renderMainLanguageRedirect() error {
|
||||||
mainLang := s.h.multilingual.DefaultLang
|
mainLang := s.h.multilingual.DefaultLang
|
||||||
if s.Info.defaultContentLanguageInSubdir {
|
if s.Info.defaultContentLanguageInSubdir {
|
||||||
mainLangURL := s.PathSpec.AbsURL(mainLang.Lang+"/", false)
|
mainLangURL := s.PathSpec.AbsURL(mainLang.Lang+"/", false)
|
||||||
s.Log.Debug().Printf("Write redirect to main language %s: %s", mainLang, mainLangURL)
|
s.Log.Debugf("Write redirect to main language %s: %s", mainLang, mainLangURL)
|
||||||
if err := s.publishDestAlias(true, "/", mainLangURL, html, nil); err != nil {
|
if err := s.publishDestAlias(true, "/", mainLangURL, html, nil); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
mainLangURL := s.PathSpec.AbsURL("", false)
|
mainLangURL := s.PathSpec.AbsURL("", false)
|
||||||
s.Log.Debug().Printf("Write redirect to main language %s: %s", mainLang, mainLangURL)
|
s.Log.Debugf("Write redirect to main language %s: %s", mainLang, mainLangURL)
|
||||||
if err := s.publishDestAlias(true, mainLang.Lang, mainLangURL, html, nil); err != nil {
|
if err := s.publishDestAlias(true, mainLang.Lang, mainLangURL, html, nil); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,7 @@ import (
|
||||||
|
|
||||||
type translateFunc func(translationID string, templateData interface{}) string
|
type translateFunc func(translationID string, templateData interface{}) string
|
||||||
|
|
||||||
var i18nWarningLogger = helpers.NewDistinctFeedbackLogger()
|
var i18nWarningLogger = helpers.NewDistinctErrorLogger()
|
||||||
|
|
||||||
// Translator handles i18n translations.
|
// Translator handles i18n translations.
|
||||||
type Translator struct {
|
type Translator struct {
|
||||||
|
|
|
@ -16,17 +16,17 @@
|
||||||
package page
|
package page
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/gohugoio/hugo/helpers"
|
"github.com/gohugoio/hugo/common/loggers"
|
||||||
"github.com/gohugoio/hugo/hugofs"
|
"github.com/gohugoio/hugo/hugofs"
|
||||||
"github.com/gohugoio/hugo/source"
|
"github.com/gohugoio/hugo/source"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ZeroFile represents a zero value of source.File with warnings if invoked.
|
// ZeroFile represents a zero value of source.File with warnings if invoked.
|
||||||
type zeroFile struct {
|
type zeroFile struct {
|
||||||
log *helpers.DistinctLogger
|
log loggers.Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewZeroFile(log *helpers.DistinctLogger) source.File {
|
func NewZeroFile(log loggers.Logger) source.File {
|
||||||
return zeroFile{log: log}
|
return zeroFile{log: log}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -380,7 +380,7 @@ func (ns *Namespace) IsSet(a interface{}, key interface{}) (bool, error) {
|
||||||
return av.MapIndex(kv).IsValid(), nil
|
return av.MapIndex(kv).IsValid(), nil
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
helpers.DistinctFeedbackLog.Printf("WARNING: calling IsSet with unsupported type %q (%T) will always return false.\n", av.Kind(), a)
|
helpers.DistinctErrorLog.Printf("WARNING: calling IsSet with unsupported type %q (%T) will always return false.\n", av.Kind(), a)
|
||||||
}
|
}
|
||||||
|
|
||||||
return false, nil
|
return false, nil
|
||||||
|
|
|
@ -218,7 +218,7 @@ func newDeps(cfg config.Provider) *deps.Deps {
|
||||||
FileCaches: fileCaches,
|
FileCaches: fileCaches,
|
||||||
ContentSpec: cs,
|
ContentSpec: cs,
|
||||||
Log: logger,
|
Log: logger,
|
||||||
DistinctErrorLog: helpers.NewDistinctLogger(logger.Error()),
|
LogDistinct: helpers.NewDistinctLogger(logger),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,20 +17,22 @@ package fmt
|
||||||
import (
|
import (
|
||||||
_fmt "fmt"
|
_fmt "fmt"
|
||||||
|
|
||||||
|
"github.com/gohugoio/hugo/common/loggers"
|
||||||
|
|
||||||
"github.com/gohugoio/hugo/deps"
|
"github.com/gohugoio/hugo/deps"
|
||||||
"github.com/gohugoio/hugo/helpers"
|
"github.com/gohugoio/hugo/helpers"
|
||||||
)
|
)
|
||||||
|
|
||||||
// New returns a new instance of the fmt-namespaced template functions.
|
// New returns a new instance of the fmt-namespaced template functions.
|
||||||
func New(d *deps.Deps) *Namespace {
|
func New(d *deps.Deps) *Namespace {
|
||||||
|
ignorableLogger := d.Log.(loggers.IgnorableLogger)
|
||||||
|
distinctLogger := helpers.NewDistinctLogger(d.Log)
|
||||||
ns := &Namespace{
|
ns := &Namespace{
|
||||||
errorLogger: helpers.NewDistinctLogger(d.Log.Error()),
|
distinctLogger: ignorableLogger.Apply(distinctLogger),
|
||||||
warnLogger: helpers.NewDistinctLogger(d.Log.Warn()),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
d.BuildStartListeners.Add(func() {
|
d.BuildStartListeners.Add(func() {
|
||||||
ns.errorLogger.Reset()
|
ns.distinctLogger.Reset()
|
||||||
ns.warnLogger.Reset()
|
|
||||||
})
|
})
|
||||||
|
|
||||||
return ns
|
return ns
|
||||||
|
@ -38,8 +40,7 @@ func New(d *deps.Deps) *Namespace {
|
||||||
|
|
||||||
// Namespace provides template functions for the "fmt" namespace.
|
// Namespace provides template functions for the "fmt" namespace.
|
||||||
type Namespace struct {
|
type Namespace struct {
|
||||||
errorLogger *helpers.DistinctLogger
|
distinctLogger loggers.IgnorableLogger
|
||||||
warnLogger *helpers.DistinctLogger
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Print returns string representation of the passed arguments.
|
// Print returns string representation of the passed arguments.
|
||||||
|
@ -60,13 +61,21 @@ func (ns *Namespace) Println(a ...interface{}) string {
|
||||||
// Errorf formats according to a format specifier and logs an ERROR.
|
// Errorf formats according to a format specifier and logs an ERROR.
|
||||||
// It returns an empty string.
|
// It returns an empty string.
|
||||||
func (ns *Namespace) Errorf(format string, a ...interface{}) string {
|
func (ns *Namespace) Errorf(format string, a ...interface{}) string {
|
||||||
ns.errorLogger.Printf(format, a...)
|
ns.distinctLogger.Errorf(format, a...)
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// Erroridf formats according to a format specifier and logs an ERROR and
|
||||||
|
// an information text that the error with the given ID can be suppressed in config.
|
||||||
|
// It returns an empty string.
|
||||||
|
func (ns *Namespace) Erroridf(id, format string, a ...interface{}) string {
|
||||||
|
ns.distinctLogger.Errorsf(id, format, a...)
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
// Warnf formats according to a format specifier and logs a WARNING.
|
// Warnf formats according to a format specifier and logs a WARNING.
|
||||||
// It returns an empty string.
|
// It returns an empty string.
|
||||||
func (ns *Namespace) Warnf(format string, a ...interface{}) string {
|
func (ns *Namespace) Warnf(format string, a ...interface{}) string {
|
||||||
ns.warnLogger.Printf(format, a...)
|
ns.distinctLogger.Warnf(format, a...)
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,6 +57,13 @@ func init() {
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
ns.AddMethodMapping(ctx.Erroridf,
|
||||||
|
[]string{"erroridf"},
|
||||||
|
[][2]string{
|
||||||
|
{`{{ erroridf "my-err-id" "%s." "failed" }}`, ``},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
ns.AddMethodMapping(ctx.Warnf,
|
ns.AddMethodMapping(ctx.Warnf,
|
||||||
[]string{"warnf"},
|
[]string{"warnf"},
|
||||||
[][2]string{
|
[][2]string{
|
||||||
|
|
|
@ -30,7 +30,7 @@ func TestInit(t *testing.T) {
|
||||||
var ns *internal.TemplateFuncsNamespace
|
var ns *internal.TemplateFuncsNamespace
|
||||||
|
|
||||||
for _, nsf := range internal.TemplateFuncsNamespaceRegistry {
|
for _, nsf := range internal.TemplateFuncsNamespaceRegistry {
|
||||||
ns = nsf(&deps.Deps{Log: loggers.NewErrorLogger()})
|
ns = nsf(&deps.Deps{Log: loggers.NewIgnorableLogger(loggers.NewErrorLogger())})
|
||||||
if ns.Name == name {
|
if ns.Name == name {
|
||||||
found = true
|
found = true
|
||||||
break
|
break
|
||||||
|
|
Loading…
Reference in a new issue