mirror of
https://github.com/gohugoio/hugo.git
synced 2024-11-21 20:46:30 -05:00
parent
fe63de3a83
commit
fa60a2fbc3
4 changed files with 91 additions and 33 deletions
|
@ -610,7 +610,7 @@ func (h *HugoSites) processPartial(ctx context.Context, l logg.LevelLogger, conf
|
||||||
|
|
||||||
// For a list of events for the different OSes, see the test output in https://github.com/bep/fsnotifyeventlister/.
|
// For a list of events for the different OSes, see the test output in https://github.com/bep/fsnotifyeventlister/.
|
||||||
events = h.fileEventsFilter(events)
|
events = h.fileEventsFilter(events)
|
||||||
events = h.fileEventsTranslate(events)
|
events = h.fileEventsTrim(events)
|
||||||
eventInfos := h.fileEventsApplyInfo(events)
|
eventInfos := h.fileEventsApplyInfo(events)
|
||||||
|
|
||||||
logger := h.Log
|
logger := h.Log
|
||||||
|
|
|
@ -10,6 +10,7 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
"runtime"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
@ -685,8 +686,17 @@ func (s *IntegrationTestBuilder) build(cfg BuildCfg) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We simulate the fsnotify events.
|
||||||
|
// See the test output in https://github.com/bep/fsnotifyeventlister for what events gets produced
|
||||||
|
// by the different OSes.
|
||||||
func (s *IntegrationTestBuilder) changeEvents() []fsnotify.Event {
|
func (s *IntegrationTestBuilder) changeEvents() []fsnotify.Event {
|
||||||
var events []fsnotify.Event
|
var (
|
||||||
|
events []fsnotify.Event
|
||||||
|
isLinux = runtime.GOOS == "linux"
|
||||||
|
isMacOs = runtime.GOOS == "darwin"
|
||||||
|
isWindows = runtime.GOOS == "windows"
|
||||||
|
)
|
||||||
|
|
||||||
for _, v := range s.removedFiles {
|
for _, v := range s.removedFiles {
|
||||||
events = append(events, fsnotify.Event{
|
events = append(events, fsnotify.Event{
|
||||||
Name: v,
|
Name: v,
|
||||||
|
@ -713,12 +723,32 @@ func (s *IntegrationTestBuilder) changeEvents() []fsnotify.Event {
|
||||||
Name: v,
|
Name: v,
|
||||||
Op: fsnotify.Write,
|
Op: fsnotify.Write,
|
||||||
})
|
})
|
||||||
|
if isLinux || isWindows {
|
||||||
|
// Duplicate write events, for some reason.
|
||||||
|
events = append(events, fsnotify.Event{
|
||||||
|
Name: v,
|
||||||
|
Op: fsnotify.Write,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if isMacOs {
|
||||||
|
events = append(events, fsnotify.Event{
|
||||||
|
Name: v,
|
||||||
|
Op: fsnotify.Chmod,
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for _, v := range s.createdFiles {
|
for _, v := range s.createdFiles {
|
||||||
events = append(events, fsnotify.Event{
|
events = append(events, fsnotify.Event{
|
||||||
Name: v,
|
Name: v,
|
||||||
Op: fsnotify.Create,
|
Op: fsnotify.Create,
|
||||||
})
|
})
|
||||||
|
if isLinux || isWindows {
|
||||||
|
events = append(events, fsnotify.Event{
|
||||||
|
Name: v,
|
||||||
|
Op: fsnotify.Write,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Shuffle events.
|
// Shuffle events.
|
||||||
|
|
|
@ -1553,3 +1553,27 @@ Single: {{ .Title }}|{{ .Content }}|
|
||||||
b.AssertRenderCountPage(1)
|
b.AssertRenderCountPage(1)
|
||||||
b.AssertRenderCountContent(1)
|
b.AssertRenderCountContent(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestRebuildEditSingleListChangeUbuntuIssue12362(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
files := `
|
||||||
|
-- hugo.toml --
|
||||||
|
disableKinds = ['rss','section','sitemap','taxonomy','term']
|
||||||
|
disableLiveReload = true
|
||||||
|
-- layouts/_default/list.html --
|
||||||
|
{{ range .Pages }}{{ .Title }}|{{ end }}
|
||||||
|
-- layouts/_default/single.html --
|
||||||
|
{{ .Title }}
|
||||||
|
-- content/p1.md --
|
||||||
|
---
|
||||||
|
title: p1
|
||||||
|
---
|
||||||
|
`
|
||||||
|
|
||||||
|
b := TestRunning(t, files)
|
||||||
|
b.AssertFileContent("public/index.html", "p1|")
|
||||||
|
|
||||||
|
b.AddFiles("content/p2.md", "---\ntitle: p2\n---").Build()
|
||||||
|
b.AssertFileContent("public/index.html", "p1|p2|") // this test passes, which doesn't match reality
|
||||||
|
}
|
||||||
|
|
|
@ -424,7 +424,35 @@ func (h *HugoSites) fileEventsFilter(events []fsnotify.Event) []fsnotify.Event {
|
||||||
events[n] = ev
|
events[n] = ev
|
||||||
n++
|
n++
|
||||||
}
|
}
|
||||||
return events[:n]
|
events = events[:n]
|
||||||
|
|
||||||
|
eventOrdinal := func(e fsnotify.Event) int {
|
||||||
|
// Pull the structural changes to the top.
|
||||||
|
if e.Op.Has(fsnotify.Create) {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
if e.Op.Has(fsnotify.Remove) {
|
||||||
|
return 2
|
||||||
|
}
|
||||||
|
if e.Op.Has(fsnotify.Rename) {
|
||||||
|
return 3
|
||||||
|
}
|
||||||
|
if e.Op.Has(fsnotify.Write) {
|
||||||
|
return 4
|
||||||
|
}
|
||||||
|
return 5
|
||||||
|
}
|
||||||
|
|
||||||
|
sort.Slice(events, func(i, j int) bool {
|
||||||
|
// First sort by event type.
|
||||||
|
if eventOrdinal(events[i]) != eventOrdinal(events[j]) {
|
||||||
|
return eventOrdinal(events[i]) < eventOrdinal(events[j])
|
||||||
|
}
|
||||||
|
// Then sort by name.
|
||||||
|
return events[i].Name < events[j].Name
|
||||||
|
})
|
||||||
|
|
||||||
|
return events
|
||||||
}
|
}
|
||||||
|
|
||||||
type fileEventInfo struct {
|
type fileEventInfo struct {
|
||||||
|
@ -494,41 +522,17 @@ func (h *HugoSites) fileEventsApplyInfo(events []fsnotify.Event) []fileEventInfo
|
||||||
return infos
|
return infos
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *HugoSites) fileEventsTranslate(events []fsnotify.Event) []fsnotify.Event {
|
func (h *HugoSites) fileEventsTrim(events []fsnotify.Event) []fsnotify.Event {
|
||||||
eventMap := make(map[string][]fsnotify.Event)
|
seen := make(map[string]bool)
|
||||||
|
|
||||||
// We often get a Remove etc. followed by a Create, a Create followed by a Write.
|
|
||||||
// Remove the superfluous events to make the update logic simpler.
|
|
||||||
for _, ev := range events {
|
|
||||||
eventMap[ev.Name] = append(eventMap[ev.Name], ev)
|
|
||||||
}
|
|
||||||
|
|
||||||
n := 0
|
n := 0
|
||||||
for _, ev := range events {
|
for _, ev := range events {
|
||||||
mapped := eventMap[ev.Name]
|
if seen[ev.Name] {
|
||||||
|
continue
|
||||||
// Keep one
|
|
||||||
found := false
|
|
||||||
var kept fsnotify.Event
|
|
||||||
for i, ev2 := range mapped {
|
|
||||||
if i == 0 {
|
|
||||||
kept = ev2
|
|
||||||
}
|
}
|
||||||
|
seen[ev.Name] = true
|
||||||
if ev2.Op&fsnotify.Write == fsnotify.Write {
|
events[n] = ev
|
||||||
kept = ev2
|
|
||||||
found = true
|
|
||||||
}
|
|
||||||
|
|
||||||
if !found && ev2.Op&fsnotify.Create == fsnotify.Create {
|
|
||||||
kept = ev2
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
events[n] = kept
|
|
||||||
n++
|
n++
|
||||||
}
|
}
|
||||||
|
|
||||||
return events
|
return events
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue