ref: ca6ca4f4fc29906e491b5ac6b63fb65125c9c9e4
parent: bcc42c0549263681ef9eada21a9fc4eb2d8ff055
author: Steve Francia <[email protected]>
date: Mon Dec 21 19:10:01 EST 2015
Separate handling content, data and template changes Data & Templates reading independently Need to work on page source reading and other source files
--- a/commands/hugo.go
+++ b/commands/hugo.go
@@ -44,6 +44,8 @@
"gopkg.in/fsnotify.v1"
)
+var mainSite *hugolib.Site
+
// userError is an error used to signal different error situations in command handling.
type commandError struct {
s string
@@ -528,20 +530,34 @@
func buildSite(watching ...bool) (err error) {
startTime := time.Now()
- site := &hugolib.Site{}
+ if mainSite == nil {
+ mainSite = new(hugolib.Site)
+ }
if len(watching) > 0 && watching[0] {
- site.RunMode.Watching = true
+ mainSite.RunMode.Watching = true
}
- err = site.Build()
+ err = mainSite.Build()
if err != nil {
return err
}
- site.Stats()
+ mainSite.Stats()
jww.FEEDBACK.Printf("in %v ms\n", int(1000*time.Since(startTime).Seconds()))
return nil
}
+func rebuildSite(changes map[string]bool) error {
+ startTime := time.Now()
+ err := mainSite.ReBuild(changes)
+ if err != nil {
+ return err
+ }
+ mainSite.Stats()
+ jww.FEEDBACK.Printf("in %v ms\n", int(1000*time.Since(startTime).Seconds()))
+
+ return nil
+}
+
// NewWatcher creates a new watcher to watch filesystem events.
func NewWatcher(port int) error {
if runtime.GOOS == "darwin" {
@@ -574,6 +590,7 @@
staticChanged := false
dynamicChanged := false
staticFilesChanged := make(map[string]bool)
+ dynamicFilesChanged := make(map[string]bool)
for _, ev := range evs {
ext := filepath.Ext(ev.Name)
@@ -603,7 +620,11 @@
dynamicChanged = dynamicChanged || !isstatic
if isstatic {
- staticFilesChanged[ev.Name] = true
+ if staticPath, err := helpers.MakeStaticPathRelative(ev.Name); err == nil {
+ staticFilesChanged[staticPath] = true
+ }
+ } else {
+ dynamicFilesChanged[ev.Name] = true
}
// add new directory to watch list
@@ -680,7 +701,10 @@
fmt.Print("\nChange detected, rebuilding site\n")
const layout = "2006-01-02 15:04 -0700"
fmt.Println(time.Now().Format(layout))
- utils.CheckErr(buildSite(true))
+ //TODO here
+
+ // utils.CheckErr(buildSite(true))
+ rebuildSite(dynamicFilesChanged)
if !BuildWatch && !viper.GetBool("DisableLiveReload") {
// Will block forever trying to write to a channel that nobody is reading if livereload isn't initalized
--- a/hugolib/site.go
+++ b/hugolib/site.go
@@ -426,6 +426,78 @@
return nil
}
+func (s *Site) ReBuild(changed map[string]bool) error {
+ s.timerStep("initialize rebuild")
+ // First we need to determine what changed
+
+ sourceChanged := []string{}
+ tmplChanged := []string{}
+ dataChanged := []string{}
+ var err error
+
+ for f := range changed {
+ // Need to re-read source
+ if strings.HasPrefix(f, s.absContentDir()) {
+ fmt.Println("Source changed", f)
+ sourceChanged = append(sourceChanged, f)
+ }
+ if strings.HasPrefix(f, s.absLayoutDir()) || strings.HasPrefix(f, s.absThemeDir()) {
+ fmt.Println("Template changed", f)
+ tmplChanged = append(tmplChanged, f)
+ }
+ if strings.HasPrefix(f, s.absDataDir()) {
+ fmt.Println("Data changed", f)
+ dataChanged = append(dataChanged, f)
+ }
+ }
+
+
+ if len(tmplChanged) > 0 {
+ s.prepTemplates()
+ s.Tmpl.PrintErrors()
+ s.timerStep("template prep")
+ }
+
+ if len(dataChanged) > 0 {
+ s.ReadDataFromSourceFS()
+ }
+
+ if len (sourceChanged) > 0 {
+ if err = s.CreatePages(); err != nil {
+ return err
+ }
+ s.setupPrevNext()
+ if err = s.BuildSiteMeta(); err != nil {
+ return err
+ }
+ s.timerStep("build taxonomies")
+ }
+
+ if err = s.Render(); err != nil {
+ // Better reporting when the template is missing (commit 2bbecc7b)
+ jww.ERROR.Printf("Error rendering site: %s", err)
+
+ jww.ERROR.Printf("Available templates:")
+ var keys []string
+ for _, template := range s.Tmpl.Templates() {
+ if name := template.Name(); name != "" {
+ keys = append(keys, name)
+ }
+ }
+ sort.Strings(keys)
+ for _, k := range keys {
+ jww.ERROR.Printf("\t%s\n", k)
+ }
+
+ return nil
+ } else {
+ return err
+ }
+
+ return nil
+}
+
+
func (s *Site) Analyze() error {
if err := s.Process(); err != nil {
return err
@@ -508,17 +580,8 @@
}
}
-func (s *Site) Process() (err error) {
- s.timerStep("Go initialization")
- if err = s.initialize(); err != nil {
- return
- }
- s.prepTemplates()
- s.Tmpl.PrintErrors()
- s.timerStep("initialize & template prep")
-
+func (s *Site) ReadDataFromSourceFS() error {
dataSources := make([]source.Input, 0, 2)
-
dataSources = append(dataSources, &source.Filesystem{Base: s.absDataDir()})
// have to be last - duplicate keys in earlier entries will win
@@ -527,11 +590,24 @@
dataSources = append(dataSources, &source.Filesystem{Base: themeStaticDir})
}
- if err = s.loadData(dataSources); err != nil {
+ err = s.loadData(dataSources)
+ s.timerStep("load data")
+ return err
+}
+
+func (s *Site) Process() (err error) {
+ s.timerStep("Go initialization")
+ if err = s.initialize(); err != nil {
return
}
- s.timerStep("load data")
+ s.prepTemplates()
+ s.Tmpl.PrintErrors()
+ s.timerStep("initialize & template prep")
+ if err = s.ReadDataFromSourceFS(); err != nil {
+ return
+ }
+
if err = s.CreatePages(); err != nil {
return
}
@@ -864,7 +940,6 @@
}
func (s *Site) BuildSiteMeta() (err error) {
-
s.assembleMenus()
if len(s.Pages) == 0 {
@@ -929,6 +1004,7 @@
}
func (s *Site) assembleMenus() {
+ s.Menus = Menus{}
type twoD struct {
MenuName, EntryName string