github.com/mlmmr/revel-cmd@v0.21.2-0.20191112133115-68d8795776dd/parser/imports.go (about)

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