diff --git a/cmd/build.go b/cmd/build.go index 85ab4c02..6028fe4b 100644 --- a/cmd/build.go +++ b/cmd/build.go @@ -117,7 +117,7 @@ func Build() error { if _, buildPathExistsErr := os.Stat(buildPath); buildPathExistsErr == nil { build.Log("Removing old '" + buildPath + "' build directory") if err = os.RemoveAll(buildPath); err != nil { - log.Fatal("\nCan't remove \"%v\" folder from previous build", err, buildDir) + log.Fatal("\nCan't remove \"%s\" folder from previous build: %s", buildDir, err) } } diff --git a/cmd/serve.go b/cmd/serve.go index 0e342745..7fb826bb 100644 --- a/cmd/serve.go +++ b/cmd/serve.go @@ -128,7 +128,6 @@ var serveCmd = &cobra.Command{ // Watch filesystem for changes. serve.Gowatch(buildDir, Build) - serve.Gowatch(buildDir, Build) if build.Doreload { // websockets diff --git a/cmd/serve/watcher.go b/cmd/serve/watcher.go index 67c906e4..fe91b573 100644 --- a/cmd/serve/watcher.go +++ b/cmd/serve/watcher.go @@ -6,7 +6,6 @@ import ( "log" "os" "path/filepath" - "sync/atomic" "github.com/plentico/plenti/cmd/build" @@ -80,8 +79,8 @@ func (w *watcher) watch(buildPath string, Build buildFunc) { // Set delay for batching events. ticker := time.NewTicker(300 * time.Millisecond) - // use a map for double firing events (happens when saving files in some text editors). - events := map[string]fsnotify.Event{} + // Batch events to prevent double firing (happens when saving files in some text editors). + events := make([]fsnotify.Event, 0) go func() { for { @@ -91,64 +90,26 @@ func (w *watcher) watch(buildPath string, Build buildFunc) { // Don't rebuild when build dir is added or deleted. if event.Name != "./"+buildPath { // Add current event to array for batching. - // don't really care but if we build with - events[event.Name] = event - + events = append(events, event) } + case <-ticker.C: // Checks on set interval if there are events. - // only build if there was an event. + // Display messages for each event in batch. + logEvents(events, w) + // Only build if there was an event. if len(events) > 0 { - // if locked i.e still building from last then this will do nothing. - // Can queue build with a mutex but gets messy quickly if you have 3-4 quick ctrl-s with one right after next. - if !atomic.CompareAndSwapUint32(&lock, 0, 1) { - err := Build() - // will be unlocked when we receive loaded message from ws in window.onload - // if any error leave as is. Shoud never send on channel if no connections or it will hang forever or until re load in browser.. - if err == nil && build.Doreload && len(connections) > 0 { - reloadC <- struct{}{} - - } else { - // not reloading so just unlock - atomic.StoreUint32(&lock, 0) - } - - } - - } - - // Display messages for each events in batch. - for _, event := range events { - if event.Op&fsnotify.Create == fsnotify.Create { - build.Log("File create detected: " + event.String()) - //common.CheckErr(w.Add(event.Name)) - // TODO: Checking error breaks server on Ubuntu. - w.Add(event.Name) - build.Log("Now watching " + event.Name) - } - if event.Op&fsnotify.Write == fsnotify.Write { - build.Log("File write detected: " + event.String()) - - } - if event.Op&fsnotify.Remove == fsnotify.Remove { - build.Log("File delete detected: " + event.String()) - } - if event.Op&fsnotify.Rename == fsnotify.Rename { - build.Log("File rename detected: " + event.String()) - } - - // optimised since 1.11 to reuse map. should lock this really and other access - for k := range events { - delete(events, k) - } - + Build() } + // Empty the batch array. + events = make([]fsnotify.Event, 0) // Watch for errors. case err := <-w.Errors: if err != nil { fmt.Printf("\nFile watching error: %s\n", err) } + } } }() @@ -171,3 +132,23 @@ func (w *watcher) watchDir(buildPath string) fs.WalkDirFunc { return nil } } + +func logEvents(events []fsnotify.Event, w *watcher) { + for _, event := range events { + if event.Op&fsnotify.Create == fsnotify.Create { + build.Log("File create detected: " + event.String()) + w.Add(event.Name) // Start watching new file for changes + build.Log("Now watching " + event.Name) + } + if event.Op&fsnotify.Write == fsnotify.Write { + build.Log("File write detected: " + event.String()) + + } + if event.Op&fsnotify.Remove == fsnotify.Remove { + build.Log("File delete detected: " + event.String()) + } + if event.Op&fsnotify.Rename == fsnotify.Rename { + build.Log("File rename detected: " + event.String()) + } + } +}