hugo

Unnamed repository; edit this file 'description' to name the repository.

git clone git://git.shimmy1996.com/hugo.git
commit 7d1f806ecb3621ae7b545a686d04de4568814055
parent 04b59599613a62d378bf3710ac0eb06c9543b96d
Author: Bjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Date:   Tue, 31 Aug 2021 17:02:51 +0200

commands: Don't fail on template errors on go mod graph etc.

Fixes #8942

Diffstat:
Mcommands/commandeer.go | 35+++++++++++++++++++++++++----------
Mcommands/commands.go | 2+-
Mcommands/config.go | 4++--
Mcommands/convert.go | 2+-
Mcommands/deploy.go | 2+-
Mcommands/hugo.go | 10+++++-----
Mcommands/list.go | 2+-
Mcommands/mod.go | 2+-
Mcommands/new.go | 2+-
Mcommands/new_theme.go | 2+-
Mcommands/server.go | 2+-
Mhugolib/hugo_sites.go | 7+++++--
12 files changed, 45 insertions(+), 27 deletions(-)
diff --git a/commands/commandeer.go b/commands/commandeer.go
@@ -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)
 	})
diff --git a/commands/commands.go b/commands/commands.go
@@ -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
diff --git a/commands/config.go b/commands/config.go
@@ -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
 	}
diff --git a/commands/convert.go b/commands/convert.go
@@ -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
 	}
diff --git a/commands/deploy.go b/commands/deploy.go
@@ -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
 			}
diff --git a/commands/hugo.go b/commands/hugo.go
@@ -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
diff --git a/commands/list.go b/commands/list.go
@@ -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
 	}
diff --git a/commands/mod.go b/commands/mod.go
@@ -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
 	}
diff --git a/commands/new.go b/commands/new.go
@@ -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
 	}
diff --git a/commands/new_theme.go b/commands/new_theme.go
@@ -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
 	}
diff --git a/commands/server.go b/commands/server.go
@@ -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
diff --git a/hugolib/hugo_sites.go b/hugolib/hugo_sites.go
@@ -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 {