summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>2023-05-17 13:12:49 +0200
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>2023-05-17 22:13:29 +0200
commit05542130ba0205d3d8d14575b7e49ed42a855b9a (patch)
treebb94df8ba48b349bdcb18d254af51a38722bef13
parent5251f015bfff40b49f92f8855834d5682f925860 (diff)
Handle transient errors in config loading etc.
As in: Get the Kubernetes site to build with the new Hugo version. Updates #10947
-rw-r--r--config/allconfig/allconfig.go20
-rw-r--r--config/allconfig/load.go8
-rw-r--r--hugolib/config_test.go38
-rw-r--r--hugolib/site.go4
-rw-r--r--hugolib/site_new.go2
-rw-r--r--langs/language.go7
-rw-r--r--resources/page/site.go22
7 files changed, 96 insertions, 5 deletions
diff --git a/config/allconfig/allconfig.go b/config/allconfig/allconfig.go
index 4daae3ccb..6731b9003 100644
--- a/config/allconfig/allconfig.go
+++ b/config/allconfig/allconfig.go
@@ -182,6 +182,7 @@ func (c Config) cloneForLang() *Config {
}
func (c *Config) CompileConfig() error {
+ var transientErr error
s := c.Timeout
if _, err := strconv.Atoi(s); err == nil {
// A number, assume seconds.
@@ -209,7 +210,8 @@ func (c *Config) CompileConfig() error {
}
f, found := outputFormats.GetByName(format)
if !found {
- return fmt.Errorf("unknown output format %q for kind %q", format, kind)
+ transientErr = fmt.Errorf("unknown output format %q for kind %q", format, kind)
+ continue
}
kindOutputFormats[kind] = append(kindOutputFormats[kind], f)
}
@@ -288,6 +290,7 @@ func (c *Config) CompileConfig() error {
IgnoreFile: ignoreFile,
MainSections: c.MainSections,
Clock: clock,
+ transientErr: transientErr,
}
for _, s := range allDecoderSetups {
@@ -323,6 +326,11 @@ type ConfigCompiled struct {
IgnoreFile func(filename string) bool
MainSections []string
Clock time.Time
+
+ // This is set to the last transient error found during config compilation.
+ // With themes/modules we compule the configuration in multiple passes, and
+ // errors with missing output format definitions may resolve itself.
+ transientErr error
}
// This may be set after the config is compiled.
@@ -565,6 +573,16 @@ type Configs struct {
configLangs []config.AllProvider
}
+// transientErr returns the last transient error found during config compilation.
+func (c *Configs) transientErr() error {
+ for _, l := range c.LanguageConfigSlice {
+ if l.C.transientErr != nil {
+ return l.C.transientErr
+ }
+ }
+ return nil
+}
+
func (c *Configs) IsZero() bool {
// A config always has at least one language.
return c == nil || len(c.Languages) == 0
diff --git a/config/allconfig/load.go b/config/allconfig/load.go
index 9f27e867e..2d1a84423 100644
--- a/config/allconfig/load.go
+++ b/config/allconfig/load.go
@@ -63,13 +63,19 @@ func LoadConfig(d ConfigSourceDescriptor) (*Configs, error) {
if err != nil {
return nil, fmt.Errorf("failed to load modules: %w", err)
}
+
if len(l.ModulesConfigFiles) > 0 {
// Config merged in from modules.
// Re-read the config.
configs, err = FromLoadConfigResult(d.Fs, res)
if err != nil {
- return nil, fmt.Errorf("failed to create config: %w", err)
+ return nil, fmt.Errorf("failed to create config from modules config: %w", err)
+ }
+ if err := configs.transientErr(); err != nil {
+ return nil, fmt.Errorf("failed to create config from modules config: %w", err)
}
+ } else if err := configs.transientErr(); err != nil {
+ return nil, fmt.Errorf("failed to create config: %w", err)
}
configs.Modules = moduleConfig.ActiveModules
diff --git a/hugolib/config_test.go b/hugolib/config_test.go
index 93060134d..e27068da6 100644
--- a/hugolib/config_test.go
+++ b/hugolib/config_test.go
@@ -742,6 +742,42 @@ themeconfigdirparam: {{ site.Params.themeconfigdirparam }}
}
+func TestConfigOutputFormatDefinedInTheme(t *testing.T) {
+ t.Parallel()
+
+ files := `
+-- hugo.toml --
+theme = "mytheme"
+[outputFormats]
+[outputFormats.myotherformat]
+baseName = 'myotherindex'
+mediaType = 'text/html'
+[outputs]
+ home = ['myformat']
+-- themes/mytheme/hugo.toml --
+[outputFormats]
+[outputFormats.myformat]
+baseName = 'myindex'
+mediaType = 'text/html'
+-- layouts/index.html --
+Home.
+
+
+
+`
+
+ b, err := NewIntegrationTestBuilder(
+ IntegrationTestConfig{
+ T: t,
+ TxtarString: files,
+ },
+ ).BuildE()
+
+ b.Assert(err, qt.IsNil)
+ b.AssertFileContent("public/myindex.html", "Home.")
+
+}
+
func TestReproCommentsIn10947(t *testing.T) {
t.Parallel()
@@ -768,7 +804,7 @@ title: "My Swedish Section"
---
-- layouts/index.html --
{{ range $i, $e := (slice site .Site) }}
-{{ $i }}|AllPages: {{ len .AllPages }}|Sections: {{ if .Sections }}true{{ end }}| Author: {{ .Authors }}|BuildDrafts: {{ .BuildDrafts }}|IsMultiLingual: {{ .IsMultiLingual }}|Param: {{ .Language.Params.myparam }}|
+{{ $i }}|AllPages: {{ len .AllPages }}|Sections: {{ if .Sections }}true{{ end }}| Author: {{ .Authors }}|BuildDrafts: {{ .BuildDrafts }}|IsMultiLingual: {{ .IsMultiLingual }}|Param: {{ .Language.Params.myparam }}|Language string: {{ .Language }}|Languages: {{ .Languages }}
{{ end }}
diff --git a/hugolib/site.go b/hugolib/site.go
index b055cf690..301d66dac 100644
--- a/hugolib/site.go
+++ b/hugolib/site.go
@@ -273,6 +273,10 @@ func (s *Site) Language() *langs.Language {
return s.language
}
+func (s *Site) Languages() langs.Languages {
+ return s.h.Configs.Languages
+}
+
func (s *Site) isEnabled(kind string) bool {
if kind == kindUnknown {
panic("Unknown kind")
diff --git a/hugolib/site_new.go b/hugolib/site_new.go
index 2b959a8da..b0b34e457 100644
--- a/hugolib/site_new.go
+++ b/hugolib/site_new.go
@@ -431,7 +431,7 @@ func (s *Site) GoogleAnalytics() string {
return s.Config().Services.GoogleAnalytics.ID
}
-func (s *Site) Param(key string) (any, error) {
+func (s *Site) Param(key any) (any, error) {
return resource.Param(s, nil, key)
}
diff --git a/langs/language.go b/langs/language.go
index 5bf80274d..232331cae 100644
--- a/langs/language.go
+++ b/langs/language.go
@@ -87,7 +87,8 @@ var DeprecationFunc = func(item, alternative string, err bool) {}
const paramsDeprecationWarning = `.Language.Params is deprecated and will be removed in a future release. Use site.Params instead.
-Also, for all but custom parameters, you need to use the built in Hugo variables, e.g. site.Title, site.LanguageCode; site.Language.Params.Title will not work.
+- For all but custom parameters, you need to use the built in Hugo variables, e.g. site.Title, site.LanguageCode; site.Language.Params.Title will not work.
+- All custom parameters needs to be placed below params, e.g. [languages.en.params] in TOML.
See https://gohugo.io/content-management/multilingual/#changes-in-hugo-01120
@@ -111,6 +112,10 @@ func (l *Language) loadLocation(tzStr string) error {
return nil
}
+func (l *Language) String() string {
+ return l.Lang
+}
+
// Languages is a sortable list of languages.
type Languages []*Language
diff --git a/resources/page/site.go b/resources/page/site.go
index d36857bb1..899042391 100644
--- a/resources/page/site.go
+++ b/resources/page/site.go
@@ -35,6 +35,9 @@ type Site interface {
// Returns the Language configured for this Site.
Language() *langs.Language
+ // Returns all the languages configured for all sites.
+ Languages() langs.Languages
+
GetPage(ref ...string) (Page, error)
// AllPages returns all pages for all languages.
@@ -94,6 +97,9 @@ type Site interface {
// Returns the Params configured for this site.
Params() maps.Params
+ // Param is a convenience method to do lookups in Params.
+ Param(key any) (any, error)
+
// Returns a map of all the data inside /data.
Data() map[string]any
@@ -174,6 +180,10 @@ func (s *siteWrapper) Language() *langs.Language {
return s.s.Language()
}
+func (s *siteWrapper) Languages() langs.Languages {
+ return s.s.Languages()
+}
+
func (s *siteWrapper) AllPages() Pages {
return s.s.AllPages()
}
@@ -254,6 +264,10 @@ func (s *siteWrapper) Params() maps.Params {
return s.s.Params()
}
+func (s *siteWrapper) Param(key any) (any, error) {
+ return s.s.Param(key)
+}
+
func (s *siteWrapper) Data() map[string]any {
return s.s.Data()
}
@@ -334,6 +348,10 @@ func (t testSite) Current() Site {
return t
}
+func (t testSite) Languages() langs.Languages {
+ return nil
+}
+
func (t testSite) GoogleAnalytics() string {
return ""
}
@@ -410,6 +428,10 @@ func (s testSite) IsMultiLingual() bool {
return false
}
+func (s testSite) Param(key any) (any, error) {
+ return nil, nil
+}
+
// NewDummyHugoSite creates a new minimal test site.
func NewDummyHugoSite(cfg config.Provider) Site {
return testSite{