// findImportPath takes a absolute directory and returns the import path and go path. func (ctx *Context) findImportPath(dir string) (importPath, gopath string, err error) { for _, gopath := range ctx.GopathList { if pathos.FileHasPrefix(dir, gopath) { importPath = pathos.FileTrimPrefix(dir, gopath) importPath = pathos.SlashToImportPath(importPath) return importPath, gopath, nil } } return "", "", ErrNotInGOPATH{dir} }
func vendorFileFindLocal(vf *vendorfile.File, root, gopath, importPath string) *vendorfile.Package { local := pathos.SlashToImportPath(pathos.FileTrimPrefix(root, gopath)) // "/co1" = /file/src/co1, /file/src local = strings.TrimPrefix(strings.TrimPrefix(importPath, local), "/") for _, pkg := range vf.Package { if pkg.Remove { continue } if pkg.Local == local { return pkg } } return nil }
func readVendorFile(vendorFilePath string) (*vendorfile.File, error) { vf := &vendorfile.File{} f, err := os.Open(vendorFilePath) if err != nil { return nil, err } defer f.Close() err = vf.Unmarshal(f) if err != nil { return nil, err } // Determine if local field is relative to GOPATH or vendor file. // Change to relative to vendor file as needed. folder, _ := filepath.Split(vendorFilePath) relToFile := 0 relToGOPATH := 0 for _, pkg := range vf.Package { p := filepath.Join(folder, pathos.SlashToFilepath(pkg.Local)) _, err := os.Stat(p) if os.IsNotExist(err) { relToGOPATH++ continue } relToFile++ } if relToFile > relToGOPATH || len(vf.Package) == 0 { return vf, nil } gopathList := strings.Split(os.Getenv("GOPATH"), string(os.PathListSeparator)) gopath := "" for _, gp := range gopathList { if pathos.FileHasPrefix(folder, gp) { gopath = gp break } } if len(gopath) == 0 { return vf, nil } prefix := pathos.SlashToImportPath(pathos.FileTrimPrefix(folder, filepath.Join(gopath, "src"))) prefix = strings.TrimPrefix(prefix, "/") for _, pkg := range vf.Package { pkg.Local = strings.TrimPrefix(pkg.Local, prefix) } return vf, nil }
// addFileImports is called from loadPackage and resolveUnknown. func (ctx *Context) addFileImports(pathname, gopath string) error { dir, filenameExt := filepath.Split(pathname) importPath := pathos.FileTrimPrefix(dir, gopath) importPath = pathos.SlashToImportPath(importPath) importPath = strings.TrimPrefix(importPath, "/") importPath = strings.TrimSuffix(importPath, "/") if strings.HasSuffix(pathname, ".go") == false { return nil } f, err := parser.ParseFile(token.NewFileSet(), pathname, nil, parser.ImportsOnly|parser.ParseComments) if err != nil { return err } tags, err := ctx.getFileTags(pathname, f) if err != nil { return err } pkg, found := ctx.Package[importPath] if !found { status := StatusUnknown if f.Name.Name == "main" { status = StatusProgram } pkg = ctx.setPackage(dir, importPath, importPath, gopath, status) ctx.Package[importPath] = pkg } if pkg.Status != StatusLocal && pkg.Status != StatusProgram { for _, tag := range tags { for _, ignore := range ctx.ignoreTag { if tag == ignore { pkg.ignoreFile = append(pkg.ignoreFile, filenameExt) return nil } } } } pf := &File{ Package: pkg, Path: pathname, Imports: make([]string, len(f.Imports)), } pkg.Files = append(pkg.Files, pf) for i := range f.Imports { imp := f.Imports[i].Path.Value imp, err = strconv.Unquote(imp) if err != nil { return err } if strings.HasPrefix(imp, "./") { imp = path.Join(importPath, imp) } pf.Imports[i] = imp err = ctx.addSingleImport(pkg.Dir, imp) if err != nil { return err } } // Record any import comment for file. var ic *ast.Comment if f.Name != nil { pos := f.Name.Pos() big: // Find the next comment after the package name. for _, cblock := range f.Comments { for _, c := range cblock.List { if c.Pos() > pos { ic = c break big } } } } if ic != nil { // If it starts with the import text, assume it is the import comment and remove. if index := strings.Index(ic.Text, " import "); index > 0 && index < 5 { q := strings.TrimSpace(ic.Text[index+len(" import "):]) pf.ImportComment, err = strconv.Unquote(q) if err != nil { pf.ImportComment = q } } } return nil }
// addFileImports is called from loadPackage and resolveUnknown. func (ctx *Context) addFileImports(pathname, gopath string) error { dir, filenameExt := filepath.Split(pathname) importPath := pathos.FileTrimPrefix(dir, gopath) importPath = pathos.SlashToImportPath(importPath) importPath = strings.TrimPrefix(importPath, "/") importPath = strings.TrimSuffix(importPath, "/") if strings.HasSuffix(pathname, ".go") == false { return nil } f, err := parser.ParseFile(token.NewFileSet(), pathname, nil, parser.ImportsOnly|parser.ParseComments) if err != nil { return err } filename := filenameExt[:len(filenameExt)-3] filenameParts := strings.Split(filename, "_") tags := make([]string, 0) for i, part := range filenameParts { if i == 0 { continue } tags = append(tags, part) } const buildPrefix = "// +build " for _, cc := range f.Comments { for _, c := range cc.List { if strings.HasPrefix(c.Text, buildPrefix) { text := strings.TrimPrefix(c.Text, buildPrefix) ss := strings.Fields(text) for _, s := range ss { tags = append(tags, strings.Split(s, ",")...) } } } } pkg, found := ctx.Package[importPath] if !found { status := StatusUnknown if f.Name.Name == "main" { status = StatusProgram } pkg = ctx.setPackage(dir, importPath, importPath, gopath, status) ctx.Package[importPath] = pkg } for _, tag := range tags { for _, ignore := range ctx.ignoreTag { if tag == ignore { pkg.ignoreFile = append(pkg.ignoreFile, filenameExt) return nil } } } pf := &File{ Package: pkg, Path: pathname, Imports: make([]string, len(f.Imports)), } pkg.Files = append(pkg.Files, pf) for i := range f.Imports { imp := f.Imports[i].Path.Value imp, err = strconv.Unquote(imp) if err != nil { return err } if strings.HasPrefix(imp, "./") { imp = path.Join(importPath, imp) } pf.Imports[i] = imp err = ctx.addSingleImport(pkg.Dir, imp) if err != nil { return err } } return nil }
// addFileImports is called from loadPackage and resolveUnknown. func (ctx *Context) addFileImports(pathname, gopath string) error { dir, filenameExt := filepath.Split(pathname) importPath := pathos.FileTrimPrefix(dir, gopath) importPath = pathos.SlashToImportPath(importPath) importPath = strings.TrimPrefix(importPath, "/") importPath = strings.TrimSuffix(importPath, "/") if strings.HasSuffix(pathname, ".go") == false { return nil } f, err := parser.ParseFile(token.NewFileSet(), pathname, nil, parser.ImportsOnly|parser.ParseComments) if err != nil { return err } tags, err := ctx.getFileTags(pathname, f) if err != nil { return err } pkg, found := ctx.Package[importPath] if !found { status := StatusUnknown if f.Name.Name == "main" { status = StatusProgram } pkg = ctx.setPackage(dir, importPath, importPath, gopath, status) ctx.Package[importPath] = pkg } if pkg.Status != StatusLocal && pkg.Status != StatusProgram { for _, tag := range tags { for _, ignore := range ctx.ignoreTag { if tag == ignore { pkg.ignoreFile = append(pkg.ignoreFile, filenameExt) return nil } } } } pf := &File{ Package: pkg, Path: pathname, Imports: make([]string, len(f.Imports)), } pkg.Files = append(pkg.Files, pf) for i := range f.Imports { imp := f.Imports[i].Path.Value imp, err = strconv.Unquote(imp) if err != nil { return err } if strings.HasPrefix(imp, "./") { imp = path.Join(importPath, imp) } pf.Imports[i] = imp err = ctx.addSingleImport(pkg.Dir, imp) if err != nil { return err } } return nil }