diff --git a/resources/virt.go b/resources/virt.go index eeb9cffd..87a474f3 100644 --- a/resources/virt.go +++ b/resources/virt.go @@ -25,6 +25,7 @@ import ( "net/url" "os/user" "path" + "regexp" "strings" "sync" "time" @@ -1168,15 +1169,29 @@ func isNotFound(err error) bool { return false // some other error } -// expandHome does a simple expansion of the tilde into your $HOME value. +// expandHome does an expansion of ~/ or ~james/ into user's home dir value. func expandHome(p string) (string, error) { - // TODO: this doesn't match strings of the form: ~james/... - if !strings.HasPrefix(p, "~/") { - return p, nil + if strings.HasPrefix(p, "~/") { + usr, err := user.Current() + if err != nil { + return p, fmt.Errorf("can't expand ~ into home directory") + } + return path.Join(usr.HomeDir, p[len("~/"):]), nil } - usr, err := user.Current() + + // check if provided path is in format ~username and keep track of provided username + r, err := regexp.Compile("~([^/]+)/") if err != nil { - return p, fmt.Errorf("can't expand ~ into home directory") + return p, errwrap.Wrapf(err, "can't compile regexp") } - return path.Join(usr.HomeDir, p[len("~/"):]), nil + if match := r.FindStringSubmatch(p); match != nil { + username := match[len(match)-1] + usr, err := user.Lookup(username) + if err != nil { + return p, fmt.Errorf("can't expand %s into home directory", match[0]) + } + return path.Join(usr.HomeDir, p[len(match[0]):]), nil + } + + return p, nil } diff --git a/resources/virt_test.go b/resources/virt_test.go new file mode 100644 index 00000000..2dac409f --- /dev/null +++ b/resources/virt_test.go @@ -0,0 +1,48 @@ +// Mgmt +// Copyright (C) 2013-2017+ James Shubin and the project contributors +// Written by James Shubin and the project contributors +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package resources + +import ( + "os/user" + "testing" +) + +func TestExpandHome(t *testing.T) { + usr, _ := user.Current() + var expandHomeTests = []struct { + path string + expanded string + }{ + {"/some/random/path", "/some/random/path"}, + {"~/", usr.HomeDir}, + {"~/some/path", usr.HomeDir + "/some/path"}, + {"~" + usr.Username + "/", usr.HomeDir}, + {"~" + usr.Username + "/some/path", usr.HomeDir + "/some/path"}, + } + + for _, test := range expandHomeTests { + actual, err := expandHome(test.path) + if err != nil { + t.Error(err) + } + + if actual != test.expanded { + t.Errorf("expandHome(%s): expected %s, actual %s", test.path, test.expanded, actual) + } + } +}