package homedir

import (
	
	
	
	
	
	
	
	
	
)
DisableCache will disable caching of the home directory. Caching is enabled by default.
Dir returns the home directory for the executing user. This uses an OS-specific method for discovering the home directory. An error is returned if a home directory cannot be detected.
func () (string, error) {
	if !DisableCache {
		cacheLock.RLock()
		 := homedirCache
		cacheLock.RUnlock()
		if  != "" {
			return , nil
		}
	}

	cacheLock.Lock()
	defer cacheLock.Unlock()

	var  string
	var  error
	if runtime.GOOS == "windows" {
		,  = dirWindows()
Unix-like system, so just assume Unix
		,  = dirUnix()
	}

	if  != nil {
		return "", 
	}
	homedirCache = 
	return , nil
}
Expand expands the path to include the home directory if the path is prefixed with `~`. If it isn't prefixed with `~`, the path is returned as-is.
func ( string) (string, error) {
	if len() == 0 {
		return , nil
	}

	if [0] != '~' {
		return , nil
	}

	if len() > 1 && [1] != '/' && [1] != '\\' {
		return "", errors.New("cannot expand user-specific home dir")
	}

	,  := Dir()
	if  != nil {
		return "", 
	}

	return filepath.Join(, [1:]), nil
}
Reset clears the cache, forcing the next call to Dir to re-detect the home directory. This generally never has to be called, but can be useful in tests if you're modifying the home directory via the HOME env var or something.
func () {
	cacheLock.Lock()
	defer cacheLock.Unlock()
	homedirCache = ""
}

func () (string, error) {
	 := "HOME"
On plan9, env vars are lowercase.
		 = "home"
	}
First prefer the HOME environmental variable
	if  := os.Getenv();  != "" {
		return , nil
	}

	var  bytes.Buffer
If that fails, try OS specific commands
	if runtime.GOOS == "darwin" {
		 := exec.Command("sh", "-c", `dscl -q . -read /Users/"$(whoami)" NFSHomeDirectory | sed 's/^[^ ]*: //'`)
		.Stdout = &
		if  := .Run();  == nil {
			 := strings.TrimSpace(.String())
			if  != "" {
				return , nil
			}
		}
	} else {
		 := exec.Command("getent", "passwd", strconv.Itoa(os.Getuid()))
		.Stdout = &
If the error is ErrNotFound, we ignore it. Otherwise, return it.
			if  != exec.ErrNotFound {
				return "", 
			}
		} else {
username:password:uid:gid:gecos:home:shell
				 := strings.SplitN(, ":", 7)
				if len() > 5 {
					return [5], nil
				}
			}
		}
	}
If all else fails, try the shell
	.Reset()
	 := exec.Command("sh", "-c", "cd && pwd")
	.Stdout = &
	if  := .Run();  != nil {
		return "", 
	}

	 := strings.TrimSpace(.String())
	if  == "" {
		return "", errors.New("blank output when reading home directory")
	}

	return , nil
}

First prefer the HOME environmental variable
	if  := os.Getenv("HOME");  != "" {
		return , nil
	}
Prefer standard environment variable USERPROFILE
	if  := os.Getenv("USERPROFILE");  != "" {
		return , nil
	}

	 := os.Getenv("HOMEDRIVE")
	 := os.Getenv("HOMEPATH")
	 :=  + 
	if  == "" ||  == "" {
		return "", errors.New("HOMEDRIVE, HOMEPATH, or USERPROFILE are blank")
	}

	return , nil