Only print the path warnings once

We could reset and rerun it on server rebuilds, but that report needs a full build to make sense.

Also clean up the config vs flags in this area: Make all config settings match the flags e.g. `printPathWarnings`, but set up aliases for the
old.

Fixes #11187
This commit is contained in:
Bjørn Erik Pedersen 2023-06-30 08:47:11 +02:00
parent b4b65245b2
commit ffd37d4f75
11 changed files with 76 additions and 45 deletions

View file

@ -110,12 +110,10 @@ type rootCommand struct {
environment string environment string
// Common build flags. // Common build flags.
baseURL string baseURL string
gc bool gc bool
poll string poll string
forceSyncStatic bool forceSyncStatic bool
printPathWarnings bool
printUnusedTemplates bool
// Profile flags (for debugging of performance problems) // Profile flags (for debugging of performance problems)
cpuprofile string cpuprofile string
@ -288,7 +286,7 @@ func (r *rootCommand) ConfigFromProvider(key int32, cfg config.Provider) (*commo
htime.Clock = clock.Start(configs.Base.C.Clock) htime.Clock = clock.Start(configs.Base.C.Clock)
} }
if base.LogPathWarnings { if base.PrintPathWarnings {
// Note that we only care about the "dynamic creates" here, // Note that we only care about the "dynamic creates" here,
// so skip the static fs. // so skip the static fs.
fs.PublishDir = hugofs.NewCreateCountingFs(fs.PublishDir) fs.PublishDir = hugofs.NewCreateCountingFs(fs.PublishDir)
@ -544,8 +542,8 @@ func applyLocalFlagsBuild(cmd *cobra.Command, r *rootCommand) {
cmd.Flags().BoolP("noChmod", "", false, "don't sync permission mode of files") cmd.Flags().BoolP("noChmod", "", false, "don't sync permission mode of files")
cmd.Flags().BoolP("noBuildLock", "", false, "don't create .hugo_build.lock file") cmd.Flags().BoolP("noBuildLock", "", false, "don't create .hugo_build.lock file")
cmd.Flags().BoolP("printI18nWarnings", "", false, "print missing translations") cmd.Flags().BoolP("printI18nWarnings", "", false, "print missing translations")
cmd.Flags().BoolVarP(&r.printPathWarnings, "printPathWarnings", "", false, "print warnings on duplicate target paths etc.") cmd.Flags().BoolP("printPathWarnings", "", false, "print warnings on duplicate target paths etc.")
cmd.Flags().BoolVarP(&r.printUnusedTemplates, "printUnusedTemplates", "", false, "print warnings on unused templates.") cmd.Flags().BoolP("printUnusedTemplates", "", false, "print warnings on unused templates.")
cmd.Flags().StringVarP(&r.cpuprofile, "profile-cpu", "", "", "write cpu profile to `file`") cmd.Flags().StringVarP(&r.cpuprofile, "profile-cpu", "", "", "write cpu profile to `file`")
cmd.Flags().StringVarP(&r.memprofile, "profile-mem", "", "", "write memory profile to `file`") cmd.Flags().StringVarP(&r.memprofile, "profile-mem", "", "", "write memory profile to `file`")
cmd.Flags().BoolVarP(&r.printm, "printMemoryUsage", "", false, "print memory usage to screen at intervals") cmd.Flags().BoolVarP(&r.printm, "printMemoryUsage", "", false, "print memory usage to screen at intervals")

View file

@ -79,11 +79,9 @@ func flagsToCfgWithAdditionalConfigBase(cd *simplecobra.Commandeer, cfg config.P
// Flags with a different name in the config. // Flags with a different name in the config.
keyMap := map[string]string{ keyMap := map[string]string{
"minify": "minifyOutput", "minify": "minifyOutput",
"destination": "publishDir", "destination": "publishDir",
"printI18nWarnings": "logI18nWarnings", "editor": "newContentEditor",
"printPathWarnings": "logPathWarnings",
"editor": "newContentEditor",
} }
// Flags that we for some reason don't want to expose in the site config. // Flags that we for some reason don't want to expose in the site config.

View file

@ -43,7 +43,6 @@ import (
"github.com/gohugoio/hugo/hugolib/filesystems" "github.com/gohugoio/hugo/hugolib/filesystems"
"github.com/gohugoio/hugo/livereload" "github.com/gohugoio/hugo/livereload"
"github.com/gohugoio/hugo/resources/page" "github.com/gohugoio/hugo/resources/page"
"github.com/gohugoio/hugo/tpl"
"github.com/gohugoio/hugo/watcher" "github.com/gohugoio/hugo/watcher"
"github.com/spf13/fsync" "github.com/spf13/fsync"
"golang.org/x/sync/errgroup" "golang.org/x/sync/errgroup"
@ -418,13 +417,6 @@ func (c *hugoBuilder) build() error {
return err return err
} }
if c.r.printUnusedTemplates {
unusedTemplates := h.Tmpl().(tpl.UnusedTemplatesProvider).UnusedTemplates()
for _, unusedTemplate := range unusedTemplates {
c.r.logger.Warnf("Template %s is unused, source file %s", unusedTemplate.Name(), unusedTemplate.Filename())
}
}
h.PrintProcessingStats(os.Stdout) h.PrintProcessingStats(os.Stdout)
c.r.Println() c.r.Println()
} }

View file

@ -484,12 +484,6 @@ type RootConfig struct {
// Enable to print greppable placeholders (on the form "[i18n] TRANSLATIONID") for missing translation strings. // Enable to print greppable placeholders (on the form "[i18n] TRANSLATIONID") for missing translation strings.
EnableMissingTranslationPlaceholders bool EnableMissingTranslationPlaceholders bool
// Enable to print warnings for missing translation strings.
LogI18nWarnings bool
// ENable to print warnings for multiple files published to the same destination.
LogPathWarnings bool
// Enable to panic on warning log entries. This may make it easier to detect the source. // Enable to panic on warning log entries. This may make it easier to detect the source.
PanicOnWarning bool PanicOnWarning bool
@ -525,6 +519,12 @@ type RootConfig struct {
// Whether to track and print unused templates during the build. // Whether to track and print unused templates during the build.
PrintUnusedTemplates bool PrintUnusedTemplates bool
// Enable to print warnings for missing translation strings.
PrintI18nWarnings bool
// ENable to print warnings for multiple files published to the same destination.
PrintPathWarnings bool
// URL to be used as a placeholder when a page reference cannot be found in ref or relref. Is used as-is. // URL to be used as a placeholder when a page reference cannot be found in ref or relref. Is used as-is.
RefLinksNotFoundURL string RefLinksNotFoundURL string

View file

@ -199,8 +199,8 @@ func (c ConfigLanguage) EnableMissingTranslationPlaceholders() bool {
return c.config.EnableMissingTranslationPlaceholders return c.config.EnableMissingTranslationPlaceholders
} }
func (c ConfigLanguage) LogI18nWarnings() bool { func (c ConfigLanguage) PrintI18nWarnings() bool {
return c.config.LogI18nWarnings return c.config.PrintI18nWarnings
} }
func (c ConfigLanguage) CreateTitle(s string) string { func (c ConfigLanguage) CreateTitle(s string) string {

View file

@ -69,3 +69,21 @@ Title: {{ .Title }}
b.Assert(modConf.Mounts[1].Lang, qt.Equals, "sv") b.Assert(modConf.Mounts[1].Lang, qt.Equals, "sv")
} }
func TestConfigAliases(t *testing.T) {
files := `
-- hugo.toml --
baseURL = "https://example.com"
logI18nWarnings = true
logPathWarnings = true
`
b := hugolib.NewIntegrationTestBuilder(
hugolib.IntegrationTestConfig{T: t, TxtarString: files},
).Build()
conf := b.H.Configs.Base
b.Assert(conf.PrintI18nWarnings, qt.Equals, true)
b.Assert(conf.PrintPathWarnings, qt.Equals, true)
}

View file

@ -139,7 +139,11 @@ type configLoader struct {
// Handle some legacy values. // Handle some legacy values.
func (l configLoader) applyConfigAliases() error { func (l configLoader) applyConfigAliases() error {
aliases := []types.KeyValueStr{{Key: "taxonomies", Value: "indexes"}} aliases := []types.KeyValueStr{
{Key: "indexes", Value: "taxonomies"},
{Key: "logI18nWarnings", Value: "printI18nWarnings"},
{Key: "logPathWarnings", Value: "printPathWarnings"},
}
for _, alias := range aliases { for _, alias := range aliases {
if l.cfg.IsSet(alias.Key) { if l.cfg.IsSet(alias.Key) {

View file

@ -57,7 +57,7 @@ type AllProvider interface {
EnableMissingTranslationPlaceholders() bool EnableMissingTranslationPlaceholders() bool
TemplateMetrics() bool TemplateMetrics() bool
TemplateMetricsHints() bool TemplateMetricsHints() bool
LogI18nWarnings() bool PrintI18nWarnings() bool
CreateTitle(s string) string CreateTitle(s string) string
IgnoreFile(s string) bool IgnoreFile(s string) bool
NewContentEditor() string NewContentEditor() string

View file

@ -77,6 +77,8 @@ type HugoSites struct {
contentInit sync.Once contentInit sync.Once
content *pageMaps content *pageMaps
postRenderInit sync.Once
// Keeps track of bundle directories and symlinks to enable partial rebuilding. // Keeps track of bundle directories and symlinks to enable partial rebuilding.
ContentChanges *contentChangeMap ContentChanges *contentChangeMap

View file

@ -25,6 +25,7 @@ import (
"github.com/bep/logg" "github.com/bep/logg"
"github.com/gohugoio/hugo/langs" "github.com/gohugoio/hugo/langs"
"github.com/gohugoio/hugo/publisher" "github.com/gohugoio/hugo/publisher"
"github.com/gohugoio/hugo/tpl"
"github.com/gohugoio/hugo/hugofs" "github.com/gohugoio/hugo/hugofs"
@ -144,18 +145,8 @@ func (h *HugoSites) Build(config BuildCfg, events ...fsnotify.Event) error {
h.SendError(fmt.Errorf("render: %w", err)) h.SendError(fmt.Errorf("render: %w", err))
} }
if h.Configs.Base.LogPathWarnings { if err := h.postRenderOnce(); err != nil {
// We need to do this before any post processing, as that may write to the same files twice h.SendError(fmt.Errorf("postRenderOnce: %w", err))
// and create false positives.
hugofs.WalkFilesystems(h.Fs.PublishDir, func(fs afero.Fs) bool {
if dfs, ok := fs.(hugofs.DuplicatesReporter); ok {
dupes := dfs.ReportDuplicates()
if dupes != "" {
h.Log.Warnln("Duplicate target paths:", dupes)
}
}
return false
})
} }
if err := h.postProcess(infol); err != nil { if err := h.postProcess(infol); err != nil {
@ -329,6 +320,34 @@ func (h *HugoSites) render(l logg.LevelLogger, config *BuildCfg) error {
return nil return nil
} }
func (h *HugoSites) postRenderOnce() error {
h.postRenderInit.Do(func() {
conf := h.Configs.Base
if conf.PrintPathWarnings {
// We need to do this before any post processing, as that may write to the same files twice
// and create false positives.
hugofs.WalkFilesystems(h.Fs.PublishDir, func(fs afero.Fs) bool {
if dfs, ok := fs.(hugofs.DuplicatesReporter); ok {
dupes := dfs.ReportDuplicates()
if dupes != "" {
h.Log.Warnln("Duplicate target paths:", dupes)
}
}
return false
})
}
if conf.PrintUnusedTemplates {
unusedTemplates := h.Tmpl().(tpl.UnusedTemplatesProvider).UnusedTemplates()
for _, unusedTemplate := range unusedTemplates {
h.Log.Warnf("Template %s is unused, source file %s", unusedTemplate.Name(), unusedTemplate.Filename())
}
}
})
return nil
}
func (h *HugoSites) postProcess(l logg.LevelLogger) error { func (h *HugoSites) postProcess(l logg.LevelLogger) error {
defer h.timeTrack(l, time.Now(), "postProcess") defer h.timeTrack(l, time.Now(), "postProcess")

View file

@ -119,7 +119,7 @@ func (t Translator) initFuncs(bndl *i18n.Bundle) {
t.logger.Warnf("Failed to get translated string for language %q and ID %q: %s", currentLangStr, translationID, err) t.logger.Warnf("Failed to get translated string for language %q and ID %q: %s", currentLangStr, translationID, err)
} }
if t.cfg.LogI18nWarnings() { if t.cfg.PrintI18nWarnings() {
t.logger.Warnf("i18n|MISSING_TRANSLATION|%s|%s", currentLangStr, translationID) t.logger.Warnf("i18n|MISSING_TRANSLATION|%s|%s", currentLangStr, translationID)
} }