aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/99designs/gqlgen/internal/code/imports.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/99designs/gqlgen/internal/code/imports.go')
-rw-r--r--vendor/github.com/99designs/gqlgen/internal/code/imports.go90
1 files changed, 72 insertions, 18 deletions
diff --git a/vendor/github.com/99designs/gqlgen/internal/code/imports.go b/vendor/github.com/99designs/gqlgen/internal/code/imports.go
index 2384e87d..75c30fe1 100644
--- a/vendor/github.com/99designs/gqlgen/internal/code/imports.go
+++ b/vendor/github.com/99designs/gqlgen/internal/code/imports.go
@@ -2,44 +2,96 @@ package code
import (
"errors"
+ "go/build"
+ "go/parser"
+ "go/token"
+ "io/ioutil"
"path/filepath"
+ "regexp"
+ "strings"
"sync"
"golang.org/x/tools/go/packages"
)
-var pathForDirCache = sync.Map{}
+var nameForPackageCache = sync.Map{}
-// 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
-func ImportPathForDir(dir string) string {
- if v, ok := pathForDirCache.Load(dir); ok {
- return v.(string)
+var gopaths []string
+
+func init() {
+ gopaths = filepath.SplitList(build.Default.GOPATH)
+ for i, p := range gopaths {
+ gopaths[i] = filepath.ToSlash(filepath.Join(p, "src"))
}
+}
- p, _ := packages.Load(&packages.Config{
- Dir: dir,
- }, ".")
+// NameForDir manually looks for package stanzas in files located in the given directory. This can be
+// much faster than having to consult go list, because we already know exactly where to look.
+func NameForDir(dir string) string {
+ dir, err := filepath.Abs(dir)
+ if err != nil {
+ return SanitizePackageName(filepath.Base(dir))
+ }
+ files, err := ioutil.ReadDir(dir)
+ if err != nil {
+ return SanitizePackageName(filepath.Base(dir))
+ }
+ fset := token.NewFileSet()
+ for _, file := range files {
+ if !strings.HasSuffix(strings.ToLower(file.Name()), ".go") {
+ continue
+ }
+
+ filename := filepath.Join(dir, file.Name())
+ if src, err := parser.ParseFile(fset, filename, nil, parser.PackageClauseOnly); err == nil {
+ return src.Name.Name
+ }
+ }
- // If the dir dosent exist yet, keep walking up the directory tree trying to find a match
- if len(p) != 1 {
- parent, err := filepath.Abs(filepath.Join(dir, ".."))
+ return SanitizePackageName(filepath.Base(dir))
+}
+
+// ImportPathForDir takes a path and returns a golang import path for the package
+func ImportPathForDir(dir string) (res string) {
+ dir, err := filepath.Abs(dir)
+ if err != nil {
+ panic(err)
+ }
+ dir = filepath.ToSlash(dir)
+
+ modDir := dir
+ assumedPart := ""
+ for {
+ f, err := ioutil.ReadFile(filepath.Join(modDir, "/", "go.mod"))
+ if err == nil {
+ // found it, stop searching
+ return string(modregex.FindSubmatch(f)[1]) + assumedPart
+ }
+
+ assumedPart = "/" + filepath.Base(modDir) + assumedPart
+ modDir, err = filepath.Abs(filepath.Join(modDir, ".."))
if err != nil {
panic(err)
}
+
// Walked all the way to the root and didnt find anything :'(
- if parent == dir {
- return ""
+ if modDir == "/" {
+ break
}
- return ImportPathForDir(parent) + "/" + filepath.Base(dir)
}
- pathForDirCache.Store(dir, p[0].PkgPath)
+ for _, gopath := range gopaths {
+ if len(gopath) < len(dir) && strings.EqualFold(gopath, dir[0:len(gopath)]) {
+ return dir[len(gopath)+1:]
+ }
+ }
- return p[0].PkgPath
+ return ""
}
-var nameForPackageCache = sync.Map{}
+var modregex = regexp.MustCompile("module (.*)\n")
+// NameForPackage returns the package name for a given import path. This can be really slow.
func NameForPackage(importPath string) string {
if importPath == "" {
panic(errors.New("import path can not be empty"))
@@ -48,7 +100,9 @@ func NameForPackage(importPath string) string {
return v.(string)
}
importPath = QualifyPackagePath(importPath)
- p, _ := packages.Load(nil, importPath)
+ p, _ := packages.Load(&packages.Config{
+ Mode: packages.NeedName,
+ }, importPath)
if len(p) != 1 || p[0].Name == "" {
return SanitizePackageName(filepath.Base(importPath))