feat: monitor glance.yml for changes

This commit is contained in:
teemozhu 2024-05-20 14:37:08 +08:00
parent 6de0f73ec1
commit 1600007f70
6 changed files with 87 additions and 16 deletions

2
.gitignore vendored
View File

@ -1,4 +1,6 @@
/assets
/build
/playground
.idea
.vscode
glance.yml

2
go.mod
View File

@ -11,9 +11,11 @@ require (
require (
github.com/PuerkitoBio/goquery v1.9.1 // indirect
github.com/andybalholm/cascadia v1.3.2 // indirect
github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/mmcdole/goxpp v1.1.1 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
golang.org/x/net v0.24.0 // indirect
golang.org/x/sys v0.19.0 // indirect
)

4
go.sum
View File

@ -5,6 +5,8 @@ github.com/andybalholm/cascadia v1.3.2/go.mod h1:7gtRlve5FxPPgIgX36uWBX58OdBsSS6
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
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/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
@ -45,6 +47,8 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=

View File

@ -1,8 +1,11 @@
package glance
import (
"errors"
"fmt"
"github.com/fsnotify/fsnotify"
"io"
"os"
"gopkg.in/yaml.v3"
)
@ -35,6 +38,19 @@ func NewConfigFromYml(contents io.Reader) (*Config, error) {
return config, nil
}
// NewConfigFromFile reads a yaml file and returns a Config struct
func NewConfigFromFile(path string) (*Config, error) {
configFile, err := os.Open(path)
if err != nil {
return nil, errors.New("failed opening config file: " + err.Error())
}
defer configFile.Close()
return NewConfigFromYml(configFile)
}
func NewConfig() *Config {
config := &Config{}
@ -77,3 +93,44 @@ func configIsValid(config *Config) error {
return nil
}
func watchConfigFile(configPath string, f func(*Config) error) {
watcher, err := fsnotify.NewWatcher()
if err != nil {
fmt.Printf("failed creating watcher: %v\n", err)
return
}
go func() {
for {
select {
case event, ok := <-watcher.Events:
if !ok {
return
}
if event.Op&fsnotify.Write == fsnotify.Write {
config, err := NewConfigFromFile(configPath)
if err != nil {
fmt.Printf("failed loading config file: %v\n", err)
return
}
err = f(config)
if err != nil {
fmt.Printf("failed applying new config: %v\n", err)
}
}
case err, ok := <-watcher.Errors:
if !ok {
return
}
_ = watcher.Close()
fmt.Printf("watcher error: %v\n", err)
}
}
}()
err = watcher.Add(configPath)
if err != nil {
fmt.Printf("failed adding watcher: %v\n", err)
}
}

View File

@ -97,6 +97,10 @@ func titleToSlug(s string) string {
}
func NewApplication(config *Config) (*Application, error) {
// make sure the config is valid
if config == nil {
return nil, fmt.Errorf("config is nil")
}
if len(config.Pages) == 0 {
return nil, fmt.Errorf("no pages configured")
}
@ -107,17 +111,24 @@ func NewApplication(config *Config) (*Application, error) {
slugToPage: make(map[string]*Page),
}
app.slugToPage[""] = &config.Pages[0]
app.Reload(config)
return app, nil
}
// Reload updates the application with a new config
func (a *Application) Reload(config *Config) {
a.Config = *config
a.slugToPage[""] = &config.Pages[0]
for i := range config.Pages {
if config.Pages[i].Slug == "" {
config.Pages[i].Slug = titleToSlug(config.Pages[i].Title)
}
app.slugToPage[config.Pages[i].Slug] = &config.Pages[i]
a.slugToPage[config.Pages[i].Slug] = &config.Pages[i]
}
return app, nil
}
func (a *Application) HandlePageRequest(w http.ResponseWriter, r *http.Request) {

View File

@ -2,7 +2,6 @@ package glance
import (
"fmt"
"os"
)
func Main() int {
@ -13,18 +12,9 @@ func Main() int {
return 1
}
configFile, err := os.Open(options.ConfigPath)
config, err := NewConfigFromFile(options.ConfigPath)
if err != nil {
fmt.Printf("failed opening config file: %v\n", err)
return 1
}
config, err := NewConfigFromYml(configFile)
configFile.Close()
if err != nil {
fmt.Printf("failed parsing config file: %v\n", err)
fmt.Printf("failed loading config file: %v\n", err)
return 1
}
@ -36,6 +26,11 @@ func Main() int {
return 1
}
watchConfigFile(options.ConfigPath, func(config *Config) error {
app.Reload(config)
return nil
})
if app.Serve() != nil {
fmt.Printf("http server error: %v\n", err)
return 1