package main import ( "bufio" "encoding/json" "fmt" "os" "path/filepath" "strings" ) type Config struct { PorkbunAPIKey string `json:"porkbun_api_key"` PorkbunSecretKey string `json:"porkbun_secret_key"` Domain string `json:"domain"` CaddyAdminURL string `json:"caddy_admin_url"` CaddyfilePath string `json:"caddyfile_path"` } func configPath() (string, error) { home, err := os.UserHomeDir() if err != nil { return "", fmt.Errorf("getting home directory: %w", err) } return filepath.Join(home, ".config", "caddybun", "config.json"), nil } func LoadOrCreateConfig() (*Config, error) { path, err := configPath() if err != nil { return nil, err } cfg := &Config{ Domain: "torrtle.co", CaddyAdminURL: "http://localhost:2019", CaddyfilePath: "/etc/caddy/Caddyfile", } data, err := os.ReadFile(path) if err == nil { if err := json.Unmarshal(data, cfg); err != nil { return nil, fmt.Errorf("parsing config: %w", err) } return cfg, nil } if !os.IsNotExist(err) { return nil, fmt.Errorf("reading config: %w", err) } // First run — prompt for API keys fmt.Println("First run — let's configure caddybun.") fmt.Println() reader := bufio.NewReader(os.Stdin) fmt.Print("Porkbun API key: ") cfg.PorkbunAPIKey, _ = reader.ReadString('\n') cfg.PorkbunAPIKey = strings.TrimSpace(cfg.PorkbunAPIKey) fmt.Print("Porkbun Secret API key: ") cfg.PorkbunSecretKey, _ = reader.ReadString('\n') cfg.PorkbunSecretKey = strings.TrimSpace(cfg.PorkbunSecretKey) fmt.Printf("Domain [%s]: ", cfg.Domain) if d, _ := reader.ReadString('\n'); strings.TrimSpace(d) != "" { cfg.Domain = strings.TrimSpace(d) } fmt.Printf("Caddy admin URL [%s]: ", cfg.CaddyAdminURL) if u, _ := reader.ReadString('\n'); strings.TrimSpace(u) != "" { cfg.CaddyAdminURL = strings.TrimSpace(u) } fmt.Printf("Caddyfile path [%s]: ", cfg.CaddyfilePath) if p, _ := reader.ReadString('\n'); strings.TrimSpace(p) != "" { cfg.CaddyfilePath = strings.TrimSpace(p) } fmt.Println() if err := saveConfig(path, cfg); err != nil { return nil, err } fmt.Printf("Config saved to %s\n\n", path) return cfg, nil } func saveConfig(path string, cfg *Config) error { if err := os.MkdirAll(filepath.Dir(path), 0700); err != nil { return fmt.Errorf("creating config directory: %w", err) } data, err := json.MarshalIndent(cfg, "", " ") if err != nil { return fmt.Errorf("marshaling config: %w", err) } if err := os.WriteFile(path, data, 0600); err != nil { return fmt.Errorf("writing config: %w", err) } return nil }