mirror of
https://github.com/Theodor-Springmann-Stiftung/musenalm.git
synced 2025-10-29 01:05:32 +00:00
hot reload, search refactor begin
This commit is contained in:
23
app/pb.go
23
app/pb.go
@@ -120,20 +120,21 @@ func (app *App) Serve() error {
|
||||
|
||||
// INFO: hot reloading for poor people
|
||||
if app.MAConfig.Debug {
|
||||
watcher, err := fsnotify.NewWatcher()
|
||||
watcher, err := EngineWatcher(engine)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Failed to create watcher: %w.", err)
|
||||
}
|
||||
defer watcher.Close()
|
||||
|
||||
go app.watchFN(watcher, engine)
|
||||
if err := watcher.Add(LAYOUT_DIR); err != nil {
|
||||
return fmt.Errorf("Failed to watch layout directory: %w.", err)
|
||||
app.PB.Logger().Error("Failed to create watcher, continuing without", "error", err)
|
||||
} else {
|
||||
watcher.AddRecursive(LAYOUT_DIR)
|
||||
watcher.AddRecursive(ROUTES_DIR)
|
||||
engine.Debug()
|
||||
rwatcher, err := RefreshWatcher(engine)
|
||||
if err != nil {
|
||||
app.PB.Logger().Error("Failed to create watcher, continuing without", "error", err)
|
||||
} else {
|
||||
rwatcher.Add("./views/assets")
|
||||
}
|
||||
}
|
||||
|
||||
if err := watcher.Add(ROUTES_DIR); err != nil {
|
||||
return fmt.Errorf("Failed to watch routes directory: %w.", err)
|
||||
}
|
||||
}
|
||||
|
||||
app.PB.OnBootstrap().BindFunc(func(e *core.BootstrapEvent) error {
|
||||
|
||||
136
app/watch.go
Normal file
136
app/watch.go
Normal file
@@ -0,0 +1,136 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"io/fs"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"github.com/Theodor-Springmann-Stiftung/musenalm/templating"
|
||||
"github.com/fsnotify/fsnotify"
|
||||
)
|
||||
|
||||
const (
|
||||
WATCHER_DEBOUNCE = 300 * time.Millisecond
|
||||
)
|
||||
|
||||
// INFO: this is hot reload for poor people
|
||||
type Watcher struct {
|
||||
*fsnotify.Watcher
|
||||
}
|
||||
|
||||
func RefreshWatcher(engine *templating.Engine) (*Watcher, error) {
|
||||
watcher := Watcher{}
|
||||
w, err := fsnotify.NewWatcher()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
watcher.Watcher = w
|
||||
|
||||
done := make(chan bool)
|
||||
|
||||
go func() {
|
||||
var reloadTimer *time.Timer
|
||||
|
||||
for {
|
||||
select {
|
||||
case event := <-watcher.Events:
|
||||
if event.Op&(fsnotify.Create|fsnotify.Write|fsnotify.Remove|fsnotify.Rename) != 0 {
|
||||
if reloadTimer != nil {
|
||||
reloadTimer.Stop()
|
||||
}
|
||||
reloadTimer = time.AfterFunc(WATCHER_DEBOUNCE, func() {
|
||||
log.Println("Changes detected, reloading templates...")
|
||||
engine.Refresh()
|
||||
})
|
||||
}
|
||||
|
||||
if event.Op&fsnotify.Create == fsnotify.Create {
|
||||
fi, statErr := os.Stat(event.Name)
|
||||
if statErr == nil && fi.IsDir() {
|
||||
_ = watcher.Add(event.Name)
|
||||
log.Printf("Now watching new directory: %s", event.Name)
|
||||
}
|
||||
}
|
||||
|
||||
case err := <-watcher.Errors:
|
||||
if err != nil {
|
||||
log.Printf("fsnotify error: %v\n", err)
|
||||
}
|
||||
|
||||
case <-done:
|
||||
watcher.Close()
|
||||
return
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
return &watcher, nil
|
||||
|
||||
}
|
||||
|
||||
func EngineWatcher(engine *templating.Engine) (*Watcher, error) {
|
||||
watcher := Watcher{}
|
||||
w, err := fsnotify.NewWatcher()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
watcher.Watcher = w
|
||||
|
||||
done := make(chan bool)
|
||||
|
||||
go func() {
|
||||
var reloadTimer *time.Timer
|
||||
|
||||
for {
|
||||
select {
|
||||
case event := <-watcher.Events:
|
||||
if event.Op&(fsnotify.Create|fsnotify.Write|fsnotify.Remove|fsnotify.Rename) != 0 {
|
||||
if reloadTimer != nil {
|
||||
reloadTimer.Stop()
|
||||
}
|
||||
reloadTimer = time.AfterFunc(WATCHER_DEBOUNCE, func() {
|
||||
log.Println("Changes detected, reloading templates...")
|
||||
engine.Reload()
|
||||
})
|
||||
}
|
||||
|
||||
if event.Op&fsnotify.Create == fsnotify.Create {
|
||||
fi, statErr := os.Stat(event.Name)
|
||||
if statErr == nil && fi.IsDir() {
|
||||
_ = watcher.Add(event.Name)
|
||||
log.Printf("Now watching new directory: %s", event.Name)
|
||||
}
|
||||
}
|
||||
|
||||
case err := <-watcher.Errors:
|
||||
if err != nil {
|
||||
log.Printf("fsnotify error: %v\n", err)
|
||||
}
|
||||
|
||||
case <-done:
|
||||
watcher.Close()
|
||||
return
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
return &watcher, nil
|
||||
}
|
||||
|
||||
func (w *Watcher) AddRecursive(root string) error {
|
||||
return filepath.WalkDir(root, func(path string, d fs.DirEntry, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if d.IsDir() {
|
||||
werr := w.Add(path)
|
||||
if werr != nil {
|
||||
return werr
|
||||
}
|
||||
log.Printf("Now watching directory: %s", path)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user