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/.
|
||||
events = h.fileEventsFilter(events)
|
||||
events = h.fileEventsTranslate(events)
|
||||
events = h.fileEventsTrim(events)
|
||||
eventInfos := h.fileEventsApplyInfo(events)
|
||||
|
||||
logger := h.Log
|
||||
|
|
|
@ -10,6 +10,7 @@ import (
|
|||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"runtime"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
|
@ -685,8 +686,17 @@ func (s *IntegrationTestBuilder) build(cfg BuildCfg) error {
|
|||
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 {
|
||||
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 {
|
||||
events = append(events, fsnotify.Event{
|
||||
Name: v,
|
||||
|
@ -713,12 +723,32 @@ func (s *IntegrationTestBuilder) changeEvents() []fsnotify.Event {
|
|||
Name: v,
|
||||
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 {
|
||||
events = append(events, fsnotify.Event{
|
||||
Name: v,
|
||||
Op: fsnotify.Create,
|
||||
})
|
||||
if isLinux || isWindows {
|
||||
events = append(events, fsnotify.Event{
|
||||
Name: v,
|
||||
Op: fsnotify.Write,
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Shuffle events.
|
||||
|
|
|
@ -1553,3 +1553,27 @@ Single: {{ .Title }}|{{ .Content }}|
|
|||
b.AssertRenderCountPage(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
|
||||
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 {
|
||||
|
@ -494,41 +522,17 @@ func (h *HugoSites) fileEventsApplyInfo(events []fsnotify.Event) []fileEventInfo
|
|||
return infos
|
||||
}
|
||||
|
||||
func (h *HugoSites) fileEventsTranslate(events []fsnotify.Event) []fsnotify.Event {
|
||||
eventMap := make(map[string][]fsnotify.Event)
|
||||
|
||||
// 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)
|
||||
}
|
||||
|
||||
func (h *HugoSites) fileEventsTrim(events []fsnotify.Event) []fsnotify.Event {
|
||||
seen := make(map[string]bool)
|
||||
n := 0
|
||||
for _, ev := range events {
|
||||
mapped := eventMap[ev.Name]
|
||||
|
||||
// Keep one
|
||||
found := false
|
||||
var kept fsnotify.Event
|
||||
for i, ev2 := range mapped {
|
||||
if i == 0 {
|
||||
kept = ev2
|
||||
if seen[ev.Name] {
|
||||
continue
|
||||
}
|
||||
|
||||
if ev2.Op&fsnotify.Write == fsnotify.Write {
|
||||
kept = ev2
|
||||
found = true
|
||||
}
|
||||
|
||||
if !found && ev2.Op&fsnotify.Create == fsnotify.Create {
|
||||
kept = ev2
|
||||
}
|
||||
}
|
||||
|
||||
events[n] = kept
|
||||
seen[ev.Name] = true
|
||||
events[n] = ev
|
||||
n++
|
||||
}
|
||||
|
||||
return events
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue