checkin github.com/mitchellh/go-homedir"
Henry committed
Oct 15, 2014 at 12:27 UTC
320ac339bb2be194cb41d0c6e6ed363c06663138
5 files changed
+199
Godeps/Godeps.json
+4
@@ -92,6 +92,10 @@
92
"Comment": "0.1.0-5-g1976046",
93
"Rev": "1976046c2b0db0b668791b3e541d76a38b7c1af7"
94
},
95
+ {
96
+ "ImportPath": "github.com/mitchellh/go-homedir",
97
+ "Rev": "7d2d8c8a4e078ce3c58736ab521a40b37a504c52"
98
+ },
99
{
100
"ImportPath": "github.com/op/go-logging",
101
"Rev": "3df864a88c7f005e676db4f026a4fe2f14929be3"
Godeps/_workspace/src/github.com/mitchellh/go-homedir/LICENSE
new
+21
@@ -0,0 +1,21 @@
1
+The MIT License (MIT)
2
+
3
+Copyright (c) 2013 Mitchell Hashimoto
4
+
5
+Permission is hereby granted, free of charge, to any person obtaining a copy
6
+of this software and associated documentation files (the "Software"), to deal
7
+in the Software without restriction, including without limitation the rights
8
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+copies of the Software, and to permit persons to whom the Software is
10
+furnished to do so, subject to the following conditions:
11
+
12
+The above copyright notice and this permission notice shall be included in
13
+all copies or substantial portions of the Software.
14
+
15
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+THE SOFTWARE.
Godeps/_workspace/src/github.com/mitchellh/go-homedir/README.md
new
+14
@@ -0,0 +1,14 @@
1
+# go-homedir
2
+
3
+This is a Go library for detecting the user's home directory without
4
+the use of cgo, so the library can be used in cross-compilation environments.
5
+
6
+Usage is incredibly simple, just call `homedir.Dir()` to get the home directory
7
+for a user, and `homedir.Expand()` to expand the `~` in a path to the home
8
+directory.
9
+
10
+**Why not just use `os/user`?** The built-in `os/user` package requires
11
+cgo on Darwin systems. This means that any Go code that uses that package
12
+cannot cross compile. But 99% of the time the use for `os/user` is just to
13
+retrieve the home directory, which we can do for the current user without
14
+cgo. This library does that, enabling cross-compilation.
Godeps/_workspace/src/github.com/mitchellh/go-homedir/homedir.go
new
+83
@@ -0,0 +1,83 @@
1
+package homedir
2
+
3
+import (
4
+ "bytes"
5
+ "errors"
6
+ "os"
7
+ "os/exec"
8
+ "runtime"
9
+ "strings"
10
+)
11
+
12
+// Dir returns the home directory for the executing user.
13
+//
14
+// This uses an OS-specific method for discovering the home directory.
15
+// An error is returned if a home directory cannot be detected.
16
+func Dir() (string, error) {
17
+ if runtime.GOOS == "windows" {
18
+ return dirWindows()
19
+ }
20
+
21
+ // Unix-like system, so just assume Unix
22
+ return dirUnix()
23
+}
24
+
25
+// Expand expands the path to include the home directory if the path
26
+// is prefixed with `~`. If it isn't prefixed with `~`, the path is
27
+// returned as-is.
28
+func Expand(path string) (string, error) {
29
+ if len(path) == 0 {
30
+ return path, nil
31
+ }
32
+
33
+ if path[0] != '~' {
34
+ return path, nil
35
+ }
36
+
37
+ if len(path) > 1 && path[1] != '/' && path[1] != '\\' {
38
+ return "", errors.New("cannot expand user-specific home dir")
39
+ }
40
+
41
+ dir, err := Dir()
42
+ if err != nil {
43
+ return "", err
44
+ }
45
+
46
+ return dir + path[1:], nil
47
+}
48
+
49
+func dirUnix() (string, error) {
50
+ // First prefer the HOME environmental variable
51
+ if home := os.Getenv("HOME"); home != "" {
52
+ return home, nil
53
+ }
54
+
55
+ // If that fails, try the shell
56
+ var stdout bytes.Buffer
57
+ cmd := exec.Command("sh", "-c", "eval echo ~$USER")
58
+ cmd.Stdout = &stdout
59
+ if err := cmd.Run(); err != nil {
60
+ return "", err
61
+ }
62
+
63
+ result := strings.TrimSpace(stdout.String())
64
+ if result == "" {
65
+ return "", errors.New("blank output when reading home directory")
66
+ }
67
+
68
+ return result, nil
69
+}
70
+
71
+func dirWindows() (string, error) {
72
+ drive := os.Getenv("HOMEDRIVE")
73
+ path := os.Getenv("HOMEPATH")
74
+ home := drive + path
75
+ if drive == "" || path == "" {
76
+ home = os.Getenv("USERPROFILE")
77
+ }
78
+ if home == "" {
79
+ return "", errors.New("HOMEDRIVE, HOMEPATH, and USERPROFILE are blank")
80
+ }
81
+
82
+ return home, nil
83
+}
Godeps/_workspace/src/github.com/mitchellh/go-homedir/homedir_test.go
new
+77
@@ -0,0 +1,77 @@
1
+package homedir
2
+
3
+import (
4
+ "fmt"
5
+ "os/user"
6
+ "testing"
7
+)
8
+
9
+func TestDir(t *testing.T) {
10
+ u, err := user.Current()
11
+ if err != nil {
12
+ t.Fatalf("err: %s", err)
13
+ }
14
+
15
+ dir, err := Dir()
16
+ if err != nil {
17
+ t.Fatalf("err: %s", err)
18
+ }
19
+
20
+ if u.HomeDir != dir {
21
+ t.Fatalf("%#v != %#v", u.HomeDir, dir)
22
+ }
23
+}
24
+
25
+func TestExpand(t *testing.T) {
26
+ u, err := user.Current()
27
+ if err != nil {
28
+ t.Fatalf("err: %s", err)
29
+ }
30
+
31
+ cases := []struct {
32
+ Input string
33
+ Output string
34
+ Err bool
35
+ }{
36
+ {
37
+ "/foo",
38
+ "/foo",
39
+ false,
40
+ },
41
+
42
+ {
43
+ "~/foo",
44
+ fmt.Sprintf("%s/foo", u.HomeDir),
45
+ false,
46
+ },
47
+
48
+ {
49
+ "",
50
+ "",
51
+ false,
52
+ },
53
+
54
+ {
55
+ "~",
56
+ u.HomeDir,
57
+ false,
58
+ },
59
+
60
+ {
61
+ "~foo/foo",
62
+ "",
63
+ true,
64
+ },
65
+ }
66
+
67
+ for _, tc := range cases {
68
+ actual, err := Expand(tc.Input)
69
+ if (err != nil) != tc.Err {
70
+ t.Fatalf("Input: %#v\n\nErr: %s", tc.Input, err)
71
+ }
72
+
73
+ if actual != tc.Output {
74
+ t.Fatalf("Input: %#v\n\nOutput: %#v", tc.Input, actual)
75
+ }
76
+ }
77
+}