Files
gems/jade-depo/internal/engine/config.go
T
2026-01-01 21:46:20 +01:00

98 lines
2.7 KiB
Go

package engine
import (
"fmt"
"os"
"path/filepath"
"github.com/spf13/viper"
)
type Config struct {
// DepoPath is the path to the jade depository. Default ~/jade-depository
DepoPath string `mapstructure:"depo_path"`
// ConfigPath is the path to the config directory. Default ~/.config/jade/config.yml
ConfigPath string `mapstructure:"config_path"`
}
// getDefaultDepoPath returns the default depository path
func getDefaultDepoPath() string {
home, err := os.UserHomeDir()
if err != nil {
return "./jade-depository"
}
return filepath.Join(home, "jade-depository")
}
// getDefaultConfigPath returns the default config directory path
func getDefaultConfigPath() string {
home, err := os.UserHomeDir()
if err != nil {
return "./.config/jade/config.yml"
}
return filepath.Join(home, ".config", "jade", "config.yml")
}
// initConfig initializes the configuration using Viper
// Precedence order: flags > environment variables > config file > defaults
func initConfig(cfgPath, depoPath string) (*Config, error) {
// Set up environment variable support
viper.SetEnvPrefix("JADE")
viper.AutomaticEnv()
// Set defaults
viper.SetDefault("depo_path", getDefaultDepoPath())
viper.SetDefault("config_path", getDefaultConfigPath())
// Determine config file location
configDir := cfgPath
if configDir == "" {
configDir = getDefaultConfigPath()
}
// Ensure config directory exists
if err := os.MkdirAll(configDir, 0755); err != nil {
return nil, fmt.Errorf("failed to create config directory: %w", err)
}
// Set up config file
viper.SetConfigName("config")
viper.SetConfigType("yaml")
viper.AddConfigPath(configDir)
// Try to read existing config file
if err := viper.ReadInConfig(); err != nil {
if _, ok := err.(viper.ConfigFileNotFoundError); ok {
// Config file not found, create it with defaults
configFilePath := filepath.Join(configDir, "config.yaml")
if err := viper.SafeWriteConfigAs(configFilePath); err != nil {
return nil, fmt.Errorf("failed to create config file: %w", err)
}
} else {
// Config file was found but another error occurred
return nil, fmt.Errorf("error reading config file: %w", err)
}
}
// Override with flags if provided (highest precedence)
if depoPath != "" {
viper.Set("depo_path", depoPath)
}
if cfgPath != "" {
viper.Set("config_path", cfgPath)
}
// Unmarshal config into struct
cfg := &Config{}
if err := viper.Unmarshal(cfg); err != nil {
return nil, fmt.Errorf("failed to unmarshal config: %w", err)
}
// Write config back to persist any changes (e.g., from flags or env vars)
if err := viper.WriteConfig(); err != nil {
return nil, fmt.Errorf("failed to write config: %w", err)
}
return cfg, nil
}