github.com/maeglindeveloper/gqlgen@v0.13.1-0.20210413081235-57808b12a0a0/internal/code/imports.go (about) 1 package code 2 3 import ( 4 "go/build" 5 "go/parser" 6 "go/token" 7 "io/ioutil" 8 "path/filepath" 9 "regexp" 10 "strings" 11 ) 12 13 var gopaths []string 14 15 func init() { 16 gopaths = filepath.SplitList(build.Default.GOPATH) 17 for i, p := range gopaths { 18 gopaths[i] = filepath.ToSlash(filepath.Join(p, "src")) 19 } 20 } 21 22 // NameForDir manually looks for package stanzas in files located in the given directory. This can be 23 // much faster than having to consult go list, because we already know exactly where to look. 24 func NameForDir(dir string) string { 25 dir, err := filepath.Abs(dir) 26 if err != nil { 27 return SanitizePackageName(filepath.Base(dir)) 28 } 29 files, err := ioutil.ReadDir(dir) 30 if err != nil { 31 return SanitizePackageName(filepath.Base(dir)) 32 } 33 fset := token.NewFileSet() 34 for _, file := range files { 35 if !strings.HasSuffix(strings.ToLower(file.Name()), ".go") { 36 continue 37 } 38 39 filename := filepath.Join(dir, file.Name()) 40 if src, err := parser.ParseFile(fset, filename, nil, parser.PackageClauseOnly); err == nil { 41 return src.Name.Name 42 } 43 } 44 45 return SanitizePackageName(filepath.Base(dir)) 46 } 47 48 // goModuleRoot returns the root of the current go module if there is a go.mod file in the directory tree 49 // If not, it returns false 50 func goModuleRoot(dir string) (string, bool) { 51 dir, err := filepath.Abs(dir) 52 if err != nil { 53 panic(err) 54 } 55 dir = filepath.ToSlash(dir) 56 modDir := dir 57 assumedPart := "" 58 for { 59 f, err := ioutil.ReadFile(filepath.Join(modDir, "go.mod")) 60 if err == nil { 61 // found it, stop searching 62 return string(modregex.FindSubmatch(f)[1]) + assumedPart, true 63 } 64 65 assumedPart = "/" + filepath.Base(modDir) + assumedPart 66 parentDir, err := filepath.Abs(filepath.Join(modDir, "..")) 67 if err != nil { 68 panic(err) 69 } 70 71 if parentDir == modDir { 72 // Walked all the way to the root and didnt find anything :'( 73 break 74 } 75 modDir = parentDir 76 } 77 return "", false 78 } 79 80 // ImportPathForDir takes a path and returns a golang import path for the package 81 func ImportPathForDir(dir string) (res string) { 82 dir, err := filepath.Abs(dir) 83 84 if err != nil { 85 panic(err) 86 } 87 dir = filepath.ToSlash(dir) 88 89 modDir, ok := goModuleRoot(dir) 90 if ok { 91 return modDir 92 } 93 94 for _, gopath := range gopaths { 95 if len(gopath) < len(dir) && strings.EqualFold(gopath, dir[0:len(gopath)]) { 96 return dir[len(gopath)+1:] 97 } 98 } 99 100 return "" 101 } 102 103 var modregex = regexp.MustCompile(`module ([^\s]*)`)