Implement configuration in a directory for modules

Fixes #8654
This commit is contained in:
Bjørn Erik Pedersen
2021-06-16 19:11:01 +02:00
parent 9096842b04
commit bb2aa08709
6 changed files with 201 additions and 120 deletions

View File

@@ -653,6 +653,9 @@ type ClientConfig struct {
// Absolute path to the project's themes dir.
ThemesDir string
// Eg. "production"
Environment string
CacheDir string // Module cache
ModuleConfig Config
}

View File

@@ -396,17 +396,16 @@ func (c *collector) applyMounts(moduleImport Import, mod *moduleAdapter) error {
func (c *collector) applyThemeConfig(tc *moduleAdapter) error {
var (
configFilename string
cfg config.Provider
themeCfg map[string]interface{}
hasConfig bool
hasConfigFile bool
err error
)
// Viper supports more, but this is the sub-set supported by Hugo.
for _, configFormats := range config.ValidConfigFileExtensions {
configFilename = filepath.Join(tc.Dir(), "config."+configFormats)
hasConfig, _ = afero.Exists(c.fs, configFilename)
if hasConfig {
hasConfigFile, _ = afero.Exists(c.fs, configFilename)
if hasConfigFile {
break
}
}
@@ -428,20 +427,38 @@ func (c *collector) applyThemeConfig(tc *moduleAdapter) error {
}
}
if hasConfig {
if hasConfigFile {
if configFilename != "" {
var err error
cfg, err = config.FromFile(c.fs, configFilename)
tc.cfg, err = config.FromFile(c.fs, configFilename)
if err != nil {
return errors.Wrapf(err, "failed to read module config for %q in %q", tc.Path(), configFilename)
}
}
tc.configFilename = configFilename
tc.cfg = cfg
tc.configFilenames = append(tc.configFilenames, configFilename)
}
config, err := decodeConfig(cfg, c.moduleConfig.replacementsMap)
// Also check for a config dir, which we overlay on top of the file configuration.
configDir := filepath.Join(tc.Dir(), "config")
dcfg, dirnames, err := config.LoadConfigFromDir(c.fs, configDir, c.ccfg.Environment)
if err != nil {
return err
}
if len(dirnames) > 0 {
tc.configFilenames = append(tc.configFilenames, dirnames...)
if hasConfigFile {
// Set will overwrite existing keys.
tc.cfg.Set("", dcfg.Get(""))
} else {
tc.cfg = dcfg
}
}
config, err := decodeConfig(tc.cfg, c.moduleConfig.replacementsMap)
if err != nil {
return err
}

View File

@@ -30,10 +30,10 @@ type Module interface {
// The decoded module config and mounts.
Config() Config
// Optional configuration filename (e.g. "/themes/mytheme/config.json").
// Optional configuration filenames (e.g. "/themes/mytheme/config.json").
// This will be added to the special configuration watch list when in
// server mode.
ConfigFilename() string
ConfigFilenames() []string
// Directory holding files for this module.
Dir() string
@@ -82,9 +82,9 @@ type moduleAdapter struct {
mounts []Mount
configFilename string
cfg config.Provider
config Config
configFilenames []string
cfg config.Provider
config Config
// Set if a Go module.
gomod *goModule
@@ -98,8 +98,8 @@ func (m *moduleAdapter) Config() Config {
return m.config
}
func (m *moduleAdapter) ConfigFilename() string {
return m.configFilename
func (m *moduleAdapter) ConfigFilenames() []string {
return m.configFilenames
}
func (m *moduleAdapter) Dir() string {