config reporter #7
| @ -1,6 +1,7 @@ | |||||||
| package config | package config | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
|  | 	"strconv" | ||||||
| 	"strings" | 	"strings" | ||||||
| 
 | 
 | ||||||
| 	"git.defalsify.org/vise.git/logging" | 	"git.defalsify.org/vise.git/logging" | ||||||
| @ -23,6 +24,7 @@ var ( | |||||||
| 	userDbConn         string | 	userDbConn         string | ||||||
| 	userDbConnMode     storage.DbMode | 	userDbConnMode     storage.DbMode | ||||||
| 	Languages          []string | 	Languages          []string | ||||||
|  | 	configManager      *Config | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| type Override struct { | type Override struct { | ||||||
| @ -134,6 +136,17 @@ func GetConns() (storage.Conns, error) { | |||||||
| 
 | 
 | ||||||
| // LoadConfig initializes the configuration values after environment variables are loaded.
 | // LoadConfig initializes the configuration values after environment variables are loaded.
 | ||||||
| func LoadConfig() error { | func LoadConfig() error { | ||||||
|  | 	configManager = NewConfig(logg) | ||||||
|  | 
 | ||||||
|  | 	// Add configuration keys with validation
 | ||||||
|  | 	configManager.AddKey("HOST", "127.0.0.1", false, nil) | ||||||
|  | 	configManager.AddKey("PORT", "7123", false, func(v string) error { | ||||||
|  | 		_, err := strconv.Atoi(v) | ||||||
|  | 		return err | ||||||
|  | 	}) | ||||||
|  | 	configManager.AddKey("DB_CONN", "", true, nil) | ||||||
|  | 	// ... add other keys ?  or is enough :/ ...
 | ||||||
|  | 
 | ||||||
| 	err := setConn() | 	err := setConn() | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
| @ -145,5 +158,7 @@ func LoadConfig() error { | |||||||
| 	DefaultLanguage = defaultLanguage | 	DefaultLanguage = defaultLanguage | ||||||
| 	Languages = languages | 	Languages = languages | ||||||
| 
 | 
 | ||||||
|  | 	// Report configuration
 | ||||||
|  | 	configManager.Report("INFO") | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
|  | |||||||
							
								
								
									
										61
									
								
								config/config_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								config/config_test.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,61 @@ | |||||||
|  | package config | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"fmt" | ||||||
|  | 	"os" | ||||||
|  | 	"testing" | ||||||
|  | 
 | ||||||
|  | 	"git.defalsify.org/vise.git/logging" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // go test -tags configreport ./config/...   ---> run with tag
 | ||||||
|  | func TestConfig(t *testing.T) { | ||||||
|  | 	logger := logging.NewVanilla().WithDomain("test") | ||||||
|  | 	cfg := NewConfig(logger) | ||||||
|  | 
 | ||||||
|  | 	t.Run("Default Values", func(t *testing.T) { | ||||||
|  | 		cfg.AddKey("TEST_KEY", "default", false, nil) | ||||||
|  | 		value, err := cfg.GetValue("TEST_KEY") | ||||||
|  | 		t.Logf("Got value: %q, error: %v", value, err) | ||||||
|  | 		if err != nil { | ||||||
|  | 			t.Errorf("unexpected error: %v", err) | ||||||
|  | 		} | ||||||
|  | 		if value != "default" { | ||||||
|  | 			t.Errorf("expected 'default', got '%s'", value) | ||||||
|  | 		} | ||||||
|  | 	}) | ||||||
|  | 
 | ||||||
|  | 	t.Run("Environment Override", func(t *testing.T) { | ||||||
|  | 		os.Setenv("TEST_ENV_KEY", "override") | ||||||
|  | 		defer os.Unsetenv("TEST_ENV_KEY") | ||||||
|  | 
 | ||||||
|  | 		cfg.AddKey("TEST_ENV_KEY", "default", false, nil) | ||||||
|  | 		value, err := cfg.GetValue("TEST_ENV_KEY") | ||||||
|  | 		t.Logf("Got value: %q, error: %v", value, err) | ||||||
|  | 		if err != nil { | ||||||
|  | 			t.Errorf("unexpected error: %v", err) | ||||||
|  | 		} | ||||||
|  | 		if value != "override" { | ||||||
|  | 			t.Errorf("expected 'override', got '%s'", value) | ||||||
|  | 		} | ||||||
|  | 	}) | ||||||
|  | 
 | ||||||
|  | 	t.Run("Validation", func(t *testing.T) { | ||||||
|  | 		validator := func(v string) error { | ||||||
|  | 			if v != "valid" { | ||||||
|  | 				return fmt.Errorf("invalid value") | ||||||
|  | 			} | ||||||
|  | 			return nil | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		cfg.AddKey("VALIDATED_KEY", "valid", false, validator) | ||||||
|  | 		os.Setenv("VALIDATED_KEY", "invalid") | ||||||
|  | 		defer os.Unsetenv("VALIDATED_KEY") | ||||||
|  | 
 | ||||||
|  | 		value, err := cfg.GetValue("VALIDATED_KEY") | ||||||
|  | 		t.Logf("Got value: %q, error: %v", value, err) | ||||||
|  | 		if err == nil { | ||||||
|  | 			t.Error("expected validation error, got nil") | ||||||
|  | 		} | ||||||
|  | 	}) | ||||||
|  | } | ||||||
							
								
								
									
										96
									
								
								config/reporter.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										96
									
								
								config/reporter.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,96 @@ | |||||||
|  | //go:build configreport
 | ||||||
|  | 
 | ||||||
|  | package config | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"fmt" | ||||||
|  | 
 | ||||||
|  | 	"git.defalsify.org/vise.git/logging" | ||||||
|  | 	"git.grassecon.net/grassrootseconomics/visedriver/env" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // ConfigValue represents a configuration key-value pair
 | ||||||
|  | type ConfigValue struct { | ||||||
|  | 	Key       string | ||||||
|  | 	Default   string | ||||||
|  | 	Validator func(string) error | ||||||
|  | 	Sensitive bool | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Config handles configuration management and reporting
 | ||||||
|  | type Config struct { | ||||||
|  | 	values map[string]ConfigValue | ||||||
|  | 	logger logging.Vanilla | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func NewConfig(logger logging.Vanilla) *Config { | ||||||
|  | 	return &Config{ | ||||||
|  | 		values: make(map[string]ConfigValue), | ||||||
|  | 		logger: logger, | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // AddKey registers a new configuration key with optional validation
 | ||||||
|  | func (c *Config) AddKey(key string, defaultValue string, sensitive bool, validator func(string) error) { | ||||||
|  | 	c.values[key] = ConfigValue{ | ||||||
|  | 		Key:       key, | ||||||
|  | 		Default:   defaultValue, | ||||||
|  | 		Validator: validator, | ||||||
|  | 		Sensitive: sensitive, | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // GetValue returns the value for a given key, applying environment override if present
 | ||||||
|  | func (c *Config) GetValue(key string) (string, error) { | ||||||
|  | 	// Find config value by key
 | ||||||
|  | 	var cv ConfigValue | ||||||
|  | 	for _, v := range c.values { | ||||||
|  | 		if v.Key == key { | ||||||
|  | 			cv = v | ||||||
|  | 			break | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if cv.Key == "" { | ||||||
|  | 		return "", fmt.Errorf("configuration key not found: %s", key) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// Get value from environment or default
 | ||||||
|  | 	value := env.GetEnv(key, cv.Default) | ||||||
|  | 
 | ||||||
|  | 	// Validate if validator exists
 | ||||||
|  | 	if cv.Validator != nil && cv.Validator(value) != nil { | ||||||
|  | 		return "", fmt.Errorf("invalid value for key %s", key) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return value, nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Report outputs all configuration values at the specified log level
 | ||||||
|  | func (c *Config) Report(level string) { | ||||||
|  | 	c.logger.Debugf("Configuration Report:") | ||||||
|  | 	for _, cv := range c.values { | ||||||
|  | 		value, err := c.GetValue(cv.Key) | ||||||
|  | 		if err != nil { | ||||||
|  | 			c.logger.Errorf("Error getting value for %s: %v", cv.Key, err) | ||||||
|  | 			continue | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		if cv.Sensitive { | ||||||
|  | 			value = "****" | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		switch level { | ||||||
|  | 		case "DEBUG": | ||||||
|  | 			c.logger.Debugf("%s: %s", cv.Key, value) | ||||||
|  | |||||||
|  | 		case "INFO": | ||||||
|  | 			c.logger.Infof("%s: %s", cv.Key, value) | ||||||
|  | 		case "WARN": | ||||||
|  | 			c.logger.Warnf("%s: %s", cv.Key, value) | ||||||
|  | 		case "ERROR": | ||||||
|  | 			c.logger.Errorf("%s: %s", cv.Key, value) | ||||||
|  | 		default: | ||||||
|  | 			c.logger.Infof("%s: %s", cv.Key, value) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
							
								
								
									
										21
									
								
								config/reporter_noop.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								config/reporter_noop.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,21 @@ | |||||||
|  | //go:build !configreport
 | ||||||
|  | 
 | ||||||
|  | package config | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  |     "git.defalsify.org/vise.git/logging" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | type Config struct{} | ||||||
|  | 
 | ||||||
|  | func NewConfig(logger logging.Vanilla) *Config { | ||||||
|  |     return &Config{} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (c *Config) AddKey(key string, defaultValue string, sensitive bool, validator func(string) error) {} | ||||||
|  | 
 | ||||||
|  | func (c *Config) GetValue(key string) (string, error) { | ||||||
|  |     return "", nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (c *Config) Report(level string) {}  | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	
Debugf is not printf, you probably want something like
c.logger.Debugf("config set", cv.Key, value)