func (ctx *Context) addSingleImport(pkgInDir, imp string) error { if _, found := ctx.Package[imp]; found { return nil } // Also need to check for vendor paths that won't use the local path in import path. for _, pkg := range ctx.Package { if pkg.Canonical == imp && pkg.inVendor && pathos.FileHasPrefix(pkg.Dir, pkgInDir) { return nil } } dir, gopath, err := ctx.findImportDir(pkgInDir, imp) if err != nil { if _, is := err.(ErrNotInGOPATH); is { ctx.setPackage("", imp, imp, "", StatusMissing) return nil } return err } if pathos.FileStringEquals(gopath, ctx.Goroot) { ctx.setPackage(dir, imp, imp, ctx.Goroot, StatusStandard) return nil } df, err := os.Open(dir) if err != nil { return err } info, err := df.Readdir(-1) df.Close() if err != nil { return err } for _, fi := range info { if fi.IsDir() { continue } switch fi.Name()[0] { case '.', '_': continue } if pathos.FileStringEquals(dir, pkgInDir) { continue } path := filepath.Join(dir, fi.Name()) err = ctx.addFileImports(path, gopath) if err != nil { return err } } return nil }
func (ctx *Context) determinePackageStatus() error { // Determine the status of remaining imports. for _, pkg := range ctx.Package { if pkg.Status != StatusUnknown { continue } if vp := ctx.VendorFilePackageLocal(pkg.Local); vp != nil { pkg.Status = StatusVendor pkg.inVendor = true pkg.Canonical = vp.Path continue } if strings.HasPrefix(pkg.Canonical, ctx.RootImportPath) { pkg.Status = StatusLocal continue } pkg.Status = StatusExternal } // Check all "external" packages for vendor. for _, pkg := range ctx.Package { if pkg.Status != StatusExternal { continue } root, err := findRoot(pkg.Dir, vendorFilename) if err != nil { // No vendor file found. if _, is := err.(ErrMissingVendorFile); is { continue } return err } vf, err := readVendorFile(filepath.Join(root, vendorFilename)) if err != nil { return err } vpkg := vendorFileFindLocal(vf, root, pkg.Gopath, pkg.Local) if vpkg != nil { pkg.Canonical = vpkg.Path } } // Determine any un-used internal vendor imports. ctx.updatePackageReferences() for i := 0; i <= looplimit; i++ { altered := false for path, pkg := range ctx.Package { if len(pkg.referenced) == 0 && pkg.Status == StatusVendor { altered = true pkg.Status = StatusUnused for _, other := range ctx.Package { delete(other.referenced, path) } } } if !altered { break } if i == looplimit { panic("determinePackageStatus loop limit") } } return nil }