示例#1
0
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
}
示例#2
0
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
}