diff --git a/README.md b/README.md index cad2c8a..387a9be 100644 --- a/README.md +++ b/README.md @@ -39,6 +39,8 @@ func main() { } ``` +If the path argument to `reload.Dir()` ends with /... or \..., the directory will be evaluated recursively. + You can also use `reload.Exec()` to manually restart your process without calling `reload.Do()`. diff --git a/reload.go b/reload.go index 80c3a6d..9ba5378 100644 --- a/reload.go +++ b/reload.go @@ -5,21 +5,21 @@ // // Example: // -// go func() { -// err := reload.Do(log.Printf) -// if err != nil { -// panic(err) -// } -// }() +// go func() { +// err := reload.Do(log.Printf) +// if err != nil { +// panic(err) +// } +// }() // // A list of additional directories to watch can be added: // -// go func() { -// err := reload.Do(log.Printf, reload.Dir("tpl", reloadTpl) -// if err != nil { -// panic(err) -// } -// }() +// go func() { +// err := reload.Do(log.Printf, reload.Dir("tpl", reloadTpl) +// if err != nil { +// panic(err) +// } +// }() // // Note that this package won't prevent race conditions (e.g. when assigning to // a global templates variable). You'll need to use sync.RWMutex yourself. @@ -27,6 +27,7 @@ package reload // import "github.com/teamwork/reload" import ( "fmt" + "io/fs" "math" "os" "path/filepath" @@ -79,6 +80,8 @@ func Do(log func(string, ...interface{}), additional ...dir) error { } timers[binSelf] = stoppedTimer(Exec) + additional = expandAdditional(log, additional) + // Watch the directory, because a recompile renames the existing // file (rather than rewriting it), so we won't get events for that. dirs := make([]string, len(additional)+1) @@ -151,6 +154,35 @@ func Do(log func(string, ...interface{}), additional ...dir) error { return nil } +func expandAdditional(log func(string, ...interface{}), additional []dir) []dir { + result := make([]dir, 0, len(additional)) + for _, a := range additional { + if strings.HasSuffix(a.path, "\\...") { + result = append(result, listDirs(log, strings.TrimSuffix(a.path, "\\..."), a.cb)...) + } else if strings.HasSuffix(a.path, "/...") { + result = append(result, listDirs(log, strings.TrimSuffix(a.path, "/..."), a.cb)...) + } else { + result = append(result, a) + } + } + return result +} + +func listDirs(log func(string, ...interface{}), rootPath string, cb func()) (result []dir) { + filepath.WalkDir(rootPath, func(dirPath string, d fs.DirEntry, err error) error { + if err != nil { + log("Error reading %s, skipped", dirPath) + return fs.SkipDir + } + if d.IsDir() { + result = append(result, Dir(dirPath, cb)) + } + return nil + }) + + return +} + // Exec replaces the current process with a new copy of itself. func Exec() { execName := binSelf