From e60a990d10ca1b6daca85dec962d25d3323f97d5 Mon Sep 17 00:00:00 2001 From: Sasha Koshka Date: Sat, 26 Nov 2022 20:52:30 -0500 Subject: [PATCH] Use XDG directories, and respect corresponding environment vars --- config/config.go | 55 +++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 50 insertions(+), 5 deletions(-) diff --git a/config/config.go b/config/config.go index 3147113..e2cbc47 100644 --- a/config/config.go +++ b/config/config.go @@ -8,6 +8,29 @@ import "strconv" import "image/color" import "path/filepath" + +// when making changes to this file, look at +// https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html + +// Error represents an error that can be returned by functions or methods in +// this module. +type Error int + +const ( + // ErrorIllegalName is thrown when an application name contains illegal + // characters such as a slash. + ErrorIllegalName Error = iota +) + +func (err Error) Error () (description string) { + switch err { + case ErrorIllegalName: + description = "name contains illegal characters" + } + + return +} + // Type represents the data type of a configuration parameter. type Type int @@ -41,9 +64,15 @@ type Config struct { Parameters map[string] any } -// Load loads and parses the files /etc//.conf and -// /.config//.conf. +// Load loads and parses the files /etc/xdg//.conf and +// /.config//.conf, unless the corresponding XDG environment +// variables are set - then it uses those. func (config *Config) Load (name string) (err error) { + if strings.ContainsAny(name, "/\\|:.%") { + err = ErrorIllegalName + return + } + if config.LegalParameters == nil { config.LegalParameters = make(map[string] Type) } @@ -51,12 +80,28 @@ func (config *Config) Load (name string) (err error) { if config.Parameters == nil { config.Parameters = make(map[string] any) } - - config.loadFile("/etc/" + name + "/" + name + ".conf") + var homeDirectory string homeDirectory, err = os.UserHomeDir() if err != nil { return } - config.loadFile(filepath.Join(homeDirectory, "/.config/" + name + "/" + name + ".conf")) + + configHome := os.Getenv("XDG_CONFIG_HOME") + if configHome == "" { + configHome = filepath.Join(homeDirectory, "/.config/") + } + + configDirsString := os.Getenv("XDG_CONFIG_DIRS") + if configDirsString == "" { + configDirsString = "/etc/xdg/" + } + + configDirs := strings.Split(configDirsString, ":") + configDirs = append(configDirs, configHome) + + for _, directory := range configDirs { + config.loadFile(filepath.Join(directory, name, name + ".conf")) + } + return }