commands: Fix --panicOnWarning flag having no effect with module version warnings

The --panicOnWarning flag was not wired into the root command's logger,
so warnings emitted during config loading (such as module version
incompatibility warnings) would not trigger a panic.

Bind the panicOnWarning flag to the rootCommand struct and set the
PanicOnWarningHook on the logger created in createLogger.

Fixes #14524

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Bjørn Erik Pedersen
2026-02-16 00:09:17 +01:00
parent ab62320d6b
commit 3f9d0ad2b6
4 changed files with 31 additions and 1 deletions
+1
View File
@@ -7,6 +7,7 @@
* Never export symbols that's not needed outside of the package. * Never export symbols that's not needed outside of the package.
* Avoid global state at (almost) all cost. * Avoid global state at (almost) all cost.
* This is a project with a long history; assume that a similiar problem has been solved before, look hard for helper functions before creating new ones. * This is a project with a long history; assume that a similiar problem has been solved before, look hard for helper functions before creating new ones.
* In tests, use `qt` matchers (e.g. `b.Assert(err, qt.ErrorMatches, ...)`) instead of raw `if`/`t.Fatal` checks.
* Use `./check.sh ./somepackage/...` when iterating. * Use `./check.sh ./somepackage/...` when iterating.
* Use `./check.sh` when you're done. * Use `./check.sh` when you're done.
+8 -1
View File
@@ -131,6 +131,7 @@ type rootCommand struct {
gc bool gc bool
poll string poll string
forceSyncStatic bool forceSyncStatic bool
panicOnWarning bool
// Profile flags (for debugging of performance problems) // Profile flags (for debugging of performance problems)
cpuprofile string cpuprofile string
@@ -488,12 +489,18 @@ func (r *rootCommand) createLogger(running bool) (loggers.Logger, error) {
} }
} }
var logHookLast func(e *logg.Entry) error
if r.panicOnWarning {
logHookLast = loggers.PanicOnWarningHook
}
optsLogger := loggers.Options{ optsLogger := loggers.Options{
DistinctLevel: logg.LevelWarn, DistinctLevel: logg.LevelWarn,
Level: level, Level: level,
StdOut: r.StdOut, StdOut: r.StdOut,
StdErr: r.StdErr, StdErr: r.StdErr,
StoreErrors: running, StoreErrors: running,
HandlerPost: logHookLast,
} }
return loggers.New(optsLogger), nil return loggers.New(optsLogger), nil
@@ -591,7 +598,7 @@ func applyLocalFlagsBuild(cmd *cobra.Command, r *rootCommand) {
cmd.Flags().BoolVar(&r.gc, "gc", false, "enable to run some cleanup tasks (remove unused cache files) after the build") cmd.Flags().BoolVar(&r.gc, "gc", false, "enable to run some cleanup tasks (remove unused cache files) after the build")
cmd.Flags().StringVar(&r.poll, "poll", "", "set this to a poll interval, e.g --poll 700ms, to use a poll based approach to watch for file system changes") cmd.Flags().StringVar(&r.poll, "poll", "", "set this to a poll interval, e.g --poll 700ms, to use a poll based approach to watch for file system changes")
_ = cmd.RegisterFlagCompletionFunc("poll", cobra.NoFileCompletions) _ = cmd.RegisterFlagCompletionFunc("poll", cobra.NoFileCompletions)
cmd.Flags().Bool("panicOnWarning", false, "panic on first WARNING log") cmd.Flags().BoolVar(&r.panicOnWarning, "panicOnWarning", false, "panic on first WARNING log")
cmd.Flags().Bool("templateMetrics", false, "display metrics about template executions") cmd.Flags().Bool("templateMetrics", false, "display metrics about template executions")
cmd.Flags().Bool("templateMetricsHints", false, "calculate some improvement hints when combined with --templateMetrics") cmd.Flags().Bool("templateMetricsHints", false, "calculate some improvement hints when combined with --templateMetrics")
cmd.Flags().BoolVar(&r.forceSyncStatic, "forceSyncStatic", false, "copy all files when static is changed.") cmd.Flags().BoolVar(&r.forceSyncStatic, "forceSyncStatic", false, "copy all files when static is changed.")
+9
View File
@@ -879,12 +879,18 @@ func (s *IntegrationTestBuilder) initBuilder() error {
w = &s.logBuff w = &s.logBuff
} }
var logHookLast func(e *logg.Entry) error
if s.Cfg.PanicOnWarning {
logHookLast = loggers.PanicOnWarningHook
}
logger := loggers.New( logger := loggers.New(
loggers.Options{ loggers.Options{
StdOut: w, StdOut: w,
StdErr: w, StdErr: w,
Level: s.Cfg.LogLevel, Level: s.Cfg.LogLevel,
DistinctLevel: logg.LevelWarn, DistinctLevel: logg.LevelWarn,
HandlerPost: logHookLast,
}, },
) )
@@ -1143,6 +1149,9 @@ type IntegrationTestConfig struct {
// The log level to use. // The log level to use.
LogLevel logg.Level LogLevel logg.Level
// Whether to panic on warnings.
PanicOnWarning bool
// Whether it needs the real file system (e.g. for js.Build tests). // Whether it needs the real file system (e.g. for js.Build tests).
NeedsOsFS bool NeedsOsFS bool
@@ -0,0 +1,13 @@
! hugo --panicOnWarning
stderr 'is not compatible with this Hugo'
-- hugo.toml --
baseURL="https://example.org"
[module]
[module.hugoVersion]
min = "0.148.0"
max = "0.148.0"
-- layouts/all.html --
All.