pkg/tui/config.go 1.3 K raw
1
package tui
2
3
import (
4
	"os"
5
	"path/filepath"
6
7
	"github.com/BurntSushi/toml"
8
)
9
10
// Config is the on-disk TUI config shape shared across apps.
11
type Config struct {
12
	RemoteURL string `toml:"remote_url"`
13
	APIKey    string `toml:"api_key"`
14
}
15
16
// ConfigPath returns $XDG_CONFIG_HOME/<app>/config.toml.
17
func ConfigPath(app string) (string, error) {
18
	dir, err := os.UserConfigDir()
19
	if err != nil {
20
		return "", err
21
	}
22
	return filepath.Join(dir, app, "config.toml"), nil
23
}
24
25
// LoadConfig reads the named app's config. Missing file returns a zero Config.
26
func LoadConfig(app string) (Config, error) {
27
	var cfg Config
28
	path, err := ConfigPath(app)
29
	if err != nil {
30
		return cfg, err
31
	}
32
	data, err := os.ReadFile(path)
33
	if err != nil {
34
		if os.IsNotExist(err) {
35
			return cfg, nil
36
		}
37
		return cfg, err
38
	}
39
	if err := toml.Unmarshal(data, &cfg); err != nil {
40
		return cfg, err
41
	}
42
	return cfg, nil
43
}
44
45
// SaveConfig writes cfg as TOML, creating parent dirs as needed.
46
func SaveConfig(app string, cfg Config) error {
47
	path, err := ConfigPath(app)
48
	if err != nil {
49
		return err
50
	}
51
	if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil {
52
		return err
53
	}
54
	f, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0o600)
55
	if err != nil {
56
		return err
57
	}
58
	defer f.Close()
59
	return toml.NewEncoder(f).Encode(cfg)
60
}