1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
|
// Copyright 2013 Canonical Ltd.
// Licensed under the LGPLv3, see LICENCE file for details.
// Methods are copied from juju/utils to break a dependency loop
// See https://github.com/juju/cmd/issues/78
package cmd
import (
"fmt"
"os"
"os/user"
"path/filepath"
"regexp"
"github.com/juju/errors"
)
func homeDir(userName string) (string, error) {
u, err := user.Lookup(userName)
if err != nil {
return "", errors.NewUserNotFound(err, "no such user")
}
return u.HomeDir, nil
}
// userHomeDir returns the home directory for the specified user, or the
// home directory for the current user if the specified user is empty.
func userHomeDir(userName string) (hDir string, err error) {
if userName == "" {
// TODO (wallyworld) - fix tests on Windows
// Ordinarily, we'd always use user.Current() to get the current user
// and then get the HomeDir from that. But our tests rely on poking
// a value into $HOME in order to override the normal home dir for the
// current user. So we're forced to use Home() to make the tests pass.
// All of our tests currently construct paths with the default user in
// mind eg "~/foo".
return os.Getenv("HOME"), nil
}
hDir, err = homeDir(userName)
if err != nil {
return "", err
}
return hDir, nil
}
// Only match paths starting with ~ (~user/test, ~/test). This will prevent
// accidental expansion on Windows when short form paths are present (C:\users\ADMINI~1\test)
var userHomePathRegexp = regexp.MustCompile("(^~(?P<user>[^/]*))(?P<path>.*)")
// normalizePath expands a path containing ~ to its absolute form,
// and removes any .. or . path elements.
func normalizePath(dir string) (string, error) {
if userHomePathRegexp.MatchString(dir) {
user := userHomePathRegexp.ReplaceAllString(dir, "$user")
userHomeDirVar, err := userHomeDir(user)
if err != nil {
return "", err
}
dir = userHomePathRegexp.ReplaceAllString(dir, fmt.Sprintf("%s$path", userHomeDirVar))
}
return filepath.Clean(dir), nil
}
|