github.com/HaswinVidanage/gqlgen@v0.8.1-0.20220609041233-69528c1bf712/internal/code/imports.go (about) 1 package code 2 3 import ( 4 "errors" 5 "path/filepath" 6 "sync" 7 8 "golang.org/x/tools/go/packages" 9 ) 10 11 var pathForDirCache = sync.Map{} 12 13 // ImportPathFromDir takes an *absolute* path and returns a golang import path for the package, and returns an error if it isn't on the gopath 14 func ImportPathForDir(dir string) string { 15 if v, ok := pathForDirCache.Load(dir); ok { 16 return v.(string) 17 } 18 19 p, _ := packages.Load(&packages.Config{ 20 Dir: dir, 21 }, ".") 22 23 // If the dir dosent exist yet, keep walking up the directory tree trying to find a match 24 if len(p) != 1 { 25 parent, err := filepath.Abs(filepath.Join(dir, "..")) 26 if err != nil { 27 panic(err) 28 } 29 // Walked all the way to the root and didnt find anything :'( 30 if parent == dir { 31 return "" 32 } 33 return ImportPathForDir(parent) + "/" + filepath.Base(dir) 34 } 35 36 pathForDirCache.Store(dir, p[0].PkgPath) 37 38 return p[0].PkgPath 39 } 40 41 var nameForPackageCache = sync.Map{} 42 43 func NameForPackage(importPath string) string { 44 if importPath == "" { 45 panic(errors.New("import path can not be empty")) 46 } 47 if v, ok := nameForPackageCache.Load(importPath); ok { 48 return v.(string) 49 } 50 importPath = QualifyPackagePath(importPath) 51 p, _ := packages.Load(nil, importPath) 52 53 if len(p) != 1 || p[0].Name == "" { 54 return SanitizePackageName(filepath.Base(importPath)) 55 } 56 57 nameForPackageCache.Store(importPath, p[0].Name) 58 59 return p[0].Name 60 }