func build(watches ...bool) { utils.CheckErr(copyStatic(), fmt.Sprintf("Error copying static files to %s", helpers.AbsPathify(viper.GetString("PublishDir")))) watch := false if len(watches) > 0 && watches[0] { watch = true } utils.StopOnErr(buildSite(BuildWatch || watch)) if BuildWatch { jww.FEEDBACK.Println("Watching for changes in", helpers.AbsPathify(viper.GetString("ContentDir"))) jww.FEEDBACK.Println("Press Ctrl+C to stop") utils.CheckErr(NewWatcher(0)) } }
//Execute adds all child commands to the root command HugoCmd and sets flags appropriately. func Execute() { AddCommands() utils.StopOnErr(HugoCmd.Execute()) }
// NewWatcher creates a new watcher to watch filesystem events. func NewWatcher(port int) error { if runtime.GOOS == "darwin" { tweakLimit() } watcher, err := watcher.New(1 * time.Second) var wg sync.WaitGroup if err != nil { fmt.Println(err) return err } defer watcher.Close() wg.Add(1) for _, d := range getDirList() { if d != "" { _ = watcher.Add(d) } } go func() { for { select { case evs := <-watcher.Events: jww.INFO.Println("File System Event:", evs) staticChanged := false dynamicChanged := false staticFilesChanged := make(map[string]bool) for _, ev := range evs { ext := filepath.Ext(ev.Name) istemp := strings.HasSuffix(ext, "~") || (ext == ".swp") || (ext == ".swx") || (ext == ".tmp") || strings.HasPrefix(ext, ".goutputstream") if istemp { continue } // renames are always followed with Create/Modify if ev.Op&fsnotify.Rename == fsnotify.Rename { continue } isstatic := strings.HasPrefix(ev.Name, helpers.GetStaticDirPath()) || (len(helpers.GetThemesDirPath()) > 0 && strings.HasPrefix(ev.Name, helpers.GetThemesDirPath())) staticChanged = staticChanged || isstatic dynamicChanged = dynamicChanged || !isstatic if isstatic { if staticPath, err := helpers.MakeStaticPathRelative(ev.Name); err == nil { staticFilesChanged[staticPath] = true } } // add new directory to watch list if s, err := os.Stat(ev.Name); err == nil && s.Mode().IsDir() { if ev.Op&fsnotify.Create == fsnotify.Create { watcher.Add(ev.Name) } } } if staticChanged { jww.FEEDBACK.Printf("Static file changed, syncing\n\n") utils.StopOnErr(copyStatic(), fmt.Sprintf("Error copying static files to %s", helpers.AbsPathify(viper.GetString("PublishDir")))) if !BuildWatch && !viper.GetBool("DisableLiveReload") { // Will block forever trying to write to a channel that nobody is reading if livereload isn't initalized // force refresh when more than one file if len(staticFilesChanged) == 1 { for path := range staticFilesChanged { livereload.RefreshPath(path) } } else { livereload.ForceRefresh() } } } if dynamicChanged { fmt.Print("\nChange detected, rebuilding site\n") const layout = "2006-01-02 15:04 -0700" fmt.Println(time.Now().Format(layout)) utils.CheckErr(buildSite(true)) if !BuildWatch && !viper.GetBool("DisableLiveReload") { // Will block forever trying to write to a channel that nobody is reading if livereload isn't initalized livereload.ForceRefresh() } } case err := <-watcher.Errors: if err != nil { fmt.Println("error:", err) } } } }() if port > 0 { if !viper.GetBool("DisableLiveReload") { livereload.Initialize() http.HandleFunc("/livereload.js", livereload.ServeJS) http.HandleFunc("/livereload", livereload.Handler) } go serve(port) } wg.Wait() return nil }