package config import ( "os" "path/filepath" "github.com/spf13/viper" ) type Config struct { DefaultLimit int `json:"defaultLimit" mapstructure:"defaultLimit"` DBLocation string `json:"dbLocation" mapstructure:"dbLocation"` MaxEntrySize int `json:"maxEntrySize" mapstructure:"maxEntrySize"` } func DefaultConfig() *Config { homeDir, _ := os.UserHomeDir() return &Config{ DefaultLimit: 20, DBLocation: filepath.Join(homeDir, ".klp.db"), MaxEntrySize: 0, // 0 means unlimited } } func Load() (*Config, error) { homeDir, err := os.UserHomeDir() if err != nil { return nil, err } configDir := filepath.Join(homeDir, ".config", "klp") if err := os.MkdirAll(configDir, 0755); err != nil { return nil, err } viper.SetConfigName("config") viper.SetConfigType("json") viper.AddConfigPath(configDir) // Set defaults defaults := DefaultConfig() viper.SetDefault("defaultLimit", defaults.DefaultLimit) viper.SetDefault("dbLocation", defaults.DBLocation) viper.SetDefault("maxEntrySize", defaults.MaxEntrySize) if err := viper.ReadInConfig(); err != nil { if _, ok := err.(viper.ConfigFileNotFoundError); ok { // Config file not found, create with defaults configPath := filepath.Join(configDir, "config.json") if err := viper.SafeWriteConfigAs(configPath); err != nil { return nil, err } } else { return nil, err } } var cfg Config if err := viper.Unmarshal(&cfg); err != nil { return nil, err } // Expand ~ in db location cfg.DBLocation = expandPath(cfg.DBLocation) return &cfg, nil } func (c *Config) DBPath() string { return c.DBLocation } func expandPath(path string) string { if len(path) > 0 && path[0] == '~' { homeDir, err := os.UserHomeDir() if err != nil { return path } return filepath.Join(homeDir, path[1:]) } return path }