xdg.go raw

   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