shithub: hugo

Download patch

ref: fe901b81191860b60e6fcb29f8ebf87baef2ee79
parent: b39689393ccb8434d9a57658a64b77568c718e99
author: Bjørn Erik Pedersen <[email protected]>
date: Thu Jun 8 16:00:05 EDT 2017

hugolib, commands: Improve live-reload on directory structure changes

This issue is more visible now that we support nested sections.

This commit makes operations like pasting new content folders or deleting content folders during server watch just work.

Fixes #3570

--- a/commands/hugo.go
+++ b/commands/hugo.go
@@ -829,6 +829,11 @@
 							if err := watcher.Add(path); err != nil {
 								return err
 							}
+						} else if !c.isStatic(path) {
+							// Hugo's rebuilding logic is entirely file based. When you drop a new folder into
+							// /content on OSX, the above logic will handle future watching of those files,
+							// but the initial CREATE is lost.
+							dynamicEvents = append(dynamicEvents, fsnotify.Event{Name: path, Op: fsnotify.Create})
 						}
 						return nil
 					}
@@ -841,9 +846,7 @@
 						}
 					}
 
-					isstatic := strings.HasPrefix(ev.Name, c.PathSpec().GetStaticDirPath()) || (len(c.PathSpec().GetThemesDirPath()) > 0 && strings.HasPrefix(ev.Name, c.PathSpec().GetThemesDirPath()))
-
-					if isstatic {
+					if c.isStatic(ev.Name) {
 						staticEvents = append(staticEvents, ev)
 					} else {
 						dynamicEvents = append(dynamicEvents, ev)
@@ -997,6 +1000,10 @@
 
 	wg.Wait()
 	return nil
+}
+
+func (c *commandeer) isStatic(path string) bool {
+	return strings.HasPrefix(path, c.PathSpec().GetStaticDirPath()) || (len(c.PathSpec().GetThemesDirPath()) > 0 && strings.HasPrefix(path, c.PathSpec().GetThemesDirPath()))
 }
 
 // isThemeVsHugoVersionMismatch returns whether the current Hugo version is
--- a/hugolib/page.go
+++ b/hugolib/page.go
@@ -322,6 +322,18 @@
 	return -1
 }
 
+func (ps Pages) FindPagePosByFilePathPrefix(prefix string) int {
+	if prefix == "" {
+		return -1
+	}
+	for i, x := range ps {
+		if strings.HasPrefix(x.Source.Path(), prefix) {
+			return i
+		}
+	}
+	return -1
+}
+
 // FindPagePos Given a page, it will find the position in Pages
 // will return -1 if not found
 func (ps Pages) FindPagePos(page *Page) int {
--- a/hugolib/page_collections.go
+++ b/hugolib/page_collections.go
@@ -137,6 +137,18 @@
 	c.rawAllPages = append(c.rawAllPages, page)
 }
 
+// When we get a REMOVE event we're not always getting all the individual files,
+// so we need to remove all below a given path.
+func (c *PageCollections) removePageByPathPrefix(path string) {
+	for {
+		i := c.rawAllPages.FindPagePosByFilePathPrefix(path)
+		if i == -1 {
+			break
+		}
+		c.rawAllPages = append(c.rawAllPages[:i], c.rawAllPages[i+1:]...)
+	}
+}
+
 func (c *PageCollections) removePageByPath(path string) {
 	if i := c.rawAllPages.FindPagePosByFilePath(path); i >= 0 {
 		c.rawAllPages = append(c.rawAllPages[:i], c.rawAllPages[i+1:]...)
--- a/hugolib/site.go
+++ b/hugolib/site.go
@@ -667,11 +667,11 @@
 		seen[ev] = true
 
 		if s.isContentDirEvent(ev) {
-			logger.Println("Source changed", ev.Name)
+			logger.Println("Source changed", ev)
 			sourceChanged = append(sourceChanged, ev)
 		}
 		if s.isLayoutDirEvent(ev) {
-			logger.Println("Template changed", ev.Name)
+			logger.Println("Template changed", ev)
 			tmplChanged = append(tmplChanged, ev)
 
 			if strings.Contains(ev.Name, "shortcodes") {
@@ -682,11 +682,11 @@
 			}
 		}
 		if s.isDataDirEvent(ev) {
-			logger.Println("Data changed", ev.Name)
+			logger.Println("Data changed", ev)
 			dataChanged = append(dataChanged, ev)
 		}
 		if s.isI18nEvent(ev) {
-			logger.Println("i18n changed", ev.Name)
+			logger.Println("i18n changed", ev)
 			i18nChanged = append(dataChanged, ev)
 		}
 	}
@@ -761,7 +761,7 @@
 		if ev.Op&fsnotify.Remove == fsnotify.Remove {
 			//remove the file & a create will follow
 			path, _ := helpers.GetRelativePath(ev.Name, s.getContentDir(ev.Name))
-			s.removePageByPath(path)
+			s.removePageByPathPrefix(path)
 			continue
 		}