]> git.maquefel.me Git - brevno-suite/hugo/commitdiff
commands: Ignore "module does not exist" errors in hugo mod init
authorBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Thu, 19 Sep 2024 08:53:39 +0000 (10:53 +0200)
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Thu, 19 Sep 2024 10:26:04 +0000 (12:26 +0200)
Closes #11458

commands/commandeer.go
commands/config.go
commands/hugobuilder.go
commands/mod.go
commands/new.go
config/allconfig/allconfig.go
config/allconfig/load.go
modules/client.go
modules/collect.go
testscripts/commands/mod_init.txt [new file with mode: 0644]

index f18a95bb997fc3d29160ea53f58dc1129e44f00a..e8cde2114f38cdf9b763e99f1a6b57f880487f24 100644 (file)
@@ -88,6 +88,11 @@ type commonConfig struct {
        fs      *hugofs.Fs
 }
 
+type configKey struct {
+       counter                    int32
+       ignoreModulesDoesNotExists bool
+}
+
 // This is the root command.
 type rootCommand struct {
        Printf  func(format string, v ...interface{})
@@ -101,8 +106,8 @@ type rootCommand struct {
 
        // Some, but not all commands need access to these.
        // Some needs more than one, so keep them in a small cache.
-       commonConfigs *lazycache.Cache[int32, *commonConfig]
-       hugoSites     *lazycache.Cache[int32, *hugolib.HugoSites]
+       commonConfigs *lazycache.Cache[configKey, *commonConfig]
+       hugoSites     *lazycache.Cache[configKey, *hugolib.HugoSites]
 
        // changesFromBuild received from Hugo in watch mode.
        changesFromBuild chan []identity.Identity
@@ -160,17 +165,18 @@ func (r *rootCommand) Commands() []simplecobra.Commander {
        return r.commands
 }
 
-func (r *rootCommand) ConfigFromConfig(key int32, oldConf *commonConfig) (*commonConfig, error) {
-       cc, _, err := r.commonConfigs.GetOrCreate(key, func(key int32) (*commonConfig, error) {
+func (r *rootCommand) ConfigFromConfig(key configKey, oldConf *commonConfig) (*commonConfig, error) {
+       cc, _, err := r.commonConfigs.GetOrCreate(key, func(key configKey) (*commonConfig, error) {
                fs := oldConf.fs
                configs, err := allconfig.LoadConfig(
                        allconfig.ConfigSourceDescriptor{
-                               Flags:       oldConf.cfg,
-                               Fs:          fs.Source,
-                               Filename:    r.cfgFile,
-                               ConfigDir:   r.cfgDir,
-                               Logger:      r.logger,
-                               Environment: r.environment,
+                               Flags:                    oldConf.cfg,
+                               Fs:                       fs.Source,
+                               Filename:                 r.cfgFile,
+                               ConfigDir:                r.cfgDir,
+                               Logger:                   r.logger,
+                               Environment:              r.environment,
+                               IgnoreModuleDoesNotExist: key.ignoreModulesDoesNotExists,
                        },
                )
                if err != nil {
@@ -193,11 +199,11 @@ func (r *rootCommand) ConfigFromConfig(key int32, oldConf *commonConfig) (*commo
        return cc, err
 }
 
-func (r *rootCommand) ConfigFromProvider(key int32, cfg config.Provider) (*commonConfig, error) {
+func (r *rootCommand) ConfigFromProvider(key configKey, cfg config.Provider) (*commonConfig, error) {
        if cfg == nil {
                panic("cfg must be set")
        }
-       cc, _, err := r.commonConfigs.GetOrCreate(key, func(key int32) (*commonConfig, error) {
+       cc, _, err := r.commonConfigs.GetOrCreate(key, func(key configKey) (*commonConfig, error) {
                var dir string
                if r.source != "" {
                        dir, _ = filepath.Abs(r.source)
@@ -220,12 +226,13 @@ func (r *rootCommand) ConfigFromProvider(key int32, cfg config.Provider) (*commo
                // Load the config first to allow publishDir to be configured in config file.
                configs, err := allconfig.LoadConfig(
                        allconfig.ConfigSourceDescriptor{
-                               Flags:       cfg,
-                               Fs:          hugofs.Os,
-                               Filename:    r.cfgFile,
-                               ConfigDir:   r.cfgDir,
-                               Environment: r.environment,
-                               Logger:      r.logger,
+                               Flags:                    cfg,
+                               Fs:                       hugofs.Os,
+                               Filename:                 r.cfgFile,
+                               ConfigDir:                r.cfgDir,
+                               Environment:              r.environment,
+                               Logger:                   r.logger,
+                               IgnoreModuleDoesNotExist: key.ignoreModulesDoesNotExists,
                        },
                )
                if err != nil {
@@ -307,7 +314,8 @@ func (r *rootCommand) ConfigFromProvider(key int32, cfg config.Provider) (*commo
 }
 
 func (r *rootCommand) HugFromConfig(conf *commonConfig) (*hugolib.HugoSites, error) {
-       h, _, err := r.hugoSites.GetOrCreate(r.configVersionID.Load(), func(key int32) (*hugolib.HugoSites, error) {
+       k := configKey{counter: r.configVersionID.Load()}
+       h, _, err := r.hugoSites.GetOrCreate(k, func(key configKey) (*hugolib.HugoSites, error) {
                depsCfg := r.newDepsConfig(conf)
                return hugolib.NewHugoSites(depsCfg)
        })
@@ -315,7 +323,12 @@ func (r *rootCommand) HugFromConfig(conf *commonConfig) (*hugolib.HugoSites, err
 }
 
 func (r *rootCommand) Hugo(cfg config.Provider) (*hugolib.HugoSites, error) {
-       h, _, err := r.hugoSites.GetOrCreate(r.configVersionID.Load(), func(key int32) (*hugolib.HugoSites, error) {
+       return r.getOrCreateHugo(cfg, false)
+}
+
+func (r *rootCommand) getOrCreateHugo(cfg config.Provider, ignoreModuleDoesNotExist bool) (*hugolib.HugoSites, error) {
+       k := configKey{counter: r.configVersionID.Load(), ignoreModulesDoesNotExists: ignoreModuleDoesNotExist}
+       h, _, err := r.hugoSites.GetOrCreate(k, func(key configKey) (*hugolib.HugoSites, error) {
                conf, err := r.ConfigFromProvider(key, cfg)
                if err != nil {
                        return nil, err
@@ -418,11 +431,11 @@ func (r *rootCommand) PreRun(cd, runner *simplecobra.Commandeer) error {
 
        r.changesFromBuild = make(chan []identity.Identity, 10)
 
-       r.commonConfigs = lazycache.New(lazycache.Options[int32, *commonConfig]{MaxEntries: 5})
+       r.commonConfigs = lazycache.New(lazycache.Options[configKey, *commonConfig]{MaxEntries: 5})
        // We don't want to keep stale HugoSites in memory longer than needed.
-       r.hugoSites = lazycache.New(lazycache.Options[int32, *hugolib.HugoSites]{
+       r.hugoSites = lazycache.New(lazycache.Options[configKey, *hugolib.HugoSites]{
                MaxEntries: 1,
-               OnEvict: func(key int32, value *hugolib.HugoSites) {
+               OnEvict: func(key configKey, value *hugolib.HugoSites) {
                        value.Close()
                        runtime.GC()
                },
index adf6bbe2bbd94738a1d15dd6c89c8a147c4d6799..c3d08ae22d4abd15459537b14b655828f692d4f8 100644 (file)
@@ -58,7 +58,7 @@ func (c *configCommand) Name() string {
 }
 
 func (c *configCommand) Run(ctx context.Context, cd *simplecobra.Commandeer, args []string) error {
-       conf, err := c.r.ConfigFromProvider(c.r.configVersionID.Load(), flagsToCfg(cd, nil))
+       conf, err := c.r.ConfigFromProvider(configKey{counter: c.r.configVersionID.Load()}, flagsToCfg(cd, nil))
        if err != nil {
                return err
        }
@@ -209,7 +209,7 @@ func (c *configMountsCommand) Name() string {
 
 func (c *configMountsCommand) Run(ctx context.Context, cd *simplecobra.Commandeer, args []string) error {
        r := c.configCmd.r
-       conf, err := r.ConfigFromProvider(r.configVersionID.Load(), flagsToCfg(cd, nil))
+       conf, err := r.ConfigFromProvider(configKey{counter: c.r.configVersionID.Load()}, flagsToCfg(cd, nil))
        if err != nil {
                return err
        }
index d15d47326ddcd43cb49d3661ff8648e0e16c0da1..42bf68a3726a36a7779032cc6f5f5d247e3d822c 100644 (file)
@@ -1047,7 +1047,7 @@ func (c *hugoBuilder) loadConfig(cd *simplecobra.Commandeer, running bool) error
                "fastRenderMode": c.fastRenderMode,
        })
 
-       conf, err := c.r.ConfigFromProvider(c.r.configVersionID.Load(), flagsToCfg(cd, cfg))
+       conf, err := c.r.ConfigFromProvider(configKey{counter: c.r.configVersionID.Load()}, flagsToCfg(cd, cfg))
        if err != nil {
                return err
        }
@@ -1116,7 +1116,7 @@ func (c *hugoBuilder) reloadConfig() error {
 
        if err := c.withConfE(func(conf *commonConfig) error {
                oldConf := conf
-               newConf, err := c.r.ConfigFromConfig(c.r.configVersionID.Load(), conf)
+               newConf, err := c.r.ConfigFromConfig(configKey{counter: c.r.configVersionID.Load()}, conf)
                if err != nil {
                        return err
                }
index 0fa83e5c0052189df838a0a71a30fefcaf4d1cbf..a9c8c459d00419c726be5274cdaf1b33927e2ff6 100644 (file)
@@ -94,7 +94,7 @@ so this may/will change in future versions of Hugo.
                                        applyLocalFlagsBuildConfig(cmd, r)
                                },
                                run: func(ctx context.Context, cd *simplecobra.Commandeer, r *rootCommand, args []string) error {
-                                       h, err := r.Hugo(flagsToCfg(cd, nil))
+                                       h, err := r.getOrCreateHugo(flagsToCfg(cd, nil), true)
                                        if err != nil {
                                                return err
                                        }
@@ -102,7 +102,11 @@ so this may/will change in future versions of Hugo.
                                        if len(args) >= 1 {
                                                initPath = args[0]
                                        }
-                                       return h.Configs.ModulesClient.Init(initPath)
+                                       c := h.Configs.ModulesClient
+                                       if err := c.Init(initPath); err != nil {
+                                               return err
+                                       }
+                                       return nil
                                },
                        },
                        &simpleCommand{
@@ -115,7 +119,7 @@ so this may/will change in future versions of Hugo.
                                        cmd.Flags().BoolVarP(&clean, "clean", "", false, "delete module cache for dependencies that fail verification")
                                },
                                run: func(ctx context.Context, cd *simplecobra.Commandeer, r *rootCommand, args []string) error {
-                                       conf, err := r.ConfigFromProvider(r.configVersionID.Load(), flagsToCfg(cd, nil))
+                                       conf, err := r.ConfigFromProvider(configKey{counter: r.configVersionID.Load()}, flagsToCfg(cd, nil))
                                        if err != nil {
                                                return err
                                        }
@@ -135,7 +139,7 @@ Note that for vendored modules, that is the version listed and not the one from
                                        cmd.Flags().BoolVarP(&clean, "clean", "", false, "delete module cache for dependencies that fail verification")
                                },
                                run: func(ctx context.Context, cd *simplecobra.Commandeer, r *rootCommand, args []string) error {
-                                       conf, err := r.ConfigFromProvider(r.configVersionID.Load(), flagsToCfg(cd, nil))
+                                       conf, err := r.ConfigFromProvider(configKey{counter: r.configVersionID.Load()}, flagsToCfg(cd, nil))
                                        if err != nil {
                                                return err
                                        }
@@ -271,7 +275,7 @@ Run "go help get" for more information. All flags available for "go get" is also
 
                                                                cfg := config.New()
                                                                cfg.Set("workingDir", dir)
-                                                               conf, err := r.ConfigFromProvider(r.configVersionID.Add(1), flagsToCfg(cd, cfg))
+                                                               conf, err := r.ConfigFromProvider(configKey{counter: r.configVersionID.Add(1)}, flagsToCfg(cd, cfg))
                                                                if err != nil {
                                                                        return err
                                                                }
@@ -284,7 +288,7 @@ Run "go help get" for more information. All flags available for "go get" is also
                                                })
                                                return nil
                                        } else {
-                                               conf, err := r.ConfigFromProvider(r.configVersionID.Load(), flagsToCfg(cd, nil))
+                                               conf, err := r.ConfigFromProvider(configKey{counter: r.configVersionID.Load()}, flagsToCfg(cd, nil))
                                                if err != nil {
                                                        return err
                                                }
@@ -313,7 +317,7 @@ func (c *modCommands) Name() string {
 }
 
 func (c *modCommands) Run(ctx context.Context, cd *simplecobra.Commandeer, args []string) error {
-       _, err := c.r.ConfigFromProvider(c.r.configVersionID.Load(), nil)
+       _, err := c.r.ConfigFromProvider(configKey{counter: c.r.configVersionID.Load()}, nil)
        if err != nil {
                return err
        }
index 4bad0059ff5218f2c56a2636e3d7bf8ff24a895e..f6bb09e0023f935790357c284333918da7cf67f1 100644 (file)
@@ -93,7 +93,7 @@ Use ` + "`hugo new [contentPath]`" + ` to create new content.`,
                                        cfg.Set("workingDir", createpath)
                                        cfg.Set("publishDir", "public")
 
-                                       conf, err := r.ConfigFromProvider(r.configVersionID.Load(), flagsToCfg(cd, cfg))
+                                       conf, err := r.ConfigFromProvider(configKey{counter: r.configVersionID.Load()}, flagsToCfg(cd, cfg))
                                        if err != nil {
                                                return err
                                        }
@@ -136,7 +136,7 @@ according to your needs.`,
                                        cfg := config.New()
                                        cfg.Set("publishDir", "public")
 
-                                       conf, err := r.ConfigFromProvider(r.configVersionID.Load(), flagsToCfg(cd, cfg))
+                                       conf, err := r.ConfigFromProvider(configKey{counter: r.configVersionID.Load()}, flagsToCfg(cd, cfg))
                                        if err != nil {
                                                return err
                                        }
index f6dfa7260fcdfd226f6c2f27e6a7538fcb0030dc..35517ece2db898d50f4c508552efb7b6f690a644 100644 (file)
@@ -809,7 +809,7 @@ func (c *Configs) Init() error {
        }
 
        if len(c.Modules) == 0 {
-               return errors.New("no modules loaded (ned at least the main module)")
+               return errors.New("no modules loaded (need at least the main module)")
        }
 
        // Apply default project mounts.
index 84419cb2ef5bdf3395c0316804e8d2fc457cbe4e..16e2019cfa95b2b7c6974ffe3fe50bfbe2ba792e 100644 (file)
@@ -64,7 +64,7 @@ func LoadConfig(d ConfigSourceDescriptor) (*Configs, error) {
                return nil, fmt.Errorf("failed to create config from result: %w", err)
        }
 
-       moduleConfig, modulesClient, err := l.loadModules(configs)
+       moduleConfig, modulesClient, err := l.loadModules(configs, d.IgnoreModuleDoesNotExist)
        if err != nil {
                return nil, fmt.Errorf("failed to load modules: %w", err)
        }
@@ -116,6 +116,9 @@ type ConfigSourceDescriptor struct {
 
        // Defaults to os.Environ if not set.
        Environ []string
+
+       // If set, this will be used to ignore the module does not exist error.
+       IgnoreModuleDoesNotExist bool
 }
 
 func (d ConfigSourceDescriptor) configFilenames() []string {
@@ -453,7 +456,7 @@ func (l *configLoader) loadConfigMain(d ConfigSourceDescriptor) (config.LoadConf
        return res, l.ModulesConfig, err
 }
 
-func (l *configLoader) loadModules(configs *Configs) (modules.ModulesConfig, *modules.Client, error) {
+func (l *configLoader) loadModules(configs *Configs, ignoreModuleDoesNotExist bool) (modules.ModulesConfig, *modules.Client, error) {
        bcfg := configs.LoadingInfo.BaseConfig
        conf := configs.Base
        workingDir := bcfg.WorkingDir
@@ -487,17 +490,18 @@ func (l *configLoader) loadModules(configs *Configs) (modules.ModulesConfig, *mo
        }
 
        modulesClient := modules.NewClient(modules.ClientConfig{
-               Fs:                 l.Fs,
-               Logger:             l.Logger,
-               Exec:               ex,
-               HookBeforeFinalize: hook,
-               WorkingDir:         workingDir,
-               ThemesDir:          themesDir,
-               PublishDir:         publishDir,
-               Environment:        l.Environment,
-               CacheDir:           conf.Caches.CacheDirModules(),
-               ModuleConfig:       conf.Module,
-               IgnoreVendor:       ignoreVendor,
+               Fs:                       l.Fs,
+               Logger:                   l.Logger,
+               Exec:                     ex,
+               HookBeforeFinalize:       hook,
+               WorkingDir:               workingDir,
+               ThemesDir:                themesDir,
+               PublishDir:               publishDir,
+               Environment:              l.Environment,
+               CacheDir:                 conf.Caches.CacheDirModules(),
+               ModuleConfig:             conf.Module,
+               IgnoreVendor:             ignoreVendor,
+               IgnoreModuleDoesNotExist: ignoreModuleDoesNotExist,
        })
 
        moduleConfig, err := modulesClient.Collect()
index dce40d2db9b35c0b7f457caf1250ea00ae394ef1..70b3ac4855d14ae53b7007d0764fd5307bc4272e 100644 (file)
@@ -742,6 +742,9 @@ type ClientConfig struct {
        // This can be nil.
        IgnoreVendor glob.Glob
 
+       // Ignore any module not found errors.
+       IgnoreModuleDoesNotExist bool
+
        // Absolute path to the project dir.
        WorkingDir string
 
index cfb6d9249423ff849b344defd5a4427bb3e81147..4eb12a1a6a8ae6fc225bb37f461d7336db823361 100644 (file)
@@ -699,6 +699,9 @@ func (c *collector) normalizeMounts(owner *moduleAdapter, mounts []Mount) ([]Mou
 }
 
 func (c *collector) wrapModuleNotFound(err error) error {
+       if c.Client.ccfg.IgnoreModuleDoesNotExist {
+               return nil
+       }
        err = fmt.Errorf(err.Error()+": %w", ErrNotExist)
        if c.GoModulesFilename == "" {
                return err
diff --git a/testscripts/commands/mod_init.txt b/testscripts/commands/mod_init.txt
new file mode 100644 (file)
index 0000000..c09e71a
--- /dev/null
@@ -0,0 +1,15 @@
+# Test the hugo init command.
+dostounix golden/go.mod.testsubmod
+
+hugo mod init testsubmod
+cmpenv go.mod $WORK/golden/go.mod.testsubmod
+
+-- hugo.toml --
+title = "Hugo Modules Test"
+[module]
+[[module.imports]]
+path="github.com/bep/empty-hugo-module"
+-- golden/go.mod.testsubmod --
+module testsubmod
+
+go ${GOVERSION}
\ No newline at end of file