1
// Copyright 2011 The Go Authors. All rights reserved.
2
// Use of this source code is governed by a BSD-style
3
// license that can be found in the LICENSE file.
19
defaultRoot *pkgroot // default root for remote packages
22
// set up gopath: parse and validate GOROOT and GOPATH variables
24
root := runtime.GOROOT()
25
p, err := newPkgroot(root)
27
log.Fatalf("Invalid GOROOT %q: %v", root, err)
30
gopath = []*pkgroot{p}
32
for _, p := range filepath.SplitList(os.Getenv("GOPATH")) {
36
r, err := newPkgroot(p)
38
log.Printf("Invalid GOPATH %q: %v", p, err)
41
gopath = append(gopath, r)
42
imports = append(imports, r.pkgDir())
44
// select first GOPATH entry as default
45
if defaultRoot == nil {
50
// use GOROOT if no valid GOPATH specified
51
if defaultRoot == nil {
52
defaultRoot = gopath[0]
58
goroot bool // TODO(adg): remove this once Go tree re-organized
61
func newPkgroot(p string) (*pkgroot, os.Error) {
62
if !filepath.IsAbs(p) {
63
return nil, os.NewError("must be absolute")
65
ep, err := filepath.EvalSymlinks(p)
69
return &pkgroot{path: ep}, nil
72
func (r *pkgroot) srcDir() string {
74
return filepath.Join(r.path, "src", "pkg")
76
return filepath.Join(r.path, "src")
79
func (r *pkgroot) pkgDir() string {
80
goos, goarch := runtime.GOOS, runtime.GOARCH
81
if e := os.Getenv("GOOS"); e != "" {
84
if e := os.Getenv("GOARCH"); e != "" {
87
return filepath.Join(r.path, "pkg", goos+"_"+goarch)
90
func (r *pkgroot) binDir() string {
91
return filepath.Join(r.path, "bin")
94
func (r *pkgroot) hasSrcDir(name string) bool {
95
fi, err := os.Stat(filepath.Join(r.srcDir(), name))
99
return fi.IsDirectory()
102
func (r *pkgroot) hasPkg(name string) bool {
103
fi, err := os.Stat(filepath.Join(r.pkgDir(), name+".a"))
107
return fi.IsRegular()
108
// TODO(adg): check object version is consistent
112
var ErrPackageNotFound = os.NewError("package could not be found locally")
114
// findPackageRoot takes an import or filesystem path and returns the
115
// root where the package source should be and the package import path.
116
func findPackageRoot(path string) (root *pkgroot, pkg string, err os.Error) {
117
if isLocalPath(path) {
118
if path, err = filepath.Abs(path); err != nil {
121
for _, r := range gopath {
122
rpath := r.srcDir() + string(filepath.Separator)
123
if !strings.HasPrefix(path, rpath) {
127
pkg = path[len(rpath):]
130
err = fmt.Errorf("path %q not inside a GOPATH", path)
135
for _, r := range gopath {
136
if r.hasSrcDir(path) {
141
err = ErrPackageNotFound
145
// Is this a local path? /foo ./foo ../foo . ..
146
func isLocalPath(s string) bool {
147
const sep = string(filepath.Separator)
148
return strings.HasPrefix(s, sep) || strings.HasPrefix(s, "."+sep) || strings.HasPrefix(s, ".."+sep) || s == "." || s == ".."