feat: monitor glance.yml for changes
This commit is contained in:
parent
6de0f73ec1
commit
1600007f70
6 changed files with 87 additions and 16 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -1,4 +1,6 @@
|
|||
/assets
|
||||
/build
|
||||
/playground
|
||||
.idea
|
||||
.vscode
|
||||
glance.yml
|
||||
|
|
2
go.mod
2
go.mod
|
@ -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
4
go.sum
|
@ -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=
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue