mirror of
https://github.com/facundoolano/jorge.git
synced 2024-12-25 21:58:28 +01:00
implement blorg serve command
Squashed commit of the following: commit 5e3c3f35c73f884bbf89f5daabcdc2aec5e0af75 Author: facundoolano <facundo.olano@gmail.com> Date: Wed Feb 14 11:24:45 2024 -0300 cleanup commit e8881df9f27fc37c46120c946dfad107d551ef67 Author: facundoolano <facundo.olano@gmail.com> Date: Wed Feb 14 11:21:54 2024 -0300 add basic src watching commit 4e61add89c632b0cc7a740d15be671de3df12157 Author: facundoolano <facundo.olano@gmail.com> Date: Wed Feb 14 00:19:25 2024 -0300 move serve command to a separate file commit abc2100582b71179e0eade154d2af3e86b48574f Author: facundoolano <facundo.olano@gmail.com> Date: Wed Feb 14 00:17:05 2024 -0300 first stab at serve command
This commit is contained in:
parent
cea4ac7b1c
commit
b181e3d855
4 changed files with 128 additions and 9 deletions
|
@ -2,12 +2,13 @@ package commands
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/facundoolano/blorg/site"
|
||||
"io"
|
||||
"io/fs"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/facundoolano/blorg/site"
|
||||
)
|
||||
|
||||
const SRC_DIR = "src"
|
||||
|
@ -98,11 +99,3 @@ func New() error {
|
|||
fmt.Println("not implemented yet")
|
||||
return nil
|
||||
}
|
||||
|
||||
func Serve() error {
|
||||
// build
|
||||
// serve target with file server
|
||||
// (later watch and live reload)
|
||||
fmt.Println("not implemented yet")
|
||||
return nil
|
||||
}
|
||||
|
|
120
commands/serve.go
Normal file
120
commands/serve.go
Normal file
|
@ -0,0 +1,120 @@
|
|||
package commands
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/fs"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/fsnotify/fsnotify"
|
||||
)
|
||||
|
||||
// Generate and serve the site, rebuilding when the source files change.
|
||||
func Serve() error {
|
||||
// TODO tweak the building logic to inject js snippet that reloads the browser on rebuild
|
||||
|
||||
// first rebuild the target
|
||||
if err := Build(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// watch for changes in src and layouts, and trigger a rebuild
|
||||
watcher, err := setupWatcher()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer watcher.Close()
|
||||
|
||||
// serve the target dir with a file server
|
||||
fs := http.FileServer(HTMLDir{http.Dir("target/")})
|
||||
http.Handle("/", http.StripPrefix("/", fs))
|
||||
fmt.Println("server listening at http://localhost:4001/")
|
||||
http.ListenAndServe(":4001", nil)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Tweaks the http file system to construct a server that hides the .html suffix from requests.
|
||||
// Based on https://stackoverflow.com/a/57281956/993769
|
||||
type HTMLDir struct {
|
||||
d http.Dir
|
||||
}
|
||||
|
||||
func (d HTMLDir) Open(name string) (http.File, error) {
|
||||
// Try name as supplied
|
||||
f, err := d.d.Open(name)
|
||||
if os.IsNotExist(err) {
|
||||
// Not found, try with .html
|
||||
if f, err := d.d.Open(name + ".html"); err == nil {
|
||||
return f, nil
|
||||
}
|
||||
}
|
||||
return f, err
|
||||
}
|
||||
|
||||
func setupWatcher() (*fsnotify.Watcher, error) {
|
||||
watcher, err := fsnotify.NewWatcher()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
go func() {
|
||||
for {
|
||||
select {
|
||||
case event, ok := <-watcher.Events:
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
// chmod events are noisy, ignore them
|
||||
isChmod := event.Has(fsnotify.Chmod)
|
||||
|
||||
// I've seen issues with temporary files, eg. .#name.org generated by emacs
|
||||
// I'll just ignore changes to dotfiles to stay on the safe side
|
||||
isDotFile := strings.HasPrefix(filepath.Base(event.Name), ".")
|
||||
|
||||
if !isChmod && !isDotFile {
|
||||
fmt.Printf("\nFile %s changed, triggering rebuild.\n", event.Name)
|
||||
|
||||
// since new nested directories could be triggering this change, and we need to watch those too
|
||||
// and since re-watching files is a noop, I just re-add the entire src everytime there's a change
|
||||
if err := addAll(watcher); err != nil {
|
||||
fmt.Println("error:", err)
|
||||
return
|
||||
}
|
||||
|
||||
if err := Build(); err != nil {
|
||||
fmt.Println("error:", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
case err, ok := <-watcher.Errors:
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
fmt.Println("error:", err)
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
err = addAll(watcher)
|
||||
|
||||
return watcher, err
|
||||
}
|
||||
|
||||
// Add the layouts and all source directories to the given watcher
|
||||
func addAll(watcher *fsnotify.Watcher) error {
|
||||
err := watcher.Add(LAYOUTS_DIR)
|
||||
// fsnotify watches all files within a dir, but non recursively
|
||||
// this walks through the src dir and adds watches for each found directory
|
||||
filepath.WalkDir(SRC_DIR, func(path string, entry fs.DirEntry, err error) error {
|
||||
if entry.IsDir() {
|
||||
watcher.Add(path)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
return err
|
||||
}
|
2
go.mod
2
go.mod
|
@ -9,8 +9,10 @@ require (
|
|||
)
|
||||
|
||||
require (
|
||||
github.com/fsnotify/fsnotify v1.7.0 // indirect
|
||||
github.com/osteele/liquid v1.3.2 // indirect
|
||||
github.com/osteele/tuesday v1.0.3 // indirect
|
||||
golang.org/x/net v0.0.0-20201224014010-6772e930b67b // indirect
|
||||
golang.org/x/sys v0.4.0 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
)
|
||||
|
|
4
go.sum
4
go.sum
|
@ -1,5 +1,7 @@
|
|||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
|
||||
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
|
||||
github.com/niklasfasching/go-org v1.7.0 h1:vyMdcMWWTe/XmANk19F4k8XGBYg0GQ/gJGMimOjGMek=
|
||||
github.com/niklasfasching/go-org v1.7.0/go.mod h1:WuVm4d45oePiE0eX25GqTDQIt/qPW1T9DGkRscqLW5o=
|
||||
github.com/osteele/liquid v1.3.2 h1:G+MvVYt1HX2xuv99JgdrhV7zRVdlvFnNi8M5rN8gQmI=
|
||||
|
@ -13,6 +15,8 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
|
|||
golang.org/x/net v0.0.0-20201224014010-6772e930b67b h1:iFwSg7t5GZmB/Q5TjiEAsdoLDrdJRC1RiF2WhuV29Qw=
|
||||
golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18=
|
||||
golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
|
|
Loading…
Reference in a new issue