/
goman.go
75 lines (60 loc) · 1.53 KB
/
goman.go
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
63
64
65
66
67
68
69
70
71
72
73
74
75
//
// most of this file is from github.com/christophberger/goman
// see LICENSE.goman.go.txt
//
package gup
import (
"go/build"
"os"
"path/filepath"
"runtime"
"strings"
"github.com/bfontaine/which/which"
"github.com/pkg/errors"
)
// Copyright (c) 2017, Christoph Berger
// All rights reserved.
// getExecPath receives the name of an executable and determines its path
// based on $PATH, $GOPATH, or the current directory (in this order).
func getExecPath(name string) (string, error) {
// Try $PATH first.
s := which.One(name) // $ which <name>
if s != "" {
return s, nil
}
// Next, try $GOPATH/bin
paths := gopath()
for i := 0; s == "" && i < len(paths); i++ {
s = which.OneWithPath(name, paths[i]+filepath.Join("bin"))
}
if s != "" {
return s, nil
}
// Finally, try the current directory.
wd, err := os.Getwd()
if err != nil {
return "", errors.Wrap(err, "Unable to determine current directory")
}
s = which.OneWithPath(name, wd)
if s == "" {
return "", errors.New(name + " not found in any of " + os.Getenv("PATH") + ":" + strings.Join(paths, ":"))
}
return s, nil
}
// gopath returns a list of paths as defined by the GOPATH environment
// variable, or the default gopath if $GOPATH is empty.
func gopath() []string {
gp := os.Getenv("GOPATH")
if gp == "" {
return []string{build.Default.GOPATH}
}
return strings.Split(gp, pathssep())
}
// pathssep returns the separator between the paths of $PATH or %PATH%.
func pathssep() string {
sep := ":"
if runtime.GOOS == "windows" {
sep = ";"
}
return sep
}