From 3916fe135b29343951cabdb0a7cdd49aa16b00b5 Mon Sep 17 00:00:00 2001 From: Viktor Stanchev Date: Tue, 26 Nov 2019 21:22:36 +0300 Subject: [PATCH 1/2] deduplicate package load between AutoBind and Binder --- codegen/config/binder.go | 16 +--------------- codegen/config/binder_test.go | 17 ++++++++++++++++- codegen/config/config.go | 35 +++++++++++++++++++++-------------- codegen/config/config_test.go | 15 ++++++++++++++- codegen/data.go | 26 ++++++++++++++++++++------ plugin/modelgen/models.go | 20 +++++++++++++++++--- 6 files changed, 89 insertions(+), 40 deletions(-) diff --git a/codegen/config/binder.go b/codegen/config/binder.go index d42b9ec523..0ebf415735 100644 --- a/codegen/config/binder.go +++ b/codegen/config/binder.go @@ -23,21 +23,7 @@ type Binder struct { SawInvalid bool } -func (c *Config) NewBinder(s *ast.Schema) (*Binder, error) { - pkgs, err := packages.Load(&packages.Config{ - Mode: packages.NeedName | - packages.NeedFiles | - packages.NeedCompiledGoFiles | - packages.NeedImports | - packages.NeedTypes | - packages.NeedTypesSizes | - packages.NeedSyntax | - packages.NeedTypesInfo, - }, c.Models.ReferencedPackages()...) - if err != nil { - return nil, err - } - +func (c *Config) NewBinder(s *ast.Schema, pkgs []*packages.Package) (*Binder, error) { mp := map[string]*packages.Package{} var pkgErrs PkgErrors for _, p := range pkgs { diff --git a/codegen/config/binder_test.go b/codegen/config/binder_test.go index 6a842a12da..94a951d9f8 100644 --- a/codegen/config/binder_test.go +++ b/codegen/config/binder_test.go @@ -7,6 +7,7 @@ import ( "github.com/stretchr/testify/require" "github.com/vektah/gqlparser" "github.com/vektah/gqlparser/ast" + "golang.org/x/tools/go/packages" ) func TestBindingToInvalid(t *testing.T) { @@ -58,7 +59,21 @@ func createBinder(cfg Config) (*Binder, *ast.Schema) { } `}) - b, err := cfg.NewBinder(s) + ps, err := packages.Load(&packages.Config{ + Mode: packages.NeedName | + packages.NeedFiles | + packages.NeedCompiledGoFiles | + packages.NeedImports | + packages.NeedTypes | + packages.NeedTypesSizes | + packages.NeedSyntax | + packages.NeedTypesInfo, + }, cfg.Models.ReferencedPackages()...) + if err != nil { + panic(err) + } + + b, err := cfg.NewBinder(s, ps) if err != nil { panic(err) } diff --git a/codegen/config/config.go b/codegen/config/config.go index a11eb75c65..7c258b6529 100644 --- a/codegen/config/config.go +++ b/codegen/config/config.go @@ -395,30 +395,34 @@ func (c *Config) normalize() error { return nil } - -func (c *Config) Autobind(s *ast.Schema) error { +func (c *Config) isAutobind(pkg *packages.Package) bool { + for _, ab := range c.AutoBind { + if strings.HasSuffix(ab, "/...") { + abPrefix := strings.TrimSuffix(ab, "/...") + if strings.HasPrefix(pkg.PkgPath, abPrefix) { + return true + } + } + if pkg.PkgPath == ab { + return true + } + } + return false +} +func (c *Config) Autobind(s *ast.Schema, ps []*packages.Package) error { if len(c.AutoBind) == 0 { return nil } - ps, err := packages.Load(&packages.Config{ - Mode: packages.NeedName | - packages.NeedFiles | - packages.NeedCompiledGoFiles | - packages.NeedImports | - packages.NeedTypes | - packages.NeedTypesSizes, - }, c.AutoBind...) - if err != nil { - return err - } - for _, t := range s.Types { if c.Models.UserDefined(t.Name) { continue } for _, p := range ps { + if !c.isAutobind(p) { + continue + } if t := p.Types.Scope().Lookup(t.Name); t != nil { c.Models.Add(t.Name(), t.Pkg().Path()+"."+t.Name()) break @@ -436,6 +440,9 @@ func (c *Config) Autobind(s *ast.Schema) error { } for _, p := range ps { + if !c.isAutobind(p) { + continue + } if p.Name != pkg { continue } diff --git a/codegen/config/config_test.go b/codegen/config/config_test.go index 7551a11543..6a72719abe 100644 --- a/codegen/config/config_test.go +++ b/codegen/config/config_test.go @@ -8,6 +8,7 @@ import ( "github.com/vektah/gqlparser" "github.com/vektah/gqlparser/ast" + "golang.org/x/tools/go/packages" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -132,7 +133,19 @@ func TestAutobinding(t *testing.T) { type Message { id: ID } `}) - require.NoError(t, cfg.Autobind(s)) + ps, err := packages.Load(&packages.Config{ + Mode: packages.NeedName | + packages.NeedFiles | + packages.NeedCompiledGoFiles | + packages.NeedImports | + packages.NeedTypes | + packages.NeedTypesSizes | + packages.NeedSyntax | + packages.NeedTypesInfo, + }, cfg.AutoBind...) + require.NoError(t, err) + + require.NoError(t, cfg.Autobind(s, ps)) require.Equal(t, "github.com/99designs/gqlgen/example/scalars/model.Banned", cfg.Models["Banned"].Model[0]) require.Equal(t, "github.com/99designs/gqlgen/example/chat.Message", cfg.Models["Message"].Model[0]) diff --git a/codegen/data.go b/codegen/data.go index d3b191f8f9..e52e9feb98 100644 --- a/codegen/data.go +++ b/codegen/data.go @@ -59,11 +59,6 @@ func BuildData(cfg *config.Config, plugins []SchemaMutator) (*Data, error) { return nil, err } - err = cfg.Autobind(b.Schema) - if err != nil { - return nil, err - } - cfg.InjectBuiltins(b.Schema) for _, p := range plugins { @@ -73,7 +68,26 @@ func BuildData(cfg *config.Config, plugins []SchemaMutator) (*Data, error) { } } - b.Binder, err = b.Config.NewBinder(b.Schema) + ps, err := packages.Load(&packages.Config{ + Mode: packages.NeedName | + packages.NeedFiles | + packages.NeedCompiledGoFiles | + packages.NeedImports | + packages.NeedTypes | + packages.NeedTypesSizes | + packages.NeedSyntax | + packages.NeedTypesInfo, + }, append(cfg.Models.ReferencedPackages(), cfg.AutoBind...)...) + if err != nil { + return nil, err + } + + err = cfg.Autobind(b.Schema, ps) + if err != nil { + return nil, err + } + + b.Binder, err = b.Config.NewBinder(b.Schema, ps) if err != nil { return nil, err } diff --git a/plugin/modelgen/models.go b/plugin/modelgen/models.go index 8e976c65bf..44ae57b7d2 100644 --- a/plugin/modelgen/models.go +++ b/plugin/modelgen/models.go @@ -80,14 +80,28 @@ func (m *Plugin) MutateConfig(cfg *config.Config) error { return err } - err = cfg.Autobind(schema) + cfg.InjectBuiltins(schema) + + ps, err := packages.Load(&packages.Config{ + Mode: packages.NeedName | + packages.NeedFiles | + packages.NeedCompiledGoFiles | + packages.NeedImports | + packages.NeedTypes | + packages.NeedTypesSizes | + packages.NeedSyntax | + packages.NeedTypesInfo, + }, append(cfg.Models.ReferencedPackages(), cfg.AutoBind...)...) if err != nil { return err } - cfg.InjectBuiltins(schema) + err = cfg.Autobind(schema, ps) + if err != nil { + return err + } - binder, err := cfg.NewBinder(schema) + binder, err := cfg.NewBinder(schema, ps) if err != nil { return err } From fbb20b9d1d76f1c01ea8175e3f3b905c08a270b2 Mon Sep 17 00:00:00 2001 From: Viktor Stanchev Date: Sat, 18 Jan 2020 17:36:36 -0800 Subject: [PATCH 2/2] fix loading non-packages --- codegen/config/config.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/codegen/config/config.go b/codegen/config/config.go index 7c258b6529..c6f0e9685e 100644 --- a/codegen/config/config.go +++ b/codegen/config/config.go @@ -310,6 +310,9 @@ func (tm TypeMap) ReferencedPackages() []string { if pkg == "" || inStrSlice(pkgs, pkg) { continue } + if !strings.Contains(pkg, ".") { + continue + } pkgs = append(pkgs, code.QualifyPackagePath(pkg)) } }