diff options
author | Bjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com> | 2016-11-10 20:55:52 +0100 |
---|---|---|
committer | Bjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com> | 2016-11-22 09:57:03 +0100 |
commit | 88972b0d5b62861128f101256027a52ab48eae86 (patch) | |
tree | bc2170773a3c6f6f0a1b62792174539fefdc864d /hugolib/hugo_sites_build.go | |
parent | 640b8bed21eabfd6e256814eab4b3ab3ad2e3354 (diff) |
node to page: Refactor the build process
To make it easier to follow and understand.
Both building and rebuilding now follow a four step flow:
1. Init
2. Process
3. Assemble
4. Render
And now there are only one Build method, used for both builds and rebuilds.
Updates #2297
Diffstat (limited to 'hugolib/hugo_sites_build.go')
-rw-r--r-- | hugolib/hugo_sites_build.go | 197 |
1 files changed, 197 insertions, 0 deletions
diff --git a/hugolib/hugo_sites_build.go b/hugolib/hugo_sites_build.go new file mode 100644 index 000000000..f5b6e6809 --- /dev/null +++ b/hugolib/hugo_sites_build.go @@ -0,0 +1,197 @@ +// Copyright 2016-present The Hugo Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package hugolib + +import ( + "time" + + "errors" + + "github.com/fsnotify/fsnotify" + "github.com/spf13/hugo/helpers" + jww "github.com/spf13/jwalterweatherman" +) + +// Build builds all sites. If filesystem events are provided, +// this is considered to be a potential partial rebuild. +func (h *HugoSites) Build(config BuildCfg, events ...fsnotify.Event) error { + t0 := time.Now() + + // Need a pointer as this may be modified. + conf := &config + + if conf.whatChanged == nil { + // Assume everything has changed + conf.whatChanged = &whatChanged{source: true, other: true} + } + + if len(events) > 0 { + // Rebuild + if err := h.initRebuild(conf); err != nil { + return err + } + } else { + if err := h.init(conf); err != nil { + return err + } + } + + if err := h.process(conf, events...); err != nil { + return err + } + + if err := h.assemble(conf); err != nil { + return err + } + + if err := h.render(conf); err != nil { + return err + } + + if config.PrintStats { + jww.FEEDBACK.Printf("total in %v ms\n", int(1000*time.Since(t0).Seconds())) + } + + return nil + +} + +// Build lifecycle methods below. +// The order listed matches the order of execution. + +func (h *HugoSites) init(config *BuildCfg) error { + + for _, s := range h.Sites { + if s.PageCollections == nil { + s.PageCollections = newPageCollections() + } + } + + if config.ResetState { + h.reset() + } + + if config.CreateSitesFromConfig { + if err := h.createSitesFromConfig(); err != nil { + return err + } + } + + h.runMode.Watching = config.Watching + + return nil +} + +func (h *HugoSites) initRebuild(config *BuildCfg) error { + if config.CreateSitesFromConfig { + return errors.New("Rebuild does not support 'CreateSitesFromConfig'.") + } + + if config.ResetState { + return errors.New("Rebuild does not support 'ResetState'.") + } + + if !config.Watching { + return errors.New("Rebuild called when not in watch mode") + } + + h.runMode.Watching = config.Watching + + for _, s := range h.Sites { + s.resetBuildState() + } + + helpers.InitLoggers() + + return nil +} + +func (h *HugoSites) process(config *BuildCfg, events ...fsnotify.Event) error { + // We should probably refactor the Site and pull up most of the logic from there to here, + // but that seems like a daunting task. + // So for now, if there are more than one site (language), + // we pre-process the first one, then configure all the sites based on that. + firstSite := h.Sites[0] + + if len(events) > 0 { + // This is a rebuild + changed, err := firstSite.reProcess(events) + config.whatChanged = &changed + return err + } + + return firstSite.process(*config) + +} + +func (h *HugoSites) assemble(config *BuildCfg) error { + // TODO(bep) np we could probably wait and do this in one go later + h.setupTranslations() + + if len(h.Sites) > 1 { + // The first is initialized during process; initialize the rest + for _, site := range h.Sites[1:] { + site.initializeSiteInfo() + } + } + + if config.whatChanged.source { + h.assembleGitInfo() + + for _, s := range h.Sites { + if err := s.buildSiteMeta(); err != nil { + return err + } + } + } + + if err := h.createMissingNodes(); err != nil { + return err + } + + for _, s := range h.Sites { + s.refreshPageCaches() + s.setupPrevNext() + } + + if err := h.assignMissingTranslations(); err != nil { + return err + } + + if err := h.preRender(*config, whatChanged{source: true, other: true}); err != nil { + return err + } + + return nil +} + +func (h *HugoSites) render(config *BuildCfg) error { + if !config.SkipRender { + for _, s := range h.Sites { + if err := s.render(); err != nil { + return err + } + + if config.PrintStats { + s.Stats() + } + } + + if err := h.renderCrossSitesArtifacts(); err != nil { + return err + } + } + + return nil +} |