mitchellh/go-homedir

Respect Windows directory locations.

MicahZoltu opened this issue · 1 comments

go-homedir/homedir.go

Lines 148 to 167 in af06845

func dirWindows() (string, error) {
// First prefer the HOME environmental variable
if home := os.Getenv("HOME"); home != "" {
return home, nil
}
// Prefer standard environment variable USERPROFILE
if home := os.Getenv("USERPROFILE"); home != "" {
return home, nil
}
drive := os.Getenv("HOMEDRIVE")
path := os.Getenv("HOMEPATH")
home := drive + path
if drive == "" || path == "" {
return "", errors.New("HOMEDRIVE, HOMEPATH, or USERPROFILE are blank")
}
return home, nil
}

TL;DR, change code to

func dirWindows() (string, error) {
	home := os.Getenv("LOCALAPPDATA")
 	if home == "" {
		return "", errors.New("LOCALAPPDATA environment variable is missing or empty")
	}
	return home, nil
}

$HOME is non-standard on Windows, and likely references $USERPROFILE. $USERPROFILE is not meant to be a location that applications store files other than via a save dialog box or similar situation where the user is explicitly putting files there. The proper location to store data that should be automatically synced to a network or uploaded to the cloud is $APPDATA. For data that should be machine-local (e.g., caches, application data, etc.) it should be stored in $LOCALAPPDATA.

In this library, it doesn't appear that you distinguish between data types so $LOCALAPPDATA is the best location. If someone throws a cache in there you don't break the user's profile.

Note: $LOCALAPPDATA has been around since Windows XP/2003 while the fallback you were using of $HOMEDRIVE I think has been deprecated and $HOMEPATH is fairly new (and I think also deprecated), so this is not only more correct, but also more backward compatible than the code currently present.