Skip to content

Commit

Permalink
On macOS, prefer XDG_CONFIG_HOME over os.UserConfigDir()
Browse files Browse the repository at this point in the history
Signed-off-by: Felix Fontein <felix@fontein.de>
  • Loading branch information
felixfontein committed Sep 21, 2023
1 parent ac7254d commit c22994d
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 4 deletions.
16 changes: 14 additions & 2 deletions age/keysource.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"io"
"os"
"path/filepath"
"runtime"
"strings"

"filippo.io/age"
Expand All @@ -23,8 +24,10 @@ const (
// age keys file.
SopsAgeKeyFileEnv = "SOPS_AGE_KEY_FILE"
// SopsAgeKeyUserConfigPath is the default age keys file path in
// os.UserConfigDir.
// getUserConfigDir().
SopsAgeKeyUserConfigPath = "sops/age/keys.txt"
// On macOS, os.UserConfigDir() ignores XDG_CONFIG_HOME. So we handle that manually.
xdgConfigHome = "XDG_CONFIG_HOME"
)

// log is the global logger for any age MasterKey.
Expand Down Expand Up @@ -222,6 +225,15 @@ func (key *MasterKey) ToMap() map[string]interface{} {
return out
}

func getUserConfigDir() (string, error) {
if runtime.GOOS == "darwin" {
if userConfigDir, ok := os.LookupEnv(xdgConfigHome); ok && userConfigDir != "" {
return userConfigDir, nil
}
}
return os.UserConfigDir()
}

// loadIdentities attempts to load the age identities based on runtime
// environment configurations (e.g. SopsAgeKeyEnv, SopsAgeKeyFileEnv,
// SopsAgeKeyUserConfigPath). It will load all found references, and expects
Expand All @@ -242,7 +254,7 @@ func (key *MasterKey) loadIdentities() (ParsedIdentities, error) {
readers[SopsAgeKeyFileEnv] = f
}

userConfigDir, err := os.UserConfigDir()
userConfigDir, err := getUserConfigDir()
if err != nil && len(readers) == 0 {
return nil, fmt.Errorf("user config directory could not be determined: %w", err)
}
Expand Down
16 changes: 14 additions & 2 deletions age/keysource_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -380,11 +380,23 @@ func overwriteUserConfigDir(t *testing.T, path string) {
switch runtime.GOOS {
case "windows":
t.Setenv("AppData", path)
case "darwin", "ios": // This adds "/Library/Application Support" as a suffix to $HOME
t.Setenv("HOME", path)
case "plan9": // This adds "/lib" as a suffix to $home
t.Setenv("home", path)
default: // Unix
t.Setenv("XDG_CONFIG_HOME", path)
}
}

// Make sure that on all supported platforms but Windows, XDG_CONFIG_HOME
// can be used to specify the user's home directory. For most platforms
// this is handled by Go's os.UserConfigDir(), but for Darwin our code
// in getUserConfigDir() handles this explicitly.
func TestUserConfigDir(t *testing.T) {
if runtime.GOOS != "windows" {
const dir = "/test/home/dir"
t.Setenv("XDG_CONFIG_HOME", dir)
home, err := getUserConfigDir()
assert.Nil(t, err)
assert.Equal(t, home, dir)
}
}

0 comments on commit c22994d

Please sign in to comment.