Skip to content

Commit

Permalink
Treat XDG_CONFIG_HOME and $HOME/.config the same way
Browse files Browse the repository at this point in the history
Currently we handle XDG_CONFIG_HOME and the fallback $HOME/.config
differently. We create the later if it does not exist and verify that
it is owned by the current user. This patch makes XDG_CONFIG_HOME
follow the same pattern.

Also Deprecate all GetDATA() functions and just use DATA().

Signed-off-by: Daniel J Walsh <[email protected]>
  • Loading branch information
rhatdan committed Sep 5, 2024
1 parent 9f9e76b commit 0285387
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 36 deletions.
32 changes: 26 additions & 6 deletions pkg/homedir/homedir.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,16 @@ import (
"path/filepath"
)

// GetDataHome returns XDG_DATA_HOME.
// GetDataHome returns $HOME/.local/share and nil error if XDG_DATA_HOME is not set.
// DataHome (deprecated)
func GetDataHome() (string, error) {
return DataHome()
}

// DataHome returns XDG_DATA_HOME.
// DataHome returns $HOME/.local/share and nil error if XDG_DATA_HOME is not set.
//
// See also https://standards.freedesktop.org/basedir-spec/latest/ar01s03.html
func GetDataHome() (string, error) {
func DataHome() (string, error) {
if xdgDataHome := os.Getenv("XDG_DATA_HOME"); xdgDataHome != "" {
return xdgDataHome, nil
}
Expand All @@ -21,11 +26,16 @@ func GetDataHome() (string, error) {
return filepath.Join(home, ".local", "share"), nil
}

// GetCacheHome returns XDG_CACHE_HOME.
// GetCacheHome returns $HOME/.cache and nil error if XDG_CACHE_HOME is not set.
// GetCacheHome (deprecated)
func GetCacheHome() (string, error) {
return CacheHome()
}

// CacheHome returns XDG_CACHE_HOME.
// CacheHome returns $HOME/.cache and nil error if XDG_CACHE_HOME is not set.
//
// See also https://standards.freedesktop.org/basedir-spec/latest/ar01s03.html
func GetCacheHome() (string, error) {
func CacheHome() (string, error) {
if xdgCacheHome := os.Getenv("XDG_CACHE_HOME"); xdgCacheHome != "" {
return xdgCacheHome, nil
}
Expand All @@ -35,3 +45,13 @@ func GetCacheHome() (string, error) {
}
return filepath.Join(home, ".cache"), nil
}

// GetRuntimeDir (deprecated)
func GetRuntimeDir() (string, error) {
return RuntimeDir()
}

// GetShortcutString (deprecated)
func GetShortcutString() string {
return ShortcutString()
}
50 changes: 28 additions & 22 deletions pkg/homedir/homedir_unix.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,9 @@ func Get() string {
return homedir
}

// GetShortcutString returns the string that is shortcut to user's home directory
// ShortcutString returns the string that is shortcut to user's home directory
// in the native shell of the platform running on.
func GetShortcutString() string {
func ShortcutString() string {
return "~"
}

Expand All @@ -52,7 +52,7 @@ func GetShortcutString() string {
//
// See also https://standards.freedesktop.org/basedir-spec/latest/ar01s03.html
func StickRuntimeDirContents(files []string) ([]string, error) {
runtimeDir, err := GetRuntimeDir()
runtimeDir, err := RuntimeDir()
if err != nil {
// ignore error if runtimeDir is empty
return nil, nil //nolint: nilerr
Expand Down Expand Up @@ -101,11 +101,20 @@ func isWriteableOnlyByOwner(perm os.FileMode) bool {
return (perm & 0o722) == 0o700
}

// GetConfigHome returns XDG_CONFIG_HOME.
// GetConfigHome returns $HOME/.config and nil error if XDG_CONFIG_HOME is not set.
//
// See also https://standards.freedesktop.org/basedir-spec/latest/ar01s03.html
// GetConfigHome deprecated
func GetConfigHome() (string, error) {
rootlessConfigHomeDir, rootlessConfigHomeDirError = ConfigHome()
if rootlessConfigHomeDirError == nil {
_ = os.MkdirAll(rootlessConfigHomeDir, 0o700)
}

return rootlessConfigHomeDir, rootlessConfigHomeDirError
}

// ConfigHome returns XDG_CONFIG_HOME. (Deprecated)
// ConfigHome returns $HOME/.config and nil error if XDG_CONFIG_HOME is not set.
// See also https://standards.freedesktop.org/basedir-spec/latest/ar01s03.html
func ConfigHome() (string, error) {
rootlessConfigHomeDirOnce.Do(func() {
cfgHomeDir := os.Getenv("XDG_CONFIG_HOME")
if cfgHomeDir == "" {
Expand All @@ -115,33 +124,30 @@ func GetConfigHome() (string, error) {
rootlessConfigHomeDirError = fmt.Errorf("cannot resolve %s: %w", home, err)
return
}
tmpDir := filepath.Join(resolvedHome, ".config")
_ = os.MkdirAll(tmpDir, 0o700)
st, err := os.Stat(tmpDir)
if err != nil {
rootlessConfigHomeDirError = err
return
} else if int(st.Sys().(*syscall.Stat_t).Uid) == os.Geteuid() {
cfgHomeDir = tmpDir
} else {
rootlessConfigHomeDirError = fmt.Errorf("path %q exists and it is not owned by the current user", tmpDir)
return
}
cfgHomeDir = filepath.Join(resolvedHome, ".config")
}
st, err := os.Stat(cfgHomeDir)
if err != nil {
rootlessConfigHomeDirError = err
return
} else if int(st.Sys().(*syscall.Stat_t).Uid) != os.Geteuid() {
rootlessConfigHomeDirError = fmt.Errorf("path %q exists and it is not owned by the current user", tmpDir)
return
}
rootlessConfigHomeDir = cfgHomeDir
})

return rootlessConfigHomeDir, rootlessConfigHomeDirError
}

// GetRuntimeDir returns a directory suitable to store runtime files.
// RuntimeDir returns a directory suitable to store runtime files.
// The function will try to use the XDG_RUNTIME_DIR env variable if it is set.
// XDG_RUNTIME_DIR is typically configured via pam_systemd.
// If XDG_RUNTIME_DIR is not set, GetRuntimeDir will try to find a suitable
// If XDG_RUNTIME_DIR is not set, RuntimeDir will try to find a suitable
// directory for the current user.
//
// See also https://standards.freedesktop.org/basedir-spec/latest/ar01s03.html
func GetRuntimeDir() (string, error) {
func RuntimeDir() (string, error) {
var rootlessRuntimeDirError error

rootlessRuntimeDirOnce.Do(func() {
Expand Down
21 changes: 13 additions & 8 deletions pkg/homedir/homedir_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,21 @@ func Get() string {
return home
}

// GetConfigHome returns the home directory of the current user with the help of
// GetConfigHome (deprecated)
func GetConfigHome() (string, error) {
return ConfigHome()
}

// ConfigHome returns the home directory of the current user with the help of
// environment variables depending on the target operating system.
// Returned path should be used with "path/filepath" to form new paths.
func GetConfigHome() (string, error) {
func ConfigHome() (string, error) {
return filepath.Join(Get(), ".config"), nil
}

// GetShortcutString returns the string that is shortcut to user's home directory
// ShortcutString returns the string that is shortcut to user's home directory
// in the native shell of the platform running on.
func GetShortcutString() string {
func ShortcutString() string {
return "%USERPROFILE%" // be careful while using in format functions
}

Expand All @@ -44,15 +49,15 @@ func StickRuntimeDirContents(files []string) ([]string, error) {
return nil, nil
}

// GetRuntimeDir returns a directory suitable to store runtime files.
// RuntimeDir returns a directory suitable to store runtime files.
// The function will try to use the XDG_RUNTIME_DIR env variable if it is set.
// XDG_RUNTIME_DIR is typically configured via pam_systemd.
// If XDG_RUNTIME_DIR is not set, GetRuntimeDir will try to find a suitable
// If XDG_RUNTIME_DIR is not set, RuntimeDir will try to find a suitable
// directory for the current user.
//
// See also https://standards.freedesktop.org/basedir-spec/latest/ar01s03.html
func GetRuntimeDir() (string, error) {
data, err := GetDataHome()
func RuntimeDir() (string, error) {
data, err := DataHome()
if err != nil {
return "", err
}
Expand Down

0 comments on commit 0285387

Please sign in to comment.