mirror of
https://github.com/taigrr/jety.git
synced 2026-04-01 19:08:58 -07:00
refactor: extract parseEnv helper, add doc comments, fix param shadow
- Extract parseEnv() to deduplicate env parsing in NewConfigManager, WithEnvPrefix, and SetEnvPrefix (was 3 copies of the same logic). - Add doc comments to ConfigMap, ConfigManager, NewConfigManager, WithEnvPrefix, SetEnvPrefix, IsSet, AllKeys, AllSettings. - Rename configType parameter in SetConfigType to avoid shadowing the configType type.
This commit is contained in:
82
jety.go
82
jety.go
@@ -22,11 +22,14 @@ const (
|
|||||||
type (
|
type (
|
||||||
configType string
|
configType string
|
||||||
|
|
||||||
|
// ConfigMap holds a configuration entry with its original key name and value.
|
||||||
ConfigMap struct {
|
ConfigMap struct {
|
||||||
Key string
|
Key string
|
||||||
Value any
|
Value any
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ConfigManager manages layered configuration from defaults, files,
|
||||||
|
// environment variables, and programmatic overrides.
|
||||||
ConfigManager struct {
|
ConfigManager struct {
|
||||||
configName string
|
configName string
|
||||||
configPath string
|
configPath string
|
||||||
@@ -46,40 +49,47 @@ var (
|
|||||||
ErrConfigFileEmpty = errors.New("config file is empty")
|
ErrConfigFileEmpty = errors.New("config file is empty")
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewConfigManager() *ConfigManager {
|
// parseEnv reads environment variables, optionally filtering by prefix,
|
||||||
cm := ConfigManager{}
|
// and returns a map keyed by lowercased (and prefix-stripped) variable names.
|
||||||
cm.envConfig = make(map[string]ConfigMap)
|
func parseEnv(prefix string) map[string]ConfigMap {
|
||||||
cm.overrideConfig = make(map[string]ConfigMap)
|
result := make(map[string]ConfigMap)
|
||||||
cm.fileConfig = make(map[string]ConfigMap)
|
for _, env := range os.Environ() {
|
||||||
cm.defaultConfig = make(map[string]ConfigMap)
|
|
||||||
cm.combinedConfig = make(map[string]ConfigMap)
|
|
||||||
envSet := os.Environ()
|
|
||||||
for _, env := range envSet {
|
|
||||||
key, value, found := strings.Cut(env, "=")
|
key, value, found := strings.Cut(env, "=")
|
||||||
if !found {
|
if !found {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
lower := strings.ToLower(key)
|
if prefix != "" {
|
||||||
cm.envConfig[lower] = ConfigMap{Key: key, Value: value}
|
stripped, ok := strings.CutPrefix(key, prefix)
|
||||||
|
if !ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
key = stripped
|
||||||
|
}
|
||||||
|
result[strings.ToLower(key)] = ConfigMap{Key: key, Value: value}
|
||||||
}
|
}
|
||||||
return &cm
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewConfigManager creates a new ConfigManager with all environment
|
||||||
|
// variables loaded. Use [ConfigManager.WithEnvPrefix] or
|
||||||
|
// [ConfigManager.SetEnvPrefix] to filter by prefix.
|
||||||
|
func NewConfigManager() *ConfigManager {
|
||||||
|
return &ConfigManager{
|
||||||
|
envConfig: parseEnv(""),
|
||||||
|
overrideConfig: make(map[string]ConfigMap),
|
||||||
|
fileConfig: make(map[string]ConfigMap),
|
||||||
|
defaultConfig: make(map[string]ConfigMap),
|
||||||
|
combinedConfig: make(map[string]ConfigMap),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithEnvPrefix filters environment variables to only those starting with
|
||||||
|
// the given prefix, stripping the prefix from key names. Returns the
|
||||||
|
// ConfigManager for chaining.
|
||||||
func (c *ConfigManager) WithEnvPrefix(prefix string) *ConfigManager {
|
func (c *ConfigManager) WithEnvPrefix(prefix string) *ConfigManager {
|
||||||
c.mutex.Lock()
|
c.mutex.Lock()
|
||||||
defer c.mutex.Unlock()
|
defer c.mutex.Unlock()
|
||||||
envSet := os.Environ()
|
c.envConfig = parseEnv(prefix)
|
||||||
c.envConfig = make(map[string]ConfigMap)
|
|
||||||
for _, env := range envSet {
|
|
||||||
key, value, found := strings.Cut(env, "=")
|
|
||||||
if !found {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if withoutPrefix, ok := strings.CutPrefix(key, prefix); ok {
|
|
||||||
lower := strings.ToLower(withoutPrefix)
|
|
||||||
c.envConfig[lower] = ConfigMap{Key: withoutPrefix, Value: value}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -201,10 +211,10 @@ func (c *ConfigManager) WriteConfig() error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ConfigManager) SetConfigType(configType string) error {
|
func (c *ConfigManager) SetConfigType(ct string) error {
|
||||||
c.mutex.Lock()
|
c.mutex.Lock()
|
||||||
defer c.mutex.Unlock()
|
defer c.mutex.Unlock()
|
||||||
switch configType {
|
switch ct {
|
||||||
case "toml":
|
case "toml":
|
||||||
c.configType = ConfigTypeTOML
|
c.configType = ConfigTypeTOML
|
||||||
case "yaml":
|
case "yaml":
|
||||||
@@ -212,29 +222,17 @@ func (c *ConfigManager) SetConfigType(configType string) error {
|
|||||||
case "json":
|
case "json":
|
||||||
c.configType = ConfigTypeJSON
|
c.configType = ConfigTypeJSON
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("config type %s not supported", configType)
|
return fmt.Errorf("config type %s not supported", ct)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetEnvPrefix filters environment variables to only those starting with
|
||||||
|
// the given prefix, stripping the prefix from key names.
|
||||||
func (c *ConfigManager) SetEnvPrefix(prefix string) {
|
func (c *ConfigManager) SetEnvPrefix(prefix string) {
|
||||||
c.mutex.Lock()
|
c.mutex.Lock()
|
||||||
defer c.mutex.Unlock()
|
defer c.mutex.Unlock()
|
||||||
// Re-read environment variables, stripping the prefix from matching keys.
|
c.envConfig = parseEnv(prefix)
|
||||||
// This mirrors WithEnvPrefix behavior so that prefixed env vars are
|
|
||||||
// accessible by their unprefixed key name.
|
|
||||||
envSet := os.Environ()
|
|
||||||
c.envConfig = make(map[string]ConfigMap)
|
|
||||||
for _, env := range envSet {
|
|
||||||
key, value, found := strings.Cut(env, "=")
|
|
||||||
if !found {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if withoutPrefix, ok := strings.CutPrefix(key, prefix); ok {
|
|
||||||
lower := strings.ToLower(withoutPrefix)
|
|
||||||
c.envConfig[lower] = ConfigMap{Key: withoutPrefix, Value: value}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ConfigManager) ReadInConfig() error {
|
func (c *ConfigManager) ReadInConfig() error {
|
||||||
|
|||||||
Reference in New Issue
Block a user