commands: Don't fail on template errors on go mod graph etc.
authorBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Tue, 31 Aug 2021 15:02:51 +0000 (17:02 +0200)
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Tue, 31 Aug 2021 20:16:12 +0000 (22:16 +0200)
Fixes #8942

12 files changed:
commands/commandeer.go
commands/commands.go
commands/config.go
commands/convert.go
commands/deploy.go
commands/hugo.go
commands/list.go
commands/mod.go
commands/new.go
commands/new_theme.go
commands/server.go
hugolib/hugo_sites.go

index b2a995ae6fd5524aa6ced966b4ce17d843f5a333..349838a7e199c39b9bf389655219741bbed0b03a 100644 (file)
@@ -61,6 +61,11 @@ type commandeer struct {
        logger       loggers.Logger
        serverConfig *config.Server
 
+       // Loading state
+       mustHaveConfigFile bool
+       failOnInitErr      bool
+       running            bool
+
        // Currently only set when in "fast render mode". But it seems to
        // be fast enough that we could maybe just add it for all server modes.
        changeDetector *fileChangeDetector
@@ -153,7 +158,7 @@ func (c *commandeer) initFs(fs *hugofs.Fs) error {
        return nil
 }
 
-func newCommandeer(mustHaveConfigFile, running bool, h *hugoBuilderCommon, f flagsToConfigHandler, cfgInit func(c *commandeer) error, subCmdVs ...*cobra.Command) (*commandeer, error) {
+func newCommandeer(mustHaveConfigFile, failOnInitErr, running bool, h *hugoBuilderCommon, f flagsToConfigHandler, cfgInit func(c *commandeer) error, subCmdVs ...*cobra.Command) (*commandeer, error) {
        var rebuildDebouncer func(f func())
        if running {
                // The time value used is tested with mass content replacements in a fairly big Hugo site.
@@ -175,11 +180,17 @@ func newCommandeer(mustHaveConfigFile, running bool, h *hugoBuilderCommon, f fla
                visitedURLs:         types.NewEvictingStringQueue(10),
                debounce:            rebuildDebouncer,
                fullRebuildSem:      semaphore.NewWeighted(1),
+
+               // Init state
+               mustHaveConfigFile: mustHaveConfigFile,
+               failOnInitErr:      failOnInitErr,
+               running:            running,
+
                // This will be replaced later, but we need something to log to before the configuration is read.
                logger: loggers.NewLogger(jww.LevelWarn, jww.LevelError, out, ioutil.Discard, running),
        }
 
-       return c, c.loadConfig(mustHaveConfigFile, running)
+       return c, c.loadConfig()
 }
 
 type fileChangeDetector struct {
@@ -244,7 +255,7 @@ func (f *fileChangeDetector) PrepareNew() {
        f.current = make(map[string]string)
 }
 
-func (c *commandeer) loadConfig(mustHaveConfigFile, running bool) error {
+func (c *commandeer) loadConfig() error {
        if c.DepsCfg == nil {
                c.DepsCfg = &deps.DepsCfg{}
        }
@@ -256,7 +267,7 @@ func (c *commandeer) loadConfig(mustHaveConfigFile, running bool) error {
 
        cfg := c.DepsCfg
        c.configured = false
-       cfg.Running = running
+       cfg.Running = c.running
 
        var dir string
        if c.h.source != "" {
@@ -270,7 +281,7 @@ func (c *commandeer) loadConfig(mustHaveConfigFile, running bool) error {
                sourceFs = c.DepsCfg.Fs.Source
        }
 
-       environment := c.h.getEnvironment(running)
+       environment := c.h.getEnvironment(c.running)
 
        doWithConfig := func(cfg config.Provider) error {
                if c.ftch != nil {
@@ -312,10 +323,10 @@ func (c *commandeer) loadConfig(mustHaveConfigFile, running bool) error {
                // We should improve the error handling here,
                // but with hugo mod init and similar there is a chicken and egg situation
                // with modules already configured in config.toml, so ignore those errors.
-               if mustHaveConfigFile || !moduleNotFoundRe.MatchString(err.Error()) {
+               if c.mustHaveConfigFile || !moduleNotFoundRe.MatchString(err.Error()) {
                        return err
                }
-       } else if mustHaveConfigFile && len(configFiles) == 0 {
+       } else if c.mustHaveConfigFile && len(configFiles) == 0 {
                return hugolib.ErrNoConfigFile
        }
 
@@ -327,7 +338,7 @@ func (c *commandeer) loadConfig(mustHaveConfigFile, running bool) error {
        }
 
        // Set some commonly used flags
-       c.doLiveReload = running && !c.Cfg.GetBool("disableLiveReload")
+       c.doLiveReload = c.running && !c.Cfg.GetBool("disableLiveReload")
        c.fastRenderMode = c.doLiveReload && !c.Cfg.GetBool("disableFastRender")
        c.showErrorInBrowser = c.doLiveReload && !c.Cfg.GetBool("disableBrowserError")
 
@@ -339,7 +350,7 @@ func (c *commandeer) loadConfig(mustHaveConfigFile, running bool) error {
                }
        }
 
-       logger, err := c.createLogger(config, running)
+       logger, err := c.createLogger(config)
        if err != nil {
                return err
        }
@@ -399,7 +410,11 @@ func (c *commandeer) loadConfig(mustHaveConfigFile, running bool) error {
 
                var h *hugolib.HugoSites
 
-               h, err = hugolib.NewHugoSites(*c.DepsCfg)
+               var createErr error
+               h, createErr = hugolib.NewHugoSites(*c.DepsCfg)
+               if h == nil || c.failOnInitErr {
+                       err = createErr
+               }
                c.hugoSites = h
                close(c.created)
        })
index c4d37ab3e966e21fea4f3c8b339d3343390f14a5..4153c3cdf2c136b3db12d5d37c5e01b72e1234d8 100644 (file)
@@ -165,7 +165,7 @@ Complete documentation is available at http://gohugo.io/.`,
                        // prevent cobra printing error so it can be handled here (before the timeTrack prints)
                        cmd.SilenceErrors = true
 
-                       c, err := initializeConfig(true, cc.buildWatch, &cc.hugoBuilderCommon, cc, cfgInit)
+                       c, err := initializeConfig(true, true, cc.buildWatch, &cc.hugoBuilderCommon, cc, cfgInit)
                        if err != nil {
                                cmd.PrintErrln("Error:", err.Error())
                                return err
index 87c8c90d60e3397d7ccee902d9ffd2e91fe7ea6f..6453319537c58332efd9a56d61f3af2aa4f4e218 100644 (file)
@@ -62,7 +62,7 @@ func (b *commandsBuilder) newConfigCmd() *configCmd {
 }
 
 func (c *configCmd) printMounts(cmd *cobra.Command, args []string) error {
-       cfg, err := initializeConfig(true, false, &c.hugoBuilderCommon, c, nil)
+       cfg, err := initializeConfig(true, false, false, &c.hugoBuilderCommon, c, nil)
        if err != nil {
                return err
        }
@@ -78,7 +78,7 @@ func (c *configCmd) printMounts(cmd *cobra.Command, args []string) error {
 }
 
 func (c *configCmd) printConfig(cmd *cobra.Command, args []string) error {
-       cfg, err := initializeConfig(true, false, &c.hugoBuilderCommon, c, nil)
+       cfg, err := initializeConfig(true, false, false, &c.hugoBuilderCommon, c, nil)
        if err != nil {
                return err
        }
index 3047add0ba3d87d9cb345c8584e08ca213eec82c..e2bd4307fad1c80c9200af73e107bf2c3c193345 100644 (file)
@@ -102,7 +102,7 @@ func (cc *convertCmd) convertContents(format metadecoders.Format) error {
                return newUserError("Unsafe operation not allowed, use --unsafe or set a different output path")
        }
 
-       c, err := initializeConfig(true, false, &cc.hugoBuilderCommon, cc, nil)
+       c, err := initializeConfig(true, false, false, &cc.hugoBuilderCommon, cc, nil)
        if err != nil {
                return err
        }
index 2e155760931bcbfeb7fbb0837b5986127e19d406..2b6d91246ff015ea30f518853264dd0e33c7c20c 100644 (file)
@@ -60,7 +60,7 @@ documentation.
                                c.Set("maxDeletes", cc.maxDeletes)
                                return nil
                        }
-                       comm, err := initializeConfig(true, false, &cc.hugoBuilderCommon, cc, cfgInit)
+                       comm, err := initializeConfig(true, true, false, &cc.hugoBuilderCommon, cc, cfgInit)
                        if err != nil {
                                return err
                        }
index 2b53d5cd6879f9bff8d2a928d6e01d1a52f00aa8..4fd20a0f48bee848ad355d9e87f3a523cbc268e2 100644 (file)
@@ -116,11 +116,11 @@ func Execute(args []string) Response {
 }
 
 // InitializeConfig initializes a config file with sensible default configuration flags.
-func initializeConfig(mustHaveConfigFile, running bool,
+func initializeConfig(mustHaveConfigFile, failOnInitErr, running bool,
        h *hugoBuilderCommon,
        f flagsToConfigHandler,
        cfgInit func(c *commandeer) error) (*commandeer, error) {
-       c, err := newCommandeer(mustHaveConfigFile, running, h, f, cfgInit)
+       c, err := newCommandeer(mustHaveConfigFile, failOnInitErr, running, h, f, cfgInit)
        if err != nil {
                return nil, err
        }
@@ -128,7 +128,7 @@ func initializeConfig(mustHaveConfigFile, running bool,
        return c, nil
 }
 
-func (c *commandeer) createLogger(cfg config.Provider, running bool) (loggers.Logger, error) {
+func (c *commandeer) createLogger(cfg config.Provider) (loggers.Logger, error) {
        var (
                logHandle       = ioutil.Discard
                logThreshold    = jww.LevelWarn
@@ -172,7 +172,7 @@ func (c *commandeer) createLogger(cfg config.Provider, running bool) (loggers.Lo
        loggers.InitGlobalLogger(stdoutThreshold, logThreshold, outHandle, logHandle)
        helpers.InitLoggers()
 
-       return loggers.NewLogger(stdoutThreshold, logThreshold, outHandle, logHandle, running), nil
+       return loggers.NewLogger(stdoutThreshold, logThreshold, outHandle, logHandle, c.running), nil
 }
 
 func initializeFlags(cmd *cobra.Command, cfg config.Provider) {
@@ -792,7 +792,7 @@ func (c *commandeer) fullRebuild(changeType string) {
                defer c.timeTrack(time.Now(), "Rebuilt")
 
                c.commandeerHugoState = newCommandeerHugoState()
-               err := c.loadConfig(true, true)
+               err := c.loadConfig()
                if err != nil {
                        // Set the processing on pause until the state is recovered.
                        c.paused = true
index 3c09cad25716f4b220afe1ad805255a878e3642c..d62672f61db335685fae6bae8e2b8f9c68595bfc 100644 (file)
@@ -40,7 +40,7 @@ func (lc *listCmd) buildSites(config map[string]interface{}) (*hugolib.HugoSites
                return nil
        }
 
-       c, err := initializeConfig(true, false, &lc.hugoBuilderCommon, lc, cfgInit)
+       c, err := initializeConfig(true, true, false, &lc.hugoBuilderCommon, lc, cfgInit)
        if err != nil {
                return nil, err
        }
index c6870e1d2a59fe702286cedea630957c703aa2b4..0f8239a4c6ac8867b2d44c4e9cf384a9ecfe842c 100644 (file)
@@ -284,7 +284,7 @@ func (c *modCmd) withHugo(f func(*hugolib.HugoSites) error) error {
 }
 
 func (c *modCmd) initConfig(failOnNoConfig bool) (*commandeer, error) {
-       com, err := initializeConfig(failOnNoConfig, false, &c.hugoBuilderCommon, c, nil)
+       com, err := initializeConfig(failOnNoConfig, false, false, &c.hugoBuilderCommon, c, nil)
        if err != nil {
                return nil, err
        }
index 44e2a7e407e2b4ee363dedad531249ad22d59166..7affd3547237bb847535f54e9843be33ae9882de 100644 (file)
@@ -71,7 +71,7 @@ func (n *newCmd) newContent(cmd *cobra.Command, args []string) error {
                return nil
        }
 
-       c, err := initializeConfig(true, false, &n.hugoBuilderCommon, n, cfgInit)
+       c, err := initializeConfig(true, true, false, &n.hugoBuilderCommon, n, cfgInit)
        if err != nil {
                return err
        }
index 965c2ca5f2832802164b6311b7466eb734efce04..9b1a4786c41f0da6b9e60456526bd849eecc49dc 100644 (file)
@@ -52,7 +52,7 @@ as you see fit.`,
 
 // newTheme creates a new Hugo theme template
 func (n *newThemeCmd) newTheme(cmd *cobra.Command, args []string) error {
-       c, err := initializeConfig(false, false, &n.hugoBuilderCommon, n, nil)
+       c, err := initializeConfig(false, false, false, &n.hugoBuilderCommon, n, nil)
        if err != nil {
                return err
        }
index 09cf43b249380d7fc63487ada85224e97cbbec8a..7d9462b36554f8891c74a1d708f01815f0140d99 100644 (file)
@@ -239,7 +239,7 @@ func (sc *serverCmd) server(cmd *cobra.Command, args []string) error {
        // silence errors in cobra so we can handle them here
        cmd.SilenceErrors = true
 
-       c, err := initializeConfig(true, true, &sc.hugoBuilderCommon, sc, cfgInit)
+       c, err := initializeConfig(true, true, true, &sc.hugoBuilderCommon, sc, cfgInit)
        if err != nil {
                cmd.PrintErrln("Error:", err.Error())
                return err
index a289556ca00ea365062589fcb7a6bcf711edb26c..27c490cc0ccdf72199dc03d5124bd116724af89d 100644 (file)
@@ -299,6 +299,9 @@ func newHugoSites(cfg deps.DepsCfg, sites ...*Site) (*HugoSites, error) {
                return nil, errors.New("Cannot provide Language in Cfg when sites are provided")
        }
 
+       // Return error at the end. Make the caller decide if it's fatal or not.
+       var initErr error
+
        langConfig, err := newMultiLingualFromSites(cfg.Cfg, sites...)
        if err != nil {
                return nil, errors.Wrap(err, "failed to create language config")
@@ -376,7 +379,7 @@ func newHugoSites(cfg deps.DepsCfg, sites ...*Site) (*HugoSites, error) {
 
        var l configLoader
        if err := l.applyDeps(cfg, sites...); err != nil {
-               return nil, errors.Wrap(err, "add site dependencies")
+               initErr = errors.Wrap(err, "add site dependencies")
        }
 
        h.Deps = sites[0].Deps
@@ -393,7 +396,7 @@ func newHugoSites(cfg deps.DepsCfg, sites ...*Site) (*HugoSites, error) {
                h.ContentChanges = contentChangeTracker
        }
 
-       return h, nil
+       return h, initErr
 }
 
 func (h *HugoSites) loadGitInfo() error {