1
0
mirror of https://github.com/danog/gojekyll.git synced 2024-11-30 06:19:00 +01:00

Implement serve --[no-]watch

This commit is contained in:
Oliver Steele 2017-07-14 18:40:09 -04:00
parent 41c60daf1e
commit 2a582e9778
6 changed files with 45 additions and 24 deletions

View File

@ -147,8 +147,8 @@ Muzukashii:
- [x] `clean`
- [x] `help`
- [x] `serve`
- [x] `--open-uri`, `--host`, `--port`
- [ ] `--baseurl`, `--config`, `--incremental`, `--[no-]watch` (`watch` is always enabled)
- [x] `--open-uri`, `--host`, `--port`, `watch` (enabled by default)
- [ ] `--baseurl`, `--config`, `--incremental`
- [ ] `--detach`, `--ssl`-* not planned
- [ ] `doctor`, `import`, `new`, `new-theme` not planned
- [ ] Windows

View File

@ -9,7 +9,8 @@ import (
// Command-line options
var (
buildOptions site.BuildOptions
configFlags = config.Flags{}
watch = true
configFlags = config.Flags{Watch: &watch}
profile = false
quiet = false
)
@ -36,7 +37,7 @@ var (
serve = app.Command("serve", "Serve your site locally").Alias("server").Alias("s")
open = serve.Flag("open-url", "Launch your site in a browser").Short('o').Bool()
_ = app.Flag("host", "Host to bind to").Short('H').Action(stringVar("host", &configFlags.Host)).String()
_ = serve.Flag("host", "Host to bind to").Short('H').Action(stringVar("host", &configFlags.Host)).String()
_ = serve.Flag("port", "Port to listen on").Short('P').Action(intVar("port", &configFlags.Port)).Int()
variables = app.Command("variables", "Display a file or URL path's variables").Alias("v").Alias("var").Alias("vars")
@ -50,4 +51,5 @@ func init() {
app.Flag("profile", "Create a Go pprof CPU profile").BoolVar(&profile)
app.Flag("quiet", "Silence (some) output.").Short('q').BoolVar(&quiet)
build.Flag("dry-run", "Dry run").Short('n').BoolVar(&buildOptions.DryRun)
serve.Flag("watch", "Watch for changes and rebuild").Short('w').Default("true").BoolVar(&watch)
}

View File

@ -45,6 +45,9 @@ type Config struct {
// Outputting
Permalink string
// CLI-only
Watch bool `yaml:"-"`
Defaults []struct {
Scope struct {
Path string

View File

@ -3,9 +3,9 @@ package config
// Flags are applied after the configuration file is loaded.
// They are pointers to represent optional types, to tell whether they have been set.
type Flags struct {
Destination, Host *string
Drafts, Future, Unpublished *bool
Port *int
Destination, Host *string
Drafts, Future, Unpublished, Watch *bool
Port *int
}
// ApplyFlags overwrites the configuration with values from flags.
@ -28,4 +28,7 @@ func (c *Config) ApplyFlags(flags Flags) {
if flags.Unpublished != nil {
c.Unpublished = *flags.Unpublished
}
if flags.Watch != nil {
c.Watch = *flags.Watch
}
}

View File

@ -27,11 +27,13 @@ func (s *Server) Run(open bool, logger func(label, value string)) error {
s.Site.SetAbsoluteURL("")
address := fmt.Sprintf("%s:%d", cfg.Host, cfg.Port)
logger("Server address:", "http://"+address+"/")
if err := s.StartLiveReloader(); err != nil {
return err
}
if err := s.watchAndReload(); err != nil {
return err
if cfg.Watch {
if err := s.StartLiveReloader(); err != nil {
return err
}
if err := s.watchAndReload(); err != nil {
return err
}
}
http.HandleFunc("/", s.handler)
c := make(chan error)

View File

@ -51,24 +51,35 @@ func (s *Server) watchFiles(fn func([]string)) error {
}()
go func() {
for {
filenames := <-debounced
relpaths := make([]string, 0, len(filenames))
seen := map[string]bool{}
for _, filename := range filenames {
relpath := utils.MustRel(sourceDir, filename)
if relpath == "_config.yml" || !site.Exclude(relpath) {
if !seen[relpath] {
seen[relpath] = true
relpaths = append(relpaths, relpath)
}
}
paths := s.sitePaths(<-debounced)
if len(paths) > 0 {
fn(paths)
}
fn(relpaths)
}
}()
return watcher.Add(sourceDir)
}
// relativize and de-dup paths and filter to those the site source
func (s *Server) sitePaths(filenames []string) []string {
var (
site = s.Site
dir = site.SourceDir()
paths = make([]string, 0, len(filenames))
seen = map[string]bool{}
)
for _, filename := range filenames {
path := utils.MustRel(dir, filename)
if path == "_config.yml" || !site.Exclude(path) {
if !seen[path] {
seen[path] = true
paths = append(paths, path)
}
}
}
return paths
}
// debounce relays values from input to output, merging successive values within interval
// TODO consider https://github.com/ReactiveX/RxGo
func debounce(interval time.Duration, input <-chan string) <-chan []string {