1 package xdg
2 3 import (
4 "github.com/adrg/xdg/internal/pathutil"
5 "github.com/adrg/xdg/internal/userdirs"
6 )
7 8 // UserDirectories defines the locations of well known user directories.
9 type UserDirectories = userdirs.Directories
10 11 var (
12 // Home contains the path of the user's home directory.
13 Home string
14 15 // DataHome defines the base directory relative to which user-specific
16 // data files should be stored. This directory is defined by the
17 // $XDG_DATA_HOME environment variable. If the variable is not set,
18 // a default equal to $HOME/.local/share should be used.
19 DataHome string
20 21 // DataDirs defines the preference-ordered set of base directories to
22 // search for data files in addition to the DataHome base directory.
23 // This set of directories is defined by the $XDG_DATA_DIRS environment
24 // variable. If the variable is not set, the default directories
25 // to be used are /usr/local/share and /usr/share, in that order. The
26 // DataHome directory is considered more important than any of the
27 // directories defined by DataDirs. Therefore, user data files should be
28 // written relative to the DataHome directory, if possible.
29 DataDirs []string
30 31 // ConfigHome defines the base directory relative to which user-specific
32 // configuration files should be written. This directory is defined by
33 // the $XDG_CONFIG_HOME environment variable. If the variable is
34 // not set, a default equal to $HOME/.config should be used.
35 ConfigHome string
36 37 // ConfigDirs defines the preference-ordered set of base directories to
38 // search for configuration files in addition to the ConfigHome base
39 // directory. This set of directories is defined by the $XDG_CONFIG_DIRS
40 // environment variable. If the variable is not set, a default equal
41 // to /etc/xdg should be used. The ConfigHome directory is considered
42 // more important than any of the directories defined by ConfigDirs.
43 // Therefore, user config files should be written relative to the
44 // ConfigHome directory, if possible.
45 ConfigDirs []string
46 47 // StateHome defines the base directory relative to which user-specific
48 // state files should be stored. This directory is defined by the
49 // $XDG_STATE_HOME environment variable. If the variable is not set,
50 // a default equal to ~/.local/state should be used.
51 StateHome string
52 53 // CacheHome defines the base directory relative to which user-specific
54 // non-essential (cached) data should be written. This directory is
55 // defined by the $XDG_CACHE_HOME environment variable. If the variable
56 // is not set, a default equal to $HOME/.cache should be used.
57 CacheHome string
58 59 // RuntimeDir defines the base directory relative to which user-specific
60 // non-essential runtime files and other file objects (such as sockets,
61 // named pipes, etc.) should be stored. This directory is defined by the
62 // $XDG_RUNTIME_DIR environment variable. If the variable is not set,
63 // applications should fall back to a replacement directory with similar
64 // capabilities. Applications should use this directory for communication
65 // and synchronization purposes and should not place larger files in it,
66 // since it might reside in runtime memory and cannot necessarily be
67 // swapped out to disk.
68 RuntimeDir string
69 70 // BinHome defines the base directory relative to which user-specific
71 // binary files should be written. This directory is defined by
72 // the non-standard $XDG_BIN_HOME environment variable. If the variable is
73 // not set, a default equal to $HOME/.local/bin should be used.
74 BinHome string
75 76 // UserDirs defines the locations of well known user directories.
77 UserDirs UserDirectories
78 79 // FontDirs defines the common locations where font files are stored.
80 FontDirs []string
81 82 // ApplicationDirs defines the common locations of applications.
83 ApplicationDirs []string
84 85 // baseDirs defines the locations of base directories.
86 baseDirs baseDirectories
87 )
88 89 func init() {
90 Reload()
91 }
92 93 // Reload refreshes base and user directories by reading the environment.
94 // Defaults are applied for XDG variables which are empty or not present
95 // in the environment.
96 func Reload() {
97 // Initialize home directory.
98 Home = pathutil.UserHomeDir()
99 100 // Initialize base and user directories.
101 initDirs(Home)
102 103 // Set standard directories.
104 DataHome = baseDirs.dataHome
105 DataDirs = baseDirs.data
106 ConfigHome = baseDirs.configHome
107 ConfigDirs = baseDirs.config
108 StateHome = baseDirs.stateHome
109 CacheHome = baseDirs.cacheHome
110 RuntimeDir = baseDirs.runtime
111 112 // Set non-standard directories.
113 BinHome = baseDirs.binHome
114 FontDirs = baseDirs.fonts
115 ApplicationDirs = baseDirs.applications
116 }
117 118 // DataFile returns a suitable location for the specified data file.
119 // The relPath parameter must contain the name of the data file, and
120 // optionally, a set of parent directories (e.g. appname/app.data).
121 // If the specified directories do not exist, they will be created relative
122 // to the base data directory. On failure, an error containing the
123 // attempted paths is returned.
124 func DataFile(relPath string) (string, error) {
125 return baseDirs.dataFile(relPath)
126 }
127 128 // ConfigFile returns a suitable location for the specified config file.
129 // The relPath parameter must contain the name of the config file, and
130 // optionally, a set of parent directories (e.g. appname/app.yaml).
131 // If the specified directories do not exist, they will be created relative
132 // to the base config directory. On failure, an error containing the
133 // attempted paths is returned.
134 func ConfigFile(relPath string) (string, error) {
135 return baseDirs.configFile(relPath)
136 }
137 138 // StateFile returns a suitable location for the specified state file. State
139 // files are usually volatile data files, not suitable to be stored relative
140 // to the $XDG_DATA_HOME directory.
141 // The relPath parameter must contain the name of the state file, and
142 // optionally, a set of parent directories (e.g. appname/app.state).
143 // If the specified directories do not exist, they will be created relative
144 // to the base state directory. On failure, an error containing the
145 // attempted paths is returned.
146 func StateFile(relPath string) (string, error) {
147 return baseDirs.stateFile(relPath)
148 }
149 150 // CacheFile returns a suitable location for the specified cache file.
151 // The relPath parameter must contain the name of the cache file, and
152 // optionally, a set of parent directories (e.g. appname/app.cache).
153 // If the specified directories do not exist, they will be created relative
154 // to the base cache directory. On failure, an error containing the
155 // attempted paths is returned.
156 func CacheFile(relPath string) (string, error) {
157 return baseDirs.cacheFile(relPath)
158 }
159 160 // RuntimeFile returns a suitable location for the specified runtime file.
161 // The relPath parameter must contain the name of the runtime file, and
162 // optionally, a set of parent directories (e.g. appname/app.pid).
163 // If the specified directories do not exist, they will be created relative
164 // to the base runtime directory. If the base runtime directory does not exist,
165 // the operating system's temporary directory is used as a fallback. On failure,
166 // an error containing the attempted paths is returned.
167 func RuntimeFile(relPath string) (string, error) {
168 return baseDirs.runtimeFile(relPath)
169 }
170 171 // SearchDataFile searches for specified file in the data search paths.
172 // The relPath parameter must contain the name of the data file, and
173 // optionally, a set of parent directories (e.g. appname/app.data). If the
174 // file cannot be found, an error specifying the searched paths is returned.
175 func SearchDataFile(relPath string) (string, error) {
176 return baseDirs.searchDataFile(relPath)
177 }
178 179 // SearchConfigFile searches for the specified file in config search paths.
180 // The relPath parameter must contain the name of the config file, and
181 // optionally, a set of parent directories (e.g. appname/app.yaml). If the
182 // file cannot be found, an error specifying the searched paths is returned.
183 func SearchConfigFile(relPath string) (string, error) {
184 return baseDirs.searchConfigFile(relPath)
185 }
186 187 // SearchStateFile searches for the specified file in the state search path.
188 // The relPath parameter must contain the name of the state file, and
189 // optionally, a set of parent directories (e.g. appname/app.state). If the
190 // file cannot be found, an error specifying the searched path is returned.
191 func SearchStateFile(relPath string) (string, error) {
192 return baseDirs.searchStateFile(relPath)
193 }
194 195 // SearchCacheFile searches for the specified file in the cache search path.
196 // The relPath parameter must contain the name of the cache file, and
197 // optionally, a set of parent directories (e.g. appname/app.cache). If the
198 // file cannot be found, an error specifying the searched path is returned.
199 func SearchCacheFile(relPath string) (string, error) {
200 return baseDirs.searchCacheFile(relPath)
201 }
202 203 // SearchRuntimeFile searches for the specified file in the runtime search path.
204 // The relPath parameter must contain the name of the runtime file, and
205 // optionally, a set of parent directories (e.g. appname/app.pid). The runtime
206 // file is also searched in the operating system's temporary directory in order
207 // to cover cases in which the runtime base directory does not exist or is not
208 // accessible. If the file cannot be found, an error specifying the searched
209 // paths is returned.
210 func SearchRuntimeFile(relPath string) (string, error) {
211 return baseDirs.searchRuntimeFile(relPath)
212 }
213