summaryrefslogtreecommitdiff
path: root/src/cmd/goinstall/path.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/goinstall/path.go')
-rw-r--r--src/cmd/goinstall/path.go117
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
+}