mirror of
https://github.com/gohugoio/hugo.git
synced 2024-11-21 20:46:30 -05:00
Handle transient errors in config loading etc.
As in: Get the Kubernetes site to build with the new Hugo version. Updates #10947
This commit is contained in:
parent
5251f015bf
commit
05542130ba
7 changed files with 96 additions and 5 deletions
|
@ -182,6 +182,7 @@ func (c Config) cloneForLang() *Config {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Config) CompileConfig() error {
|
func (c *Config) CompileConfig() error {
|
||||||
|
var transientErr error
|
||||||
s := c.Timeout
|
s := c.Timeout
|
||||||
if _, err := strconv.Atoi(s); err == nil {
|
if _, err := strconv.Atoi(s); err == nil {
|
||||||
// A number, assume seconds.
|
// A number, assume seconds.
|
||||||
|
@ -209,7 +210,8 @@ func (c *Config) CompileConfig() error {
|
||||||
}
|
}
|
||||||
f, found := outputFormats.GetByName(format)
|
f, found := outputFormats.GetByName(format)
|
||||||
if !found {
|
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)
|
kindOutputFormats[kind] = append(kindOutputFormats[kind], f)
|
||||||
}
|
}
|
||||||
|
@ -288,6 +290,7 @@ func (c *Config) CompileConfig() error {
|
||||||
IgnoreFile: ignoreFile,
|
IgnoreFile: ignoreFile,
|
||||||
MainSections: c.MainSections,
|
MainSections: c.MainSections,
|
||||||
Clock: clock,
|
Clock: clock,
|
||||||
|
transientErr: transientErr,
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, s := range allDecoderSetups {
|
for _, s := range allDecoderSetups {
|
||||||
|
@ -323,6 +326,11 @@ type ConfigCompiled struct {
|
||||||
IgnoreFile func(filename string) bool
|
IgnoreFile func(filename string) bool
|
||||||
MainSections []string
|
MainSections []string
|
||||||
Clock time.Time
|
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.
|
// This may be set after the config is compiled.
|
||||||
|
@ -565,6 +573,16 @@ type Configs struct {
|
||||||
configLangs []config.AllProvider
|
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 {
|
func (c *Configs) IsZero() bool {
|
||||||
// A config always has at least one language.
|
// A config always has at least one language.
|
||||||
return c == nil || len(c.Languages) == 0
|
return c == nil || len(c.Languages) == 0
|
||||||
|
|
|
@ -63,13 +63,19 @@ func LoadConfig(d ConfigSourceDescriptor) (*Configs, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to load modules: %w", err)
|
return nil, fmt.Errorf("failed to load modules: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(l.ModulesConfigFiles) > 0 {
|
if len(l.ModulesConfigFiles) > 0 {
|
||||||
// Config merged in from modules.
|
// Config merged in from modules.
|
||||||
// Re-read the config.
|
// Re-read the config.
|
||||||
configs, err = FromLoadConfigResult(d.Fs, res)
|
configs, err = FromLoadConfigResult(d.Fs, res)
|
||||||
if err != nil {
|
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
|
configs.Modules = moduleConfig.ActiveModules
|
||||||
|
|
|
@ -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) {
|
func TestReproCommentsIn10947(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
@ -768,7 +804,7 @@ title: "My Swedish Section"
|
||||||
---
|
---
|
||||||
-- layouts/index.html --
|
-- layouts/index.html --
|
||||||
{{ range $i, $e := (slice site .Site) }}
|
{{ 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 }}
|
{{ end }}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -273,6 +273,10 @@ func (s *Site) Language() *langs.Language {
|
||||||
return s.language
|
return s.language
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Site) Languages() langs.Languages {
|
||||||
|
return s.h.Configs.Languages
|
||||||
|
}
|
||||||
|
|
||||||
func (s *Site) isEnabled(kind string) bool {
|
func (s *Site) isEnabled(kind string) bool {
|
||||||
if kind == kindUnknown {
|
if kind == kindUnknown {
|
||||||
panic("Unknown kind")
|
panic("Unknown kind")
|
||||||
|
|
|
@ -431,7 +431,7 @@ func (s *Site) GoogleAnalytics() string {
|
||||||
return s.Config().Services.GoogleAnalytics.ID
|
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)
|
return resource.Param(s, nil, key)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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.
|
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
|
See https://gohugo.io/content-management/multilingual/#changes-in-hugo-01120
|
||||||
|
|
||||||
|
@ -111,6 +112,10 @@ func (l *Language) loadLocation(tzStr string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (l *Language) String() string {
|
||||||
|
return l.Lang
|
||||||
|
}
|
||||||
|
|
||||||
// Languages is a sortable list of languages.
|
// Languages is a sortable list of languages.
|
||||||
type Languages []*Language
|
type Languages []*Language
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,9 @@ type Site interface {
|
||||||
// Returns the Language configured for this Site.
|
// Returns the Language configured for this Site.
|
||||||
Language() *langs.Language
|
Language() *langs.Language
|
||||||
|
|
||||||
|
// Returns all the languages configured for all sites.
|
||||||
|
Languages() langs.Languages
|
||||||
|
|
||||||
GetPage(ref ...string) (Page, error)
|
GetPage(ref ...string) (Page, error)
|
||||||
|
|
||||||
// AllPages returns all pages for all languages.
|
// AllPages returns all pages for all languages.
|
||||||
|
@ -94,6 +97,9 @@ type Site interface {
|
||||||
// Returns the Params configured for this site.
|
// Returns the Params configured for this site.
|
||||||
Params() maps.Params
|
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.
|
// Returns a map of all the data inside /data.
|
||||||
Data() map[string]any
|
Data() map[string]any
|
||||||
|
|
||||||
|
@ -174,6 +180,10 @@ func (s *siteWrapper) Language() *langs.Language {
|
||||||
return s.s.Language()
|
return s.s.Language()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *siteWrapper) Languages() langs.Languages {
|
||||||
|
return s.s.Languages()
|
||||||
|
}
|
||||||
|
|
||||||
func (s *siteWrapper) AllPages() Pages {
|
func (s *siteWrapper) AllPages() Pages {
|
||||||
return s.s.AllPages()
|
return s.s.AllPages()
|
||||||
}
|
}
|
||||||
|
@ -254,6 +264,10 @@ func (s *siteWrapper) Params() maps.Params {
|
||||||
return s.s.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 {
|
func (s *siteWrapper) Data() map[string]any {
|
||||||
return s.s.Data()
|
return s.s.Data()
|
||||||
}
|
}
|
||||||
|
@ -334,6 +348,10 @@ func (t testSite) Current() Site {
|
||||||
return t
|
return t
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t testSite) Languages() langs.Languages {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (t testSite) GoogleAnalytics() string {
|
func (t testSite) GoogleAnalytics() string {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
@ -410,6 +428,10 @@ func (s testSite) IsMultiLingual() bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s testSite) Param(key any) (any, error) {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
// NewDummyHugoSite creates a new minimal test site.
|
// NewDummyHugoSite creates a new minimal test site.
|
||||||
func NewDummyHugoSite(cfg config.Provider) Site {
|
func NewDummyHugoSite(cfg config.Provider) Site {
|
||||||
return testSite{
|
return testSite{
|
||||||
|
|
Loading…
Reference in a new issue