From fe901b81191860b60e6fcb29f8ebf87baef2ee79 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Bj=C3=B8rn=20Erik=20Pedersen?= Date: Thu, 8 Jun 2017 20:00:05 +0200 Subject: [PATCH] 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 --- commands/hugo.go | 13 ++++++++++--- hugolib/page.go | 12 ++++++++++++ hugolib/page_collections.go | 12 ++++++++++++ hugolib/site.go | 10 +++++----- 4 files changed, 39 insertions(+), 8 deletions(-) diff --git a/commands/hugo.go b/commands/hugo.go index eaf75e32..9b827bc9 100644 --- a/commands/hugo.go +++ b/commands/hugo.go @@ -829,6 +829,11 @@ func (c *commandeer) newWatcher(port int) error { 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 @@ func (c *commandeer) newWatcher(port int) error { } } - 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) @@ -999,6 +1002,10 @@ func (c *commandeer) newWatcher(port int) error { 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 // less than the theme's min_version. func (c *commandeer) isThemeVsHugoVersionMismatch() (mismatch bool, requiredMinVersion string) { diff --git a/hugolib/page.go b/hugolib/page.go index cb9a28f2..42ed4e60 100644 --- a/hugolib/page.go +++ b/hugolib/page.go @@ -322,6 +322,18 @@ func (ps Pages) FindPagePosByFilePath(inPath string) int { 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 { diff --git a/hugolib/page_collections.go b/hugolib/page_collections.go index 4360f931..b3173884 100644 --- a/hugolib/page_collections.go +++ b/hugolib/page_collections.go @@ -137,6 +137,18 @@ func (c *PageCollections) addPage(page *Page) { 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:]...) diff --git a/hugolib/site.go b/hugolib/site.go index 929dd590..a172edd6 100644 --- a/hugolib/site.go +++ b/hugolib/site.go @@ -667,11 +667,11 @@ func (s *Site) reProcess(events []fsnotify.Event) (whatChanged, error) { 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 @@ func (s *Site) reProcess(events []fsnotify.Event) (whatChanged, error) { } } 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 @@ func (s *Site) reProcess(events []fsnotify.Event) (whatChanged, error) { 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 } -- 2.30.2