aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/99designs/gqlgen/internal
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/99designs/gqlgen/internal')
-rw-r--r--vendor/github.com/99designs/gqlgen/internal/code/compare.go163
-rw-r--r--vendor/github.com/99designs/gqlgen/internal/code/imports.go60
-rw-r--r--vendor/github.com/99designs/gqlgen/internal/code/util.go56
-rw-r--r--vendor/github.com/99designs/gqlgen/internal/gopath/gopath.go37
-rw-r--r--vendor/github.com/99designs/gqlgen/internal/imports/prune.go22
5 files changed, 282 insertions, 56 deletions
diff --git a/vendor/github.com/99designs/gqlgen/internal/code/compare.go b/vendor/github.com/99designs/gqlgen/internal/code/compare.go
new file mode 100644
index 00000000..dce9aea5
--- /dev/null
+++ b/vendor/github.com/99designs/gqlgen/internal/code/compare.go
@@ -0,0 +1,163 @@
+package code
+
+import (
+ "fmt"
+ "go/types"
+)
+
+// CompatibleTypes isnt a strict comparison, it allows for pointer differences
+func CompatibleTypes(expected types.Type, actual types.Type) error {
+ //fmt.Println("Comparing ", expected.String(), actual.String())
+
+ // Special case to deal with pointer mismatches
+ {
+ expectedPtr, expectedIsPtr := expected.(*types.Pointer)
+ actualPtr, actualIsPtr := actual.(*types.Pointer)
+
+ if expectedIsPtr && actualIsPtr {
+ return CompatibleTypes(expectedPtr.Elem(), actualPtr.Elem())
+ }
+ if expectedIsPtr && !actualIsPtr {
+ return CompatibleTypes(expectedPtr.Elem(), actual)
+ }
+ if !expectedIsPtr && actualIsPtr {
+ return CompatibleTypes(expected, actualPtr.Elem())
+ }
+ }
+
+ switch expected := expected.(type) {
+ case *types.Slice:
+ if actual, ok := actual.(*types.Slice); ok {
+ return CompatibleTypes(expected.Elem(), actual.Elem())
+ }
+
+ case *types.Array:
+ if actual, ok := actual.(*types.Array); ok {
+ if expected.Len() != actual.Len() {
+ return fmt.Errorf("array length differs")
+ }
+
+ return CompatibleTypes(expected.Elem(), actual.Elem())
+ }
+
+ case *types.Basic:
+ if actual, ok := actual.(*types.Basic); ok {
+ if actual.Kind() != expected.Kind() {
+ return fmt.Errorf("basic kind differs, %s != %s", expected.Name(), actual.Name())
+ }
+
+ return nil
+ }
+
+ case *types.Struct:
+ if actual, ok := actual.(*types.Struct); ok {
+ if expected.NumFields() != actual.NumFields() {
+ return fmt.Errorf("number of struct fields differ")
+ }
+
+ for i := 0; i < expected.NumFields(); i++ {
+ if expected.Field(i).Name() != actual.Field(i).Name() {
+ return fmt.Errorf("struct field %d name differs, %s != %s", i, expected.Field(i).Name(), actual.Field(i).Name())
+ }
+ if err := CompatibleTypes(expected.Field(i).Type(), actual.Field(i).Type()); err != nil {
+ return err
+ }
+ }
+ return nil
+ }
+
+ case *types.Tuple:
+ if actual, ok := actual.(*types.Tuple); ok {
+ if expected.Len() != actual.Len() {
+ return fmt.Errorf("tuple length differs, %d != %d", expected.Len(), actual.Len())
+ }
+
+ for i := 0; i < expected.Len(); i++ {
+ if err := CompatibleTypes(expected.At(i).Type(), actual.At(i).Type()); err != nil {
+ return err
+ }
+ }
+
+ return nil
+ }
+
+ case *types.Signature:
+ if actual, ok := actual.(*types.Signature); ok {
+ if err := CompatibleTypes(expected.Params(), actual.Params()); err != nil {
+ return err
+ }
+ if err := CompatibleTypes(expected.Results(), actual.Results()); err != nil {
+ return err
+ }
+
+ return nil
+ }
+ case *types.Interface:
+ if actual, ok := actual.(*types.Interface); ok {
+ if expected.NumMethods() != actual.NumMethods() {
+ return fmt.Errorf("interface method count differs, %d != %d", expected.NumMethods(), actual.NumMethods())
+ }
+
+ for i := 0; i < expected.NumMethods(); i++ {
+ if expected.Method(i).Name() != actual.Method(i).Name() {
+ return fmt.Errorf("interface method %d name differs, %s != %s", i, expected.Method(i).Name(), actual.Method(i).Name())
+ }
+ if err := CompatibleTypes(expected.Method(i).Type(), actual.Method(i).Type()); err != nil {
+ return err
+ }
+ }
+
+ return nil
+ }
+
+ case *types.Map:
+ if actual, ok := actual.(*types.Map); ok {
+ if err := CompatibleTypes(expected.Key(), actual.Key()); err != nil {
+ return err
+ }
+
+ if err := CompatibleTypes(expected.Elem(), actual.Elem()); err != nil {
+ return err
+ }
+
+ return nil
+ }
+
+ case *types.Chan:
+ if actual, ok := actual.(*types.Chan); ok {
+ return CompatibleTypes(expected.Elem(), actual.Elem())
+ }
+
+ case *types.Named:
+ if actual, ok := actual.(*types.Named); ok {
+ if NormalizeVendor(expected.Obj().Pkg().Path()) != NormalizeVendor(actual.Obj().Pkg().Path()) {
+ return fmt.Errorf(
+ "package name of named type differs, %s != %s",
+ NormalizeVendor(expected.Obj().Pkg().Path()),
+ NormalizeVendor(actual.Obj().Pkg().Path()),
+ )
+ }
+
+ if expected.Obj().Name() != actual.Obj().Name() {
+ return fmt.Errorf(
+ "named type name differs, %s != %s",
+ NormalizeVendor(expected.Obj().Name()),
+ NormalizeVendor(actual.Obj().Name()),
+ )
+ }
+
+ return nil
+ }
+
+ // Before models are generated all missing references will be Invalid Basic references.
+ // lets assume these are valid too.
+ if actual, ok := actual.(*types.Basic); ok && actual.Kind() == types.Invalid {
+ return nil
+ }
+
+ default:
+ return fmt.Errorf("missing support for %T", expected)
+ }
+
+ return fmt.Errorf("type mismatch %T != %T", expected, actual)
+}
diff --git a/vendor/github.com/99designs/gqlgen/internal/code/imports.go b/vendor/github.com/99designs/gqlgen/internal/code/imports.go
new file mode 100644
index 00000000..2384e87d
--- /dev/null
+++ b/vendor/github.com/99designs/gqlgen/internal/code/imports.go
@@ -0,0 +1,60 @@
+package code
+
+import (
+ "errors"
+ "path/filepath"
+ "sync"
+
+ "golang.org/x/tools/go/packages"
+)
+
+var pathForDirCache = 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)
+ }
+
+ p, _ := packages.Load(&packages.Config{
+ Dir: dir,
+ }, ".")
+
+ // 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, ".."))
+ if err != nil {
+ panic(err)
+ }
+ // Walked all the way to the root and didnt find anything :'(
+ if parent == dir {
+ return ""
+ }
+ return ImportPathForDir(parent) + "/" + filepath.Base(dir)
+ }
+
+ pathForDirCache.Store(dir, p[0].PkgPath)
+
+ return p[0].PkgPath
+}
+
+var nameForPackageCache = sync.Map{}
+
+func NameForPackage(importPath string) string {
+ if importPath == "" {
+ panic(errors.New("import path can not be empty"))
+ }
+ if v, ok := nameForPackageCache.Load(importPath); ok {
+ return v.(string)
+ }
+ importPath = QualifyPackagePath(importPath)
+ p, _ := packages.Load(nil, importPath)
+
+ if len(p) != 1 || p[0].Name == "" {
+ return SanitizePackageName(filepath.Base(importPath))
+ }
+
+ nameForPackageCache.Store(importPath, p[0].Name)
+
+ return p[0].Name
+}
diff --git a/vendor/github.com/99designs/gqlgen/internal/code/util.go b/vendor/github.com/99designs/gqlgen/internal/code/util.go
new file mode 100644
index 00000000..2be83a23
--- /dev/null
+++ b/vendor/github.com/99designs/gqlgen/internal/code/util.go
@@ -0,0 +1,56 @@
+package code
+
+import (
+ "go/build"
+ "os"
+ "path/filepath"
+ "regexp"
+ "strings"
+)
+
+// take a string in the form github.com/package/blah.Type and split it into package and type
+func PkgAndType(name string) (string, string) {
+ parts := strings.Split(name, ".")
+ if len(parts) == 1 {
+ return "", name
+ }
+
+ return strings.Join(parts[:len(parts)-1], "."), parts[len(parts)-1]
+}
+
+var modsRegex = regexp.MustCompile(`^(\*|\[\])*`)
+
+// NormalizeVendor takes a qualified package path and turns it into normal one.
+// eg .
+// github.com/foo/vendor/github.com/99designs/gqlgen/graphql becomes
+// github.com/99designs/gqlgen/graphql
+func NormalizeVendor(pkg string) string {
+ modifiers := modsRegex.FindAllString(pkg, 1)[0]
+ pkg = strings.TrimPrefix(pkg, modifiers)
+ parts := strings.Split(pkg, "/vendor/")
+ return modifiers + parts[len(parts)-1]
+}
+
+// QualifyPackagePath takes an import and fully qualifies it with a vendor dir, if one is required.
+// eg .
+// github.com/99designs/gqlgen/graphql becomes
+// github.com/foo/vendor/github.com/99designs/gqlgen/graphql
+//
+// x/tools/packages only supports 'qualified package paths' so this will need to be done prior to calling it
+// See https://github.com/golang/go/issues/30289
+func QualifyPackagePath(importPath string) string {
+ wd, _ := os.Getwd()
+
+ pkg, err := build.Import(importPath, wd, 0)
+ if err != nil {
+ return importPath
+ }
+
+ return pkg.ImportPath
+}
+
+var invalidPackageNameChar = regexp.MustCompile(`[^\w]`)
+
+func SanitizePackageName(pkg string) string {
+ return invalidPackageNameChar.ReplaceAllLiteralString(filepath.Base(pkg), "_")
+}
diff --git a/vendor/github.com/99designs/gqlgen/internal/gopath/gopath.go b/vendor/github.com/99designs/gqlgen/internal/gopath/gopath.go
deleted file mode 100644
index c9b66167..00000000
--- a/vendor/github.com/99designs/gqlgen/internal/gopath/gopath.go
+++ /dev/null
@@ -1,37 +0,0 @@
-package gopath
-
-import (
- "fmt"
- "go/build"
- "path/filepath"
- "strings"
-)
-
-var NotFound = fmt.Errorf("not on GOPATH")
-
-// Contains returns true if the given directory is in the GOPATH
-func Contains(dir string) bool {
- _, err := Dir2Import(dir)
- return err == nil
-}
-
-// Dir2Import 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 Dir2Import(dir string) (string, error) {
- dir = filepath.ToSlash(dir)
- for _, gopath := range filepath.SplitList(build.Default.GOPATH) {
- gopath = filepath.ToSlash(filepath.Join(gopath, "src"))
- if len(gopath) < len(dir) && strings.EqualFold(gopath, dir[0:len(gopath)]) {
- return dir[len(gopath)+1:], nil
- }
- }
- return "", NotFound
-}
-
-// MustDir2Import takes an *absolute* path and returns a golang import path for the package, and panics if it isn't on the gopath
-func MustDir2Import(dir string) string {
- pkg, err := Dir2Import(dir)
- if err != nil {
- panic(err)
- }
- return pkg
-}
diff --git a/vendor/github.com/99designs/gqlgen/internal/imports/prune.go b/vendor/github.com/99designs/gqlgen/internal/imports/prune.go
index d2469e83..d678870e 100644
--- a/vendor/github.com/99designs/gqlgen/internal/imports/prune.go
+++ b/vendor/github.com/99designs/gqlgen/internal/imports/prune.go
@@ -5,16 +5,15 @@ package imports
import (
"bytes"
"go/ast"
- "go/build"
"go/parser"
"go/printer"
"go/token"
- "path/filepath"
"strings"
- "golang.org/x/tools/imports"
+ "github.com/99designs/gqlgen/internal/code"
"golang.org/x/tools/go/ast/astutil"
+ "golang.org/x/tools/imports"
)
type visitFn func(node ast.Node)
@@ -54,12 +53,6 @@ func getUnusedImports(file ast.Node, filename string) (map[string]string, error)
imported := map[string]*ast.ImportSpec{}
used := map[string]bool{}
- abs, err := filepath.Abs(filename)
- if err != nil {
- return nil, err
- }
- srcDir := filepath.Dir(abs)
-
ast.Walk(visitFn(func(node ast.Node) {
if node == nil {
return
@@ -75,7 +68,7 @@ func getUnusedImports(file ast.Node, filename string) (map[string]string, error)
break
}
- local := importPathToName(ipath, srcDir)
+ local := code.NameForPackage(ipath)
imported[local] = v
case *ast.SelectorExpr:
@@ -108,12 +101,3 @@ func getUnusedImports(file ast.Node, filename string) (map[string]string, error)
return unusedImport, nil
}
-
-func importPathToName(importPath, srcDir string) (packageName string) {
- pkg, err := build.Default.Import(importPath, srcDir, 0)
- if err != nil {
- return ""
- }
-
- return pkg.Name
-}