1// Package config provides XDG Base Directory specification compliance utilities.
2package config
3
4import (
5 "os"
6 "path/filepath"
7)
8
9const appName = "dumber"
10
11// XDGDirs holds the XDG Base Directory paths for the application.
12type XDGDirs struct {
13 ConfigHome string
14 DataHome string
15 StateHome string
16}
17
18// GetXDGDirs returns the XDG Base Directory paths for dumber.
19// It follows the XDG Base Directory specification:
20// - $XDG_CONFIG_HOME/dumber (default: ~/.config/dumber)
21// - $XDG_DATA_HOME/dumber (default: ~/.local/share/dumber)
22// - $XDG_STATE_HOME/dumber (default: ~/.local/state/dumber)
23func GetXDGDirs() (*XDGDirs, error) {
24 homeDir, err := os.UserHomeDir()
25 if err != nil {
26 return nil, err
27 }
28
29 // XDG_CONFIG_HOME
30 configHome := os.Getenv("XDG_CONFIG_HOME")
31 if configHome == "" {
32 configHome = filepath.Join(homeDir, ".config")
33 }
34 configHome = filepath.Join(configHome, appName)
35
36 // XDG_DATA_HOME
37 dataHome := os.Getenv("XDG_DATA_HOME")
38 if dataHome == "" {
39 dataHome = filepath.Join(homeDir, ".local", "share")
40 }
41 dataHome = filepath.Join(dataHome, appName)
42
43 // XDG_STATE_HOME
44 stateHome := os.Getenv("XDG_STATE_HOME")
45 if stateHome == "" {
46 stateHome = filepath.Join(homeDir, ".local", "state")
47 }
48 stateHome = filepath.Join(stateHome, appName)
49
50 return &XDGDirs{
51 ConfigHome: configHome,
52 DataHome: dataHome,
53 StateHome: stateHome,
54 }, nil
55}
56
57// GetConfigDir returns the XDG config directory for dumber.
58func GetConfigDir() (string, error) {
59 dirs, err := GetXDGDirs()
60 if err != nil {
61 return "", err
62 }
63 return dirs.ConfigHome, nil
64}
65
66// GetDataDir returns the XDG data directory for dumber.
67func GetDataDir() (string, error) {
68 dirs, err := GetXDGDirs()
69 if err != nil {
70 return "", err
71 }
72 return dirs.DataHome, nil
73}
74
75// GetStateDir returns the XDG state directory for dumber.
76func GetStateDir() (string, error) {
77 dirs, err := GetXDGDirs()
78 if err != nil {
79 return "", err
80 }
81 return dirs.StateHome, nil
82}
83
84
85// GetConfigFile returns the path to the main configuration file.
86func GetConfigFile() (string, error) {
87 configDir, err := GetConfigDir()
88 if err != nil {
89 return "", err
90 }
91 return filepath.Join(configDir, "config.json"), nil
92}
93
94// GetDatabaseFile returns the path to the database file in the state directory.
95func GetDatabaseFile() (string, error) {
96 stateDir, err := GetStateDir()
97 if err != nil {
98 return "", err
99 }
100 return filepath.Join(stateDir, "history.db"), nil
101}
102
103// EnsureDirectories creates the XDG directories if they don't exist.
104func EnsureDirectories() error {
105 dirs, err := GetXDGDirs()
106 if err != nil {
107 return err
108 }
109
110 // Create all directories with proper permissions
111 directories := []string{
112 dirs.ConfigHome,
113 dirs.DataHome,
114 dirs.StateHome,
115 }
116
117 for _, dir := range directories {
118 if err := os.MkdirAll(dir, 0755); err != nil {
119 return err
120 }
121 }
122
123 return nil
124}