improve manager options workflow

- Break out ManagerOpts type
- Add default configuration values system
- Add WithOpts method
- Rename WithPrefix to WithEnvOverride
This commit is contained in:
Elijah Duffy
2025-06-12 17:50:15 -07:00
parent 0b7c857070
commit 6addf74925
3 changed files with 62 additions and 22 deletions

View File

@@ -10,7 +10,29 @@ import (
"github.com/spf13/viper"
)
// Manager is the top-level configuration schema and viper instance.
// ManagerOpts defines options for the configuration manager.
type ManagerOpts[T any] struct {
// PreLoad is an optional function that is called before loading the
// configuration file.
PreLoad func(*Manager[T]) error
// PostLoad is an optional function that is called after loading the
// configuration file.
PostLoad func(*Manager[T]) error
// EnvPrefix is an optional environment variable prefix that will be used
// to override configuration values from environment variables. If set,
// viper will automatically read environment variables with this prefix.
EnvPrefix string
// Defaults is a map of default values for the configuration.
Defaults map[string]any
}
// Manager is the top-level configuration schema and viper instance. Always use
// the C() method to access the loaded configuration. Always use NewManager to
// create a new configuration manager. The type parameter T is the configuration
// schema that will be used to unmarshal the configuration file.
type Manager[T any] struct {
// PreLoad is an optional function that is called before loading the
// configuration file.
@@ -49,9 +71,33 @@ func NewManager[T any](configName, configType, configPath string) *Manager[T] {
return m
}
// WithPrefix sets the environment variable prefix for the viper instance. Must
// be set in order to use environment variables for configuration.
func (m *Manager[T]) WithPrefix(prefix string) *Manager[T] {
// WithOpts sets additional options for the Manager.
func (m *Manager[T]) WithOpts(opts *ManagerOpts[T]) *Manager[T] {
if opts == nil {
return m
}
if opts.PreLoad != nil {
m.PreLoad = opts.PreLoad
}
if opts.PostLoad != nil {
m.PostLoad = opts.PostLoad
}
if opts.Defaults != nil {
for key, value := range opts.Defaults {
m.viper.SetDefault(key, value)
}
}
if opts.EnvPrefix != "" {
m.WithEnvOverride(opts.EnvPrefix)
}
return m
}
// WithEnvOverride sets the environment variable prefix for the viper instance
// and configures viper to automatically read environment variables.
func (m *Manager[T]) WithEnvOverride(prefix string) *Manager[T] {
m.viper.SetEnvPrefix(prefix)
m.viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
m.viper.AutomaticEnv()