// Package config resolves and manages .hf-config.json relative to the binary directory. package config import ( "encoding/json" "fmt" "os" "path/filepath" ) const configFileName = ".hf-config.json" // Config holds the CLI configuration. type Config struct { BaseURL string `json:"base-url"` } // DefaultConfig returns a Config with sensible defaults. func DefaultConfig() Config { return Config{ BaseURL: "http://127.0.0.1:8000", } } // BinaryDir returns the directory containing the running binary. func BinaryDir() (string, error) { exe, err := os.Executable() if err != nil { return "", fmt.Errorf("cannot resolve binary path: %w", err) } exe, err = filepath.EvalSymlinks(exe) if err != nil { return "", fmt.Errorf("cannot resolve binary symlinks: %w", err) } return filepath.Dir(exe), nil } // ConfigPath returns the full path to the config file. func ConfigPath() (string, error) { dir, err := BinaryDir() if err != nil { return "", err } return filepath.Join(dir, configFileName), nil } // Load reads the config file. If the file does not exist, returns DefaultConfig. func Load() (Config, error) { p, err := ConfigPath() if err != nil { return DefaultConfig(), err } data, err := os.ReadFile(p) if err != nil { if os.IsNotExist(err) { return DefaultConfig(), nil } return DefaultConfig(), fmt.Errorf("cannot read config: %w", err) } var cfg Config if err := json.Unmarshal(data, &cfg); err != nil { return DefaultConfig(), fmt.Errorf("invalid config JSON: %w", err) } if cfg.BaseURL == "" { cfg.BaseURL = DefaultConfig().BaseURL } return cfg, nil } // Save writes the config to the config file path. func Save(cfg Config) error { p, err := ConfigPath() if err != nil { return err } data, err := json.MarshalIndent(cfg, "", " ") if err != nil { return fmt.Errorf("cannot marshal config: %w", err) } data = append(data, '\n') if err := os.WriteFile(p, data, 0644); err != nil { return fmt.Errorf("cannot write config: %w", err) } return nil } // UpdateURL loads the existing config, updates the base-url, and saves. func UpdateURL(url string) error { cfg, _ := Load() cfg.BaseURL = url return Save(cfg) }