func findPkg(b *util.BuildCtxt, name, cwd string) *dependency.PkgInfo { var fi os.FileInfo var err error var p string info := &dependency.PkgInfo{ Name: name, } // Recurse backward to scan other vendor/ directories // If the cwd isn't an absolute path walking upwards looking for vendor/ // folders can get into an infinate loop. abs, err := filepath.Abs(cwd) if err != nil { abs = cwd } if abs != "." { // Previously there was a check on the loop that wd := "/". The path // "/" is a POSIX path so this fails on Windows. Now the check is to // make sure the same wd isn't seen twice. When the same wd happens // more than once it's the beginning of looping on the same location // which is the top level. pwd := "" for wd := abs; wd != pwd; wd = filepath.Dir(wd) { pwd = wd // Don't look for packages outside the GOPATH // Note, the GOPATH may or may not end with the path separator. // The output of filepath.Dir does not the the path separator on the // end so we need to test both. if wd == b.GOPATH || wd+string(os.PathSeparator) == b.GOPATH { break } p = filepath.Join(wd, "vendor", name) if fi, err = os.Stat(p); err == nil && (fi.IsDir() || gpath.IsLink(fi)) { info.Path = p info.Loc = dependency.LocVendor info.Vendored = true return info } } } // Check $GOPATH for _, r := range strings.Split(b.GOPATH, ":") { p = filepath.Join(r, "src", name) if fi, err = os.Stat(p); err == nil && (fi.IsDir() || gpath.IsLink(fi)) { info.Path = p info.Loc = dependency.LocGopath return info } } // Check $GOROOT for _, r := range strings.Split(b.GOROOT, ":") { p = filepath.Join(r, "src", name) if fi, err = os.Stat(p); err == nil && (fi.IsDir() || gpath.IsLink(fi)) { info.Path = p info.Loc = dependency.LocGoroot return info } } // Finally, if this is "C", we're dealing with cgo if name == "C" { info.Loc = dependency.LocCgo } return info }
func findPkg(b *util.BuildCtxt, name, cwd string) *dependency.PkgInfo { var fi os.FileInfo var err error var p string info := &dependency.PkgInfo{ Name: name, } if strings.HasPrefix(name, "./") || strings.HasPrefix(name, "../") { info.Loc = dependency.LocRelative return info } // Recurse backward to scan other vendor/ directories // If the cwd isn't an absolute path walking upwards looking for vendor/ // folders can get into an infinate loop. abs, err := filepath.Abs(cwd) if err != nil { abs = cwd } if abs != "." { // Previously there was a check on the loop that wd := "/". The path // "/" is a POSIX path so this fails on Windows. Now the check is to // make sure the same wd isn't seen twice. When the same wd happens // more than once it's the beginning of looping on the same location // which is the top level. pwd := "" for wd := abs; wd != pwd; wd = filepath.Dir(wd) { pwd = wd // Don't look for packages outside the GOPATH // Note, the GOPATH may or may not end with the path separator. // The output of filepath.Dir does not the the path separator on the // end so we need to test both. if wd == b.GOPATH || wd+string(os.PathSeparator) == b.GOPATH { break } p = filepath.Join(wd, "vendor", name) if fi, err = os.Stat(p); err == nil && (fi.IsDir() || gpath.IsLink(fi)) { info.Path = p info.Loc = dependency.LocVendor info.Vendored = true return info } } } // Check $GOPATH for _, r := range strings.Split(b.GOPATH, ":") { p = filepath.Join(r, "src", name) if fi, err = os.Stat(p); err == nil && (fi.IsDir() || gpath.IsLink(fi)) { info.Path = p info.Loc = dependency.LocGopath return info } } // Check $GOROOT for _, r := range strings.Split(b.GOROOT, ":") { p = filepath.Join(r, "src", name) if fi, err = os.Stat(p); err == nil && (fi.IsDir() || gpath.IsLink(fi)) { info.Path = p info.Loc = dependency.LocGoroot return info } } // If this is "C", we're dealing with cgo if name == "C" { info.Loc = dependency.LocCgo } else if name == "appengine" || name == "appengine_internal" || strings.HasPrefix(name, "appengine/") || strings.HasPrefix(name, "appengine_internal/") { // Appengine is a special case when it comes to Go builds. It is a local // looking package only available within appengine. It's a special case // where Google products are playing with each other. // https://blog.golang.org/the-app-engine-sdk-and-workspaces-gopath info.Loc = dependency.LocAppengine } else if name == "context" || name == "net/http/httptrace" { // context and net/http/httptrace are packages being added to // the Go 1.7 standard library. Some packages, such as golang.org/x/net // are importing it with build flags in files for go1.7. Need to detect // this and handle it. info.Loc = dependency.LocGoroot } return info }