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:
parent
41c60daf1e
commit
2a582e9778
@ -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
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -45,6 +45,9 @@ type Config struct {
|
||||
// Outputting
|
||||
Permalink string
|
||||
|
||||
// CLI-only
|
||||
Watch bool `yaml:"-"`
|
||||
|
||||
Defaults []struct {
|
||||
Scope struct {
|
||||
Path string
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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 {
|
||||
|
Loading…
Reference in New Issue
Block a user