github.com/wiselike/revel-cmd@v1.2.1/parser/imports.go (about) 1 package parser 2 3 import ( 4 "go/ast" 5 "go/build" 6 "go/token" 7 "path/filepath" 8 "strings" 9 10 "github.com/wiselike/revel-cmd/utils" 11 ) 12 13 // Add imports to the map from the source dir. 14 func addImports(imports map[string]string, decl ast.Decl, srcDir string) { 15 genDecl, ok := decl.(*ast.GenDecl) 16 if !ok { 17 return 18 } 19 20 if genDecl.Tok != token.IMPORT { 21 return 22 } 23 24 for _, spec := range genDecl.Specs { 25 importSpec := spec.(*ast.ImportSpec) 26 var pkgAlias string 27 if importSpec.Name != nil { 28 pkgAlias = importSpec.Name.Name 29 if pkgAlias == "_" { 30 continue 31 } 32 } 33 quotedPath := importSpec.Path.Value // e.g. "\"sample/app/models\"" 34 if quotedPath == `"C"` { 35 continue 36 } 37 fullPath := quotedPath[1 : len(quotedPath)-1] // Remove the quotes 38 39 // If the package was not aliased (common case), we have to import it 40 // to see what the package name is. 41 // TODO: Can improve performance here a lot: 42 // 1. Do not import everything over and over again. Keep a cache. 43 // 2. Exempt the standard library; their directories always match the package name. 44 // 3. Can use build.FindOnly and then use parser.ParseDir with mode PackageClauseOnly 45 if pkgAlias == "" { 46 utils.Logger.Debug("Reading from build", "path", fullPath, "srcPath", srcDir, "gopath", build.Default.GOPATH) 47 pkg, err := build.Import(fullPath, srcDir, 0) 48 if err != nil { 49 // We expect this to happen for apps using reverse routing (since we 50 // have not yet generated the routes). Don't log that. 51 if !strings.HasSuffix(fullPath, "/app/routes") { 52 utils.Logger.Warn("Could not find import:", "path", fullPath, "srcPath", srcDir, "error", err) 53 } 54 continue 55 } else { 56 utils.Logger.Debug("Found package in dir", "dir", pkg.Dir, "name", pkg.ImportPath) 57 } 58 pkgAlias = pkg.Name 59 } 60 61 imports[pkgAlias] = fullPath 62 } 63 } 64 65 // Returns a valid import string from the path 66 // using the build.Defaul.GOPATH to determine the root. 67 func importPathFromPath(root, basePath string) string { 68 vendorTest := filepath.Join(basePath, "vendor") 69 if len(root) > len(vendorTest) && root[:len(vendorTest)] == vendorTest { 70 return filepath.ToSlash(root[len(vendorTest)+1:]) 71 } 72 for _, gopath := range filepath.SplitList(build.Default.GOPATH) { 73 srcPath := filepath.Join(gopath, "src") 74 if strings.HasPrefix(root, srcPath) { 75 return filepath.ToSlash(root[len(srcPath)+1:]) 76 } 77 } 78 79 srcPath := filepath.Join(build.Default.GOROOT, "src", "pkg") 80 if strings.HasPrefix(root, srcPath) { 81 utils.Logger.Warn("Code path should be in GOPATH, but is in GOROOT:", "path", root) 82 return filepath.ToSlash(root[len(srcPath)+1:]) 83 } 84 85 utils.Logger.Error("Unexpected! Code path is not in GOPATH:", "path", root) 86 return "" 87 }