package config import ( "fmt" "os" "path/filepath" "github.com/yourusername/buque/internal/models" "gopkg.in/yaml.v3" ) const ( DefaultConfigDir = ".buque" DefaultConfigFile = "config.yaml" ) // Manager handles configuration operations type Manager struct { configPath string config *models.Config } // NewManager creates a new configuration manager func NewManager(configPath string) *Manager { if configPath == "" { homeDir, _ := os.UserHomeDir() configPath = filepath.Join(homeDir, DefaultConfigDir, DefaultConfigFile) } return &Manager{ configPath: configPath, } } // Load loads the configuration from file func (m *Manager) Load() (*models.Config, error) { // Create config directory if it doesn't exist configDir := filepath.Dir(m.configPath) if err := os.MkdirAll(configDir, 0755); err != nil { return nil, fmt.Errorf("failed to create config directory: %w", err) } // Check if config file exists if _, err := os.Stat(m.configPath); os.IsNotExist(err) { // Create default configuration m.config = m.defaultConfig() if err := m.Save(); err != nil { return nil, fmt.Errorf("failed to save default config: %w", err) } return m.config, nil } // Read existing configuration data, err := os.ReadFile(m.configPath) if err != nil { return nil, fmt.Errorf("failed to read config file: %w", err) } var config models.Config if err := yaml.Unmarshal(data, &config); err != nil { return nil, fmt.Errorf("failed to parse config file: %w", err) } config.ConfigPath = m.configPath m.config = &config return m.config, nil } // Save saves the current configuration to file func (m *Manager) Save() error { if m.config == nil { return fmt.Errorf("no configuration to save") } data, err := yaml.Marshal(m.config) if err != nil { return fmt.Errorf("failed to marshal config: %w", err) } if err := os.WriteFile(m.configPath, data, 0644); err != nil { return fmt.Errorf("failed to write config file: %w", err) } return nil } // GetConfig returns the current configuration func (m *Manager) GetConfig() *models.Config { return m.config } // AddEnvironment adds a new environment to the configuration func (m *Manager) AddEnvironment(env models.Environment) error { if m.config == nil { return fmt.Errorf("configuration not loaded") } // Check if environment already exists for _, e := range m.config.Environments { if e.Name == env.Name { return fmt.Errorf("environment '%s' already exists", env.Name) } } m.config.Environments = append(m.config.Environments, env) return m.Save() } // RemoveEnvironment removes an environment from the configuration func (m *Manager) RemoveEnvironment(name string) error { if m.config == nil { return fmt.Errorf("configuration not loaded") } for i, env := range m.config.Environments { if env.Name == name { m.config.Environments = append(m.config.Environments[:i], m.config.Environments[i+1:]...) return m.Save() } } return fmt.Errorf("environment '%s' not found", name) } // UpdateEnvironment updates an existing environment func (m *Manager) UpdateEnvironment(env models.Environment) error { if m.config == nil { return fmt.Errorf("configuration not loaded") } for i, e := range m.config.Environments { if e.Name == env.Name { m.config.Environments[i] = env return m.Save() } } return fmt.Errorf("environment '%s' not found", env.Name) } // GetEnvironment retrieves an environment by name func (m *Manager) GetEnvironment(name string) (*models.Environment, error) { if m.config == nil { return nil, fmt.Errorf("configuration not loaded") } for _, env := range m.config.Environments { if env.Name == env.Name { return &env, nil } } return nil, fmt.Errorf("environment '%s' not found", name) } // defaultConfig returns a default configuration func (m *Manager) defaultConfig() *models.Config { return &models.Config{ ConfigPath: m.configPath, Environments: []models.Environment{}, NginxProxy: models.NginxProxyConfig{ Enabled: false, NetworkName: "nginx-proxy", ContainerName: "nginx-proxy", Path: filepath.Join(filepath.Dir(m.configPath), "nginx-proxy"), HTTPPort: 80, HTTPSPort: 443, SSLEnabled: true, }, Docker: models.DockerConfig{ ComposeVersion: "v2", }, } }