blob: 1153e04714965d0d97b36bdd0606155651e845e4 [file] [log] [blame]
// 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
}