diff options
author | Michael Muré <batolettre@gmail.com> | 2018-08-14 14:48:41 +0200 |
---|---|---|
committer | Michael Muré <batolettre@gmail.com> | 2018-08-14 14:48:41 +0200 |
commit | 5c568a362b73cf163b06bc7371982f9a7ceaaf29 (patch) | |
tree | 755b61f969913b5290f3d56f4cfba4070b8155bc /vendor/github.com/vektah/gqlgen/codegen/build.go | |
parent | ef0d8fa108fbdef24997a84a3c6ecbf21cbc0a9e (diff) | |
download | git-bug-5c568a362b73cf163b06bc7371982f9a7ceaaf29.tar.gz |
gqlgen: add a small program to go:generate the code
Diffstat (limited to 'vendor/github.com/vektah/gqlgen/codegen/build.go')
-rw-r--r-- | vendor/github.com/vektah/gqlgen/codegen/build.go | 165 |
1 files changed, 165 insertions, 0 deletions
diff --git a/vendor/github.com/vektah/gqlgen/codegen/build.go b/vendor/github.com/vektah/gqlgen/codegen/build.go new file mode 100644 index 00000000..d56fc06f --- /dev/null +++ b/vendor/github.com/vektah/gqlgen/codegen/build.go @@ -0,0 +1,165 @@ +package codegen + +import ( + "fmt" + "go/build" + "go/types" + "os" + + "github.com/pkg/errors" + "golang.org/x/tools/go/loader" +) + +type Build struct { + PackageName string + Objects Objects + Inputs Objects + Interfaces []*Interface + Imports []*Import + QueryRoot *Object + MutationRoot *Object + SubscriptionRoot *Object + SchemaRaw string +} + +type ModelBuild struct { + PackageName string + Imports []*Import + Models []Model + Enums []Enum +} + +// Create a list of models that need to be generated +func (cfg *Config) models() (*ModelBuild, error) { + namedTypes := cfg.buildNamedTypes() + + prog, err := cfg.loadProgram(namedTypes, true) + if err != nil { + return nil, errors.Wrap(err, "loading failed") + } + imports := buildImports(namedTypes, cfg.Model.Dir()) + + cfg.bindTypes(imports, namedTypes, cfg.Model.Dir(), prog) + + models, err := cfg.buildModels(namedTypes, prog) + if err != nil { + return nil, err + } + return &ModelBuild{ + PackageName: cfg.Model.Package, + Models: models, + Enums: cfg.buildEnums(namedTypes), + Imports: imports.finalize(), + }, nil +} + +// bind a schema together with some code to generate a Build +func (cfg *Config) bind() (*Build, error) { + namedTypes := cfg.buildNamedTypes() + + prog, err := cfg.loadProgram(namedTypes, true) + if err != nil { + return nil, errors.Wrap(err, "loading failed") + } + + imports := buildImports(namedTypes, cfg.Exec.Dir()) + cfg.bindTypes(imports, namedTypes, cfg.Exec.Dir(), prog) + + objects, err := cfg.buildObjects(namedTypes, prog, imports) + if err != nil { + return nil, err + } + + inputs, err := cfg.buildInputs(namedTypes, prog, imports) + if err != nil { + return nil, err + } + + b := &Build{ + PackageName: cfg.Exec.Package, + Objects: objects, + Interfaces: cfg.buildInterfaces(namedTypes, prog), + Inputs: inputs, + Imports: imports.finalize(), + SchemaRaw: cfg.SchemaStr, + } + + if qr, ok := cfg.schema.EntryPoints["query"]; ok { + b.QueryRoot = b.Objects.ByName(qr.TypeName()) + } + + if mr, ok := cfg.schema.EntryPoints["mutation"]; ok { + b.MutationRoot = b.Objects.ByName(mr.TypeName()) + } + + if sr, ok := cfg.schema.EntryPoints["subscription"]; ok { + b.SubscriptionRoot = b.Objects.ByName(sr.TypeName()) + } + + if b.QueryRoot == nil { + return b, fmt.Errorf("query entry point missing") + } + + // Poke a few magic methods into query + q := b.Objects.ByName(b.QueryRoot.GQLType) + q.Fields = append(q.Fields, Field{ + Type: &Type{namedTypes["__Schema"], []string{modPtr}, nil}, + GQLName: "__schema", + NoErr: true, + GoMethodName: "ec.introspectSchema", + Object: q, + }) + q.Fields = append(q.Fields, Field{ + Type: &Type{namedTypes["__Type"], []string{modPtr}, nil}, + GQLName: "__type", + NoErr: true, + GoMethodName: "ec.introspectType", + Args: []FieldArgument{ + {GQLName: "name", Type: &Type{namedTypes["String"], []string{}, nil}, Object: &Object{}}, + }, + Object: q, + }) + + return b, nil +} + +func (cfg *Config) validate() error { + namedTypes := cfg.buildNamedTypes() + + _, err := cfg.loadProgram(namedTypes, false) + return err +} + +func (cfg *Config) loadProgram(namedTypes NamedTypes, allowErrors bool) (*loader.Program, error) { + conf := loader.Config{} + if allowErrors { + conf = loader.Config{ + AllowErrors: true, + TypeChecker: types.Config{ + Error: func(e error) {}, + }, + } + } + for _, imp := range ambientImports { + conf.Import(imp) + } + + for _, imp := range namedTypes { + if imp.Package != "" { + conf.Import(imp.Package) + } + } + + return conf.Load() +} + +func resolvePkg(pkgName string) (string, error) { + cwd, _ := os.Getwd() + + pkg, err := build.Default.Import(pkgName, cwd, build.FindOnly) + if err != nil { + return "", err + } + + return pkg.ImportPath, nil +} |