github.com/wilhelmeek/gqlgen@v0.7.2/codegen/build.go (about) 1 package codegen 2 3 import ( 4 "fmt" 5 "go/build" 6 "go/types" 7 "os" 8 9 "github.com/pkg/errors" 10 "golang.org/x/tools/go/loader" 11 ) 12 13 type Build struct { 14 PackageName string 15 Objects Objects 16 Inputs Objects 17 Interfaces []*Interface 18 QueryRoot *Object 19 MutationRoot *Object 20 SubscriptionRoot *Object 21 SchemaRaw map[string]string 22 SchemaFilename SchemaFilenames 23 Directives []*Directive 24 } 25 26 type ModelBuild struct { 27 PackageName string 28 Models []Model 29 Enums []Enum 30 } 31 32 type ResolverBuild struct { 33 PackageName string 34 ResolverType string 35 Objects Objects 36 ResolverFound bool 37 } 38 39 type ServerBuild struct { 40 PackageName string 41 ExecPackageName string 42 ResolverPackageName string 43 } 44 45 // Create a list of models that need to be generated 46 func (cfg *Config) models() (*ModelBuild, error) { 47 namedTypes := cfg.buildNamedTypes() 48 49 progLoader := cfg.newLoaderWithoutErrors() 50 51 prog, err := progLoader.Load() 52 if err != nil { 53 return nil, errors.Wrap(err, "loading failed") 54 } 55 56 cfg.bindTypes(namedTypes, cfg.Model.Dir(), prog) 57 58 models, err := cfg.buildModels(namedTypes, prog) 59 if err != nil { 60 return nil, err 61 } 62 return &ModelBuild{ 63 PackageName: cfg.Model.Package, 64 Models: models, 65 Enums: cfg.buildEnums(namedTypes), 66 }, nil 67 } 68 69 // bind a schema together with some code to generate a Build 70 func (cfg *Config) resolver() (*ResolverBuild, error) { 71 progLoader := cfg.newLoaderWithoutErrors() 72 progLoader.Import(cfg.Resolver.ImportPath()) 73 74 prog, err := progLoader.Load() 75 if err != nil { 76 return nil, err 77 } 78 79 destDir := cfg.Resolver.Dir() 80 81 namedTypes := cfg.buildNamedTypes() 82 83 cfg.bindTypes(namedTypes, destDir, prog) 84 85 objects, err := cfg.buildObjects(namedTypes, prog) 86 if err != nil { 87 return nil, err 88 } 89 90 def, _ := findGoType(prog, cfg.Resolver.ImportPath(), cfg.Resolver.Type) 91 resolverFound := def != nil 92 93 return &ResolverBuild{ 94 PackageName: cfg.Resolver.Package, 95 Objects: objects, 96 ResolverType: cfg.Resolver.Type, 97 ResolverFound: resolverFound, 98 }, nil 99 } 100 101 func (cfg *Config) server(destDir string) *ServerBuild { 102 return &ServerBuild{ 103 PackageName: cfg.Resolver.Package, 104 ExecPackageName: cfg.Exec.ImportPath(), 105 ResolverPackageName: cfg.Resolver.ImportPath(), 106 } 107 } 108 109 // bind a schema together with some code to generate a Build 110 func (cfg *Config) bind() (*Build, error) { 111 namedTypes := cfg.buildNamedTypes() 112 113 progLoader := cfg.newLoaderWithoutErrors() 114 prog, err := progLoader.Load() 115 if err != nil { 116 return nil, errors.Wrap(err, "loading failed") 117 } 118 119 cfg.bindTypes(namedTypes, cfg.Exec.Dir(), prog) 120 121 objects, err := cfg.buildObjects(namedTypes, prog) 122 if err != nil { 123 return nil, err 124 } 125 126 inputs, err := cfg.buildInputs(namedTypes, prog) 127 if err != nil { 128 return nil, err 129 } 130 directives, err := cfg.buildDirectives(namedTypes) 131 if err != nil { 132 return nil, err 133 } 134 135 b := &Build{ 136 PackageName: cfg.Exec.Package, 137 Objects: objects, 138 Interfaces: cfg.buildInterfaces(namedTypes, prog), 139 Inputs: inputs, 140 SchemaRaw: cfg.SchemaStr, 141 SchemaFilename: cfg.SchemaFilename, 142 Directives: directives, 143 } 144 145 if cfg.schema.Query != nil { 146 b.QueryRoot = b.Objects.ByName(cfg.schema.Query.Name) 147 } else { 148 return b, fmt.Errorf("query entry point missing") 149 } 150 151 if cfg.schema.Mutation != nil { 152 b.MutationRoot = b.Objects.ByName(cfg.schema.Mutation.Name) 153 } 154 155 if cfg.schema.Subscription != nil { 156 b.SubscriptionRoot = b.Objects.ByName(cfg.schema.Subscription.Name) 157 } 158 return b, nil 159 } 160 161 func (cfg *Config) validate() error { 162 progLoader := cfg.newLoaderWithErrors() 163 _, err := progLoader.Load() 164 return err 165 } 166 167 func (cfg *Config) newLoaderWithErrors() loader.Config { 168 conf := loader.Config{} 169 170 for _, pkg := range cfg.Models.referencedPackages() { 171 conf.Import(pkg) 172 } 173 return conf 174 } 175 176 func (cfg *Config) newLoaderWithoutErrors() loader.Config { 177 conf := cfg.newLoaderWithErrors() 178 conf.AllowErrors = true 179 conf.TypeChecker = types.Config{ 180 Error: func(e error) {}, 181 } 182 return conf 183 } 184 185 func resolvePkg(pkgName string) (string, error) { 186 cwd, _ := os.Getwd() 187 188 pkg, err := build.Default.Import(pkgName, cwd, build.FindOnly) 189 if err != nil { 190 return "", err 191 } 192 193 return pkg.ImportPath, nil 194 }