Skip to content

Commit

Permalink
Update watch; pass config to cli
Browse files Browse the repository at this point in the history
  • Loading branch information
infogulch committed Oct 13, 2023
1 parent 96b6330 commit 42a98ef
Show file tree
Hide file tree
Showing 7 changed files with 67 additions and 81 deletions.
1 change: 1 addition & 0 deletions TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

- [ ] Split xtemplate from caddy so it can be used standalone
- [ ] Integrate a static file server based on `caddy.caddyhttp.file_server`
- Serve static files from tempalates dir that are not .html files
- [ ] Add "Why?" section to readme.

### Automation
Expand Down
102 changes: 47 additions & 55 deletions bin/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import (
)

type flags struct {
help bool
listen_addr string
template_root string
context_root string
Expand All @@ -27,11 +26,10 @@ type flags struct {
db_driver string
db_connstr string
log_level int
configFlags configFlags
config config
}

func parseflags() (f flags) {
flag.BoolVar(&f.help, "help", false, "Display help")
flag.StringVar(&f.listen_addr, "listen", "0.0.0.0:8080", "Listen address")
flag.StringVar(&f.template_root, "template-root", "templates", "Template root directory")
flag.StringVar(&f.context_root, "context-root", "", "Context root directory")
Expand All @@ -42,12 +40,11 @@ func parseflags() (f flags) {
flag.StringVar(&f.db_driver, "db-driver", "", "Database driver name")
flag.StringVar(&f.db_connstr, "db-connstr", "", "Database connection string")
flag.IntVar(&f.log_level, "log", 0, "Log level, DEBUG=-4, INFO=0, WARN=4, ERROR=8")
flag.Var(&f.configFlags, "c", "Config values, in the form `x=y`, can be specified multiple times")
flag.Var(&f.config, "c", "Config values, in the form `x=y`, can be specified multiple times")
flag.Parse()
if f.help {
fmt.Printf("%s is a hypertext preprocessor and http templating web server\n\n", os.Args[0])
flag.Usage = func() {
fmt.Fprintf(flag.CommandLine.Output(), "xtemplate is a hypertext preprocessor and http templating web server.\nUsage of %s:\n", os.Args[0])
flag.PrintDefaults()
os.Exit(0)
}
return
}
Expand All @@ -59,6 +56,7 @@ func main() {
var err error
var db *sql.DB
var contextfs fs.FS
var config map[string]string

if flags.db_driver != "" {
db, err = sql.Open(flags.db_driver, flags.db_connstr)
Expand All @@ -72,10 +70,15 @@ func main() {
contextfs = os.DirFS(flags.context_root)
}

for _, kv := range flags.config {
config[kv.Key] = kv.Value
}

x := xtemplate.XTemplate{
TemplateFS: os.DirFS(flags.template_root),
ContextFS: contextfs,
// ExtraFuncs
Config: config,
Delims: struct{ L, R string }{L: flags.l_delim, R: flags.r_delim},
DB: db,
Log: log.WithGroup("xtemplate"),
Expand All @@ -86,71 +89,60 @@ func main() {
os.Exit(2)
}

var watch []string
if flags.watch_template {
watch = append(watch, flags.template_root)
}
if flags.watch_context {
if flags.context_root == "" {
log.Error("cannot watch context root if it is not specified", "context_root", flags.context_root)
os.Exit(3)
// set up fswatch
{
var watchDirs []string
if flags.watch_template {
watchDirs = append(watchDirs, flags.template_root)
}
watch = append(watch, flags.context_root)
}
if len(watch) != 0 {
dowatch(watch, func() error { return x.Reload() }, log)
}

log.Info("serving", "address", flags.listen_addr)
fmt.Printf("server stopped: %v\n", http.ListenAndServe(flags.listen_addr, &x))
}

func dowatch(dirs []string, do func() error, log *slog.Logger) {
changed, _, err := watch.WatchDirs([]string{"templates"}, 200*time.Millisecond, log)
if err != nil {
slog.Info("failed to watch directories", "error", err)
}
go func() {
for {
select {
case _, ok := <-changed:
if !ok {
return
}
err := do()
if flags.watch_context {
if flags.context_root == "" {
log.Error("cannot watch context root if it is not specified", "context_root", flags.context_root)
os.Exit(3)
}
watchDirs = append(watchDirs, flags.context_root)
}
if len(watchDirs) != 0 {
changed, halt, err := watch.WatchDirs(watchDirs, 200*time.Millisecond)
if err != nil {
slog.Info("failed to watch directories", "error", err, "directories", watchDirs)
os.Exit(4)
}
watch.React(changed, halt, func() (halt bool) {
err := x.Reload()
if err != nil {
log.Info("failed to reload xtemplate", "error", err)
} else {
log.Info("reloaded templates after file changed")
}
}
return
})
}
}()
}

log.Info("serving", "address", flags.listen_addr)
fmt.Printf("server stopped: %v\n", http.ListenAndServe(flags.listen_addr, &x))
}

type configFlags []struct{ Key, Value string }
type kv struct{ Key, Value string }

func (kv kv) String() string { return kv.Key + "=" + kv.Value }

func (c *configFlags) String() string {
type config []kv

func (c *config) String() string {
if c == nil {
return ""
}
s := new(strings.Builder)
for i, f := range *c {
if i > 0 {
s.WriteRune(' ')
}
s.WriteString(f.Key)
s.WriteRune('=')
s.WriteString(f.Value)
}
return s.String()
s := fmt.Sprint(*c)
return s[1 : len(s)-1]
}

func (c *configFlags) Set(arg string) error {
func (c *config) Set(arg string) error {
s := strings.SplitN(arg, "=", 2)
if len(s) != 2 {
return fmt.Errorf("config arg must be in the form `x=y`, got: `%s`", arg)
return fmt.Errorf("config arg must be in the form `k=v`, got: `%s`", arg)
}
*c = append(*c, struct{ Key, Value string }{Key: s[0], Value: s[1]})
*c = append(*c, kv{Key: s[0], Value: s[1]})
return nil
}
2 changes: 1 addition & 1 deletion caddy/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ go 1.21.0

require (
github.com/caddyserver/caddy/v2 v2.7.4
github.com/infogulch/watch v0.1.2
github.com/infogulch/watch v0.1.3
github.com/infogulch/xtemplate v0.1.2
github.com/mattn/go-sqlite3 v1.14.17
go.uber.org/zap/exp v0.2.0
Expand Down
4 changes: 2 additions & 2 deletions caddy/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -358,8 +358,8 @@ github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLf
github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
github.com/infogulch/pathmatcher v0.2.0 h1:pi8/e2BQ8x1nB1WAEnnVOIw+EciKDDSUYqDZsJjlVaM=
github.com/infogulch/pathmatcher v0.2.0/go.mod h1:ywO4eSHD1ARQElpii9hjqkPYFZ+IZKJ+3qDo9IZyt78=
github.com/infogulch/watch v0.1.2 h1:7mF3VN1T1Nby5NO0npTqE+OgHR7+OfJO261stDJH7TY=
github.com/infogulch/watch v0.1.2/go.mod h1:i9OU29MppSWictJKM3LoipjLVw+6VHiOK/SrzfujJGc=
github.com/infogulch/watch v0.1.3 h1:ONDgRwCs86R6Fpmhd8V8ucuyR7P4HlQMbO3vVpG2UCU=
github.com/infogulch/watch v0.1.3/go.mod h1:i9OU29MppSWictJKM3LoipjLVw+6VHiOK/SrzfujJGc=
github.com/infogulch/xtemplate v0.1.2 h1:ytJtL3301cKkr9i3zdf/s1Bdh08KDWv/mWdvWyXbMjQ=
github.com/infogulch/xtemplate v0.1.2/go.mod h1:FZwceAVuWokIWwb9jjMvnd0iaZTU3j2Ur08wGk+wHh4=
github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo=
Expand Down
33 changes: 13 additions & 20 deletions caddy/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ func (m *XTemplateModule) Provision(ctx caddy.Context) error {
Log: log.WithGroup("xtemplate"),
}

var watchPaths []string
var watchDirs []string

// Context FS
if m.ContextRoot != "" {
Expand All @@ -103,7 +103,7 @@ func (m *XTemplateModule) Provision(ctx caddy.Context) error {
return fmt.Errorf("context file path does not exist in filesystem: %v", err)
}
t.ContextFS = cfs
watchPaths = append(watchPaths, m.ContextRoot)
watchDirs = append(watchDirs, m.ContextRoot)
}

// Template FS
Expand All @@ -117,7 +117,7 @@ func (m *XTemplateModule) Provision(ctx caddy.Context) error {
return fmt.Errorf("root file path does not exist in filesystem: %v", err)
}
t.TemplateFS = tfs
watchPaths = append(watchPaths, root)
watchDirs = append(watchDirs, root)
}

// ExtraFuncs
Expand Down Expand Up @@ -155,28 +155,21 @@ func (m *XTemplateModule) Provision(ctx caddy.Context) error {

m.template = t

{
changed, halt, err := watch.WatchDirs(watchPaths, 200*time.Millisecond, log)
if len(watchDirs) > 0 {
changed, halt, err := watch.WatchDirs(watchDirs, 200*time.Millisecond)
if err != nil {
return err
}
m.halt = halt
go func() {
for {
select {
case _, ok := <-changed:
if !ok {
return
}
err := t.Reload()
if err != nil {
log.Info("failed to reload xtemplate", "error", err)
} else {
log.Info("reloaded templates after file changed")
}
}
watch.React(changed, halt, func() (halt bool) {
err := t.Reload()
if err != nil {
log.Info("failed to reload xtemplate", "error", err)
} else {
log.Info("reloaded templates after file changed")
}
}()
return
})
}
return nil
}
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ require (
github.com/alecthomas/chroma/v2 v2.9.1
github.com/dustin/go-humanize v1.0.1
github.com/infogulch/pathmatcher v0.2.0
github.com/infogulch/watch v0.1.2
github.com/infogulch/watch v0.1.3
github.com/mattn/go-sqlite3 v1.14.17
github.com/microcosm-cc/bluemonday v1.0.25
github.com/segmentio/ksuid v1.0.4
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4=
github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY=
github.com/infogulch/pathmatcher v0.2.0 h1:pi8/e2BQ8x1nB1WAEnnVOIw+EciKDDSUYqDZsJjlVaM=
github.com/infogulch/pathmatcher v0.2.0/go.mod h1:ywO4eSHD1ARQElpii9hjqkPYFZ+IZKJ+3qDo9IZyt78=
github.com/infogulch/watch v0.1.2 h1:7mF3VN1T1Nby5NO0npTqE+OgHR7+OfJO261stDJH7TY=
github.com/infogulch/watch v0.1.2/go.mod h1:i9OU29MppSWictJKM3LoipjLVw+6VHiOK/SrzfujJGc=
github.com/infogulch/watch v0.1.3 h1:ONDgRwCs86R6Fpmhd8V8ucuyR7P4HlQMbO3vVpG2UCU=
github.com/infogulch/watch v0.1.3/go.mod h1:i9OU29MppSWictJKM3LoipjLVw+6VHiOK/SrzfujJGc=
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
Expand Down

0 comments on commit 42a98ef

Please sign in to comment.