File watching extension for uconfig. Add watchfiles.New() to your plugins and call Watch for automatic config reload when source files change.
package main
import (
"context"
"encoding/json"
"fmt"
"os"
"os/signal"
"github.com/omeid/uconfig"
"github.com/omeid/uconfig/plugins/file"
watchfiles "github.com/omeid/uconfig-watchfiles"
)
type Config struct {
Hosts []string `default:"localhost" usage:"bind addresses"`
Mode string `default:"start" flag:",command" usage:"start|stop"`
}
var files = uconfig.Files{
{Path: file.Relative("config.json"), Unmarshal: json.Unmarshal, Optional: true},
}
func main() {
ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt)
defer cancel()
conf := uconfig.Classic[Config](files, watchfiles.New())
err := conf.Watch(ctx, func(ctx context.Context, c *Config) error {
fmt.Printf("config loaded: %+v\n", c)
// Block until told to reload or stop.
<-ctx.Done()
return nil
// Return nil to exit Watch cleanly.
// Return any other error to abort.
})
if err != nil {
fmt.Println(err)
os.Exit(1)
}
}The callback is called once with the initial config, then again whenever a config file changes. Changes are debounced (200ms). When a file changes, the callback's context is cancelled, the full config is re-parsed (preserving env, flags, and other sources), and the callback is called again with the new value.
watchfiles.New() is a uconfig Extension plugin. It discovers file paths from sibling file plugins and watches them with fsnotify. One watcher handles all files.
go get github.com/omeid/uconfig-watchfiles
MIT.