package config import ( "fmt" "os" "path/filepath" "time" "gopkg.in/yaml.v3" ) const ( ConfigVersion = "1" ConfigFile = ".gitlocal.yml" ) type Repo struct { Path string `yaml:"path"` ConvertedAt time.Time `yaml:"converted_at"` OriginalRemote string `yaml:"original_remote,omitempty"` OriginalBranch string `yaml:"original_branch,omitempty"` } type Config struct { Version string `yaml:"version"` Repos []Repo `yaml:"repos"` } // GetConfigPath returns the absolute path to the config file func GetConfigPath() (string, error) { home, err := os.UserHomeDir() if err != nil { return "", fmt.Errorf("failed to get home directory: %w", err) } return filepath.Join(home, ConfigFile), nil } // Load reads the config file or creates a new empty config if it doesn't exist func Load() (*Config, error) { configPath, err := GetConfigPath() if err != nil { return nil, err } // If config doesn't exist, return empty config if _, err := os.Stat(configPath); os.IsNotExist(err) { return &Config{ Version: ConfigVersion, Repos: []Repo{}, }, nil } data, err := os.ReadFile(configPath) if err != nil { return nil, fmt.Errorf("failed to read config file: %w", err) } var cfg Config if err := yaml.Unmarshal(data, &cfg); err != nil { return nil, fmt.Errorf("failed to parse config file: %w", err) } return &cfg, nil } // Save writes the config to disk func (c *Config) Save() error { configPath, err := GetConfigPath() if err != nil { return err } data, err := yaml.Marshal(c) if err != nil { return fmt.Errorf("failed to marshal config: %w", err) } if err := os.WriteFile(configPath, data, 0644); err != nil { return fmt.Errorf("failed to write config file: %w", err) } return nil } // AddRepo adds a new repo to the config func (c *Config) AddRepo(repo Repo) { // Remove existing entry if it exists c.RemoveRepo(repo.Path) c.Repos = append(c.Repos, repo) } // RemoveRepo removes a repo from the config by path func (c *Config) RemoveRepo(path string) { filtered := []Repo{} for _, r := range c.Repos { if r.Path != path { filtered = append(filtered, r) } } c.Repos = filtered } // FindRepo returns a repo by path, or nil if not found func (c *Config) FindRepo(path string) *Repo { for _, r := range c.Repos { if r.Path == path { return &r } } return nil }