]> git.maquefel.me Git - brevno-suite/hugo/commitdiff
Handle transient errors in config loading etc.
authorBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Wed, 17 May 2023 11:12:49 +0000 (13:12 +0200)
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Wed, 17 May 2023 20:13:29 +0000 (22:13 +0200)
As in: Get the Kubernetes site to build with the new Hugo version.

Updates #10947

config/allconfig/allconfig.go
config/allconfig/load.go
hugolib/config_test.go
hugolib/site.go
hugolib/site_new.go
langs/language.go
resources/page/site.go

index 4daae3ccb13815c695ee049cc9ffda2bc6d5dd41..6731b9003f6140d3b5c2dc831dae3697527cd115 100644 (file)
@@ -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
index 9f27e867e41728a25f6116b01370a651b01b6801..2d1a84423acee0ef17b285fecc7538ce4767503b 100644 (file)
@@ -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
index 93060134d362cc5463106c4351a96999dba90b44..e27068da6997ab279aebfe77a68c45497d10cf3e 100644 (file)
@@ -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 }}
 
 
index b055cf690ccc16c7ef34a25e7d530850d4cae868..301d66daca464a8a94e92c38f16a42708754fd76 100644 (file)
@@ -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")
index 2b959a8da2e825aa95c7ce6a203b7cdf6bc6a43b..b0b34e45782b83e8df4bced508f694a95d7cce90 100644 (file)
@@ -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)
 }
 
index 5bf80274d039ad0fc2c82ebd1ac6503259ab17a4..232331cae88be6e60dbd0c70468704218975ce04 100644 (file)
@@ -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
 
index d36857bb1b5c673d423833818258dc058d54bba6..899042391ad4069a91e7dca05d6a5f7bbe2b69d1 100644 (file)
@@ -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{