diff options
Diffstat (limited to 'src/cmd/goinstall/path.go')
-rw-r--r-- | src/cmd/goinstall/path.go | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/src/cmd/goinstall/path.go b/src/cmd/goinstall/path.go new file mode 100644 index 000000000..1153e0471 --- /dev/null +++ b/src/cmd/goinstall/path.go @@ -0,0 +1,117 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +import ( + "log" + "os" + "path/filepath" + "runtime" +) + +var ( + gopath []*pkgroot + imports []string + defaultRoot *pkgroot // default root for remote packages +) + +// set up gopath: parse and validate GOROOT and GOPATH variables +func init() { + p, err := newPkgroot(root) + if err != nil { + log.Fatalf("Invalid GOROOT %q: %v", root, err) + } + p.goroot = true + gopath = []*pkgroot{p} + + for _, p := range filepath.SplitList(os.Getenv("GOPATH")) { + if p == "" { + continue + } + r, err := newPkgroot(p) + if err != nil { + log.Printf("Invalid GOPATH %q: %v", p, err) + continue + } + gopath = append(gopath, r) + imports = append(imports, r.pkgDir()) + + // select first GOPATH entry as default + if defaultRoot == nil { + defaultRoot = r + } + } + + // use GOROOT if no valid GOPATH specified + if defaultRoot == nil { + defaultRoot = gopath[0] + } +} + +type pkgroot struct { + path string + goroot bool // TODO(adg): remove this once Go tree re-organized +} + +func newPkgroot(p string) (*pkgroot, os.Error) { + if !filepath.IsAbs(p) { + return nil, os.NewError("must be absolute") + } + ep, err := filepath.EvalSymlinks(p) + if err != nil { + return nil, err + } + return &pkgroot{path: ep}, nil +} + +func (r *pkgroot) srcDir() string { + if r.goroot { + return filepath.Join(r.path, "src", "pkg") + } + return filepath.Join(r.path, "src") +} + +func (r *pkgroot) pkgDir() string { + goos, goarch := runtime.GOOS, runtime.GOARCH + if e := os.Getenv("GOOS"); e != "" { + goos = e + } + if e := os.Getenv("GOARCH"); e != "" { + goarch = e + } + return filepath.Join(r.path, "pkg", goos+"_"+goarch) +} + +func (r *pkgroot) binDir() string { + return filepath.Join(r.path, "bin") +} + +func (r *pkgroot) hasSrcDir(name string) bool { + fi, err := os.Stat(filepath.Join(r.srcDir(), name)) + if err != nil { + return false + } + return fi.IsDirectory() +} + +func (r *pkgroot) hasPkg(name string) bool { + fi, err := os.Stat(filepath.Join(r.pkgDir(), name+".a")) + if err != nil { + return false + } + return fi.IsRegular() + // TODO(adg): check object version is consistent +} + +// findPkgroot searches each of the gopath roots +// for the source code for the given import path. +func findPkgroot(importPath string) *pkgroot { + for _, r := range gopath { + if r.hasSrcDir(importPath) { + return r + } + } + return defaultRoot +} |