Lookup actual home directory when expanding ~.

This fixes home directory expansion on Windows and OS X.  Previously
on these platforms, a leading ~ would expand to %LOCALAPPDATA% on
Windows or ~/Library/Application Support/ on OS X.

While here, add support for ~otheruser expansion to expand to
otheruser's home directory.
This commit is contained in:
Josh Rickmar 2016-04-13 18:51:01 -04:00
parent 42593c7dfd
commit f91303f507

View file

@ -8,7 +8,9 @@ import (
"fmt" "fmt"
"net" "net"
"os" "os"
"os/user"
"path/filepath" "path/filepath"
"runtime"
"sort" "sort"
"strings" "strings"
@ -99,16 +101,50 @@ type config struct {
// cleanAndExpandPath expands environement variables and leading ~ in the // cleanAndExpandPath expands environement variables and leading ~ in the
// passed path, cleans the result, and returns it. // passed path, cleans the result, and returns it.
func cleanAndExpandPath(path string) string { func cleanAndExpandPath(path string) string {
// Expand initial ~ to OS specific home directory.
if strings.HasPrefix(path, "~") {
homeDir := filepath.Dir(defaultAppDataDir)
path = strings.Replace(path, "~", homeDir, 1)
}
// NOTE: The os.ExpandEnv doesn't work with Windows cmd.exe-style // NOTE: The os.ExpandEnv doesn't work with Windows cmd.exe-style
// %VARIABLE%, but they variables can still be expanded via POSIX-style // %VARIABLE%, but they variables can still be expanded via POSIX-style
// $VARIABLE. // $VARIABLE.
return filepath.Clean(os.ExpandEnv(path)) path = os.ExpandEnv(path)
if !strings.HasPrefix(path, "~") {
return filepath.Clean(path)
}
// Expand initial ~ to the current user's home directory, or ~otheruser
// to otheruser's home directory. On Windows, both forward and backward
// slashes can be used.
path = path[1:]
var pathSeparators string
if runtime.GOOS == "windows" {
pathSeparators = string(os.PathSeparator) + "/"
} else {
pathSeparators = string(os.PathSeparator)
}
userName := ""
if i := strings.IndexAny(path, pathSeparators); i != -1 {
userName = path[:i]
path = path[i:]
}
homeDir := ""
var u *user.User
var err error
if userName == "" {
u, err = user.Current()
} else {
u, err = user.Lookup(userName)
}
if err == nil {
homeDir = u.HomeDir
}
// Fallback to CWD if user lookup fails or user has no home directory.
if homeDir == "" {
homeDir = "."
}
return filepath.Join(homeDir, path)
} }
// validLogLevel returns whether or not logLevel is a valid debug log level. // validLogLevel returns whether or not logLevel is a valid debug log level.