From 5c20b3683db5edd67d74610096b2520a66386d3a Mon Sep 17 00:00:00 2001 From: Dmitriy Garanzha Date: Thu, 24 Jan 2019 11:54:58 +0200 Subject: [PATCH 1/2] Linter. --- .golangci.yml | 22 +++++++ .travis.yml | 1 + Makefile | 3 + api/{multipart_file => multipartfile}/file.go | 2 +- api/scalars/scalars.go | 28 ++++---- cmd/go2gql/main.go | 14 ++-- example/simple_plugin/plugin.go | 15 ++++- generator/plugins/dataloader/config.go | 4 +- .../dataloader/data_loader_generator.go | 5 +- generator/plugins/dataloader/dataloader.go | 4 +- generator/plugins/dataloader/plugin.go | 7 +- generator/plugins/graphql/models.go | 2 +- generator/plugins/graphql/plugin.go | 8 +-- generator/plugins/graphql/plugin_test.go | 12 ++-- generator/plugins/graphql/schema_parser.go | 4 +- .../plugins/graphql/schemas_generator.go | 2 +- generator/plugins/graphql/types_generator.go | 2 +- generator/plugins/proto2gql/config.go | 14 ++-- generator/plugins/proto2gql/enums.go | 5 +- generator/plugins/proto2gql/generator.go | 8 +-- .../plugins/proto2gql/messages_inputs.go | 6 +- .../plugins/proto2gql/messages_outputs.go | 12 ++-- generator/plugins/proto2gql/parser/file.go | 22 +++---- .../plugins/proto2gql/parser/parser_test.go | 4 +- generator/plugins/proto2gql/plugin.go | 9 ++- generator/plugins/proto2gql/resolvers.go | 20 +++--- generator/plugins/proto2gql/services.go | 13 ++-- generator/plugins/swagger2gql/config.go | 12 ++-- generator/plugins/swagger2gql/helpers.go | 64 ------------------- .../swagger2gql/input_object_resolvers.go | 8 +-- .../plugins/swagger2gql/input_objects.go | 3 - .../plugins/swagger2gql/map_input_objects.go | 5 -- .../map_input_objects_resolvers.go | 5 ++ .../plugins/swagger2gql/map_output_objects.go | 5 -- .../plugins/swagger2gql/output_object.go | 8 +-- .../plugins/swagger2gql/parser/parser.go | 4 +- generator/plugins/swagger2gql/plugin.go | 6 +- generator/plugins/swagger2gql/resolvers.go | 25 ++++---- generator/plugins/swagger2gql/services.go | 13 +++- .../swagger2gql/templates_resolvers.go | 8 ++- tests/Makefile | 2 +- tests/dataloader/dataloader_test.go | 2 +- tests/{proto_unwrap => protounwrap}/Makefile | 0 .../apis/items.proto | 2 +- .../generate.yml | 0 .../mock/item.go | 8 ++- .../mock/loader.go | 2 +- .../proto_unwrap_test.go | 10 +-- tests/utils.go | 2 +- 49 files changed, 212 insertions(+), 230 deletions(-) create mode 100644 .golangci.yml rename api/{multipart_file => multipartfile}/file.go (90%) rename tests/{proto_unwrap => protounwrap}/Makefile (100%) rename tests/{proto_unwrap => protounwrap}/apis/items.proto (81%) rename tests/{proto_unwrap => protounwrap}/generate.yml (100%) rename tests/{proto_unwrap => protounwrap}/mock/item.go (93%) rename tests/{proto_unwrap => protounwrap}/mock/loader.go (53%) rename tests/{proto_unwrap => protounwrap}/proto_unwrap_test.go (88%) diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 0000000..8cdb2fe --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,22 @@ +linters: + enable-all: true + disable: + - gochecknoglobals + - scopelint + - prealloc + - maligned + - unparam + - megacheck + - nakedret + +linters-settings: + goimports: + local-prefixes: github.com/EGT-Ukraine/go2gql + gocyclo: + min-complexity: 20 # todo: decrease + lll: + line-length: 180 # todo: decrease + golint: + min-confidence: 0 + dupl: + threshold: 260 # todo: decrease diff --git a/.travis.yml b/.travis.yml index 6eff226..7bd0ea4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,4 +19,5 @@ env: script: - make test + - make lint - goveralls -race -service=travis-ci -repotoken $COVERALLS_TOKEN diff --git a/Makefile b/Makefile index 663f60c..7a7057f 100644 --- a/Makefile +++ b/Makefile @@ -15,4 +15,7 @@ test: $(MAKE) -C tests go test ./... +lint: + golangci-lint run -v + .PHONY: install diff --git a/api/multipart_file/file.go b/api/multipartfile/file.go similarity index 90% rename from api/multipart_file/file.go rename to api/multipartfile/file.go index 48d031a..f642346 100644 --- a/api/multipart_file/file.go +++ b/api/multipartfile/file.go @@ -1,4 +1,4 @@ -package multipart_file +package multipartfile import ( "mime/multipart" diff --git a/api/scalars/scalars.go b/api/scalars/scalars.go index 4a2ac64..c55034c 100644 --- a/api/scalars/scalars.go +++ b/api/scalars/scalars.go @@ -8,7 +8,7 @@ import ( "github.com/graphql-go/graphql/language/ast" "github.com/graphql-go/graphql/language/kinds" - "github.com/EGT-Ukraine/go2gql/api/multipart_file" + "github.com/EGT-Ukraine/go2gql/api/multipartfile" ) var GraphQLInt64Scalar = graphql.NewScalar(graphql.ScalarConfig{ @@ -23,7 +23,7 @@ var GraphQLInt64Scalar = graphql.NewScalar(graphql.ScalarConfig{ if val == nil { return nil } - return int64(*val) + return *val case int32: return int64(val) case *int32: @@ -88,7 +88,7 @@ var GraphQLInt32Scalar = graphql.NewScalar(graphql.ScalarConfig{ if val == nil { return nil } - return int32(*val) + return *val case int: return int32(val) case *int: @@ -114,7 +114,7 @@ var GraphQLInt32Scalar = graphql.NewScalar(graphql.ScalarConfig{ if val == nil { return nil } - return int32(*val) + return *val case int64: return int32(val) case *int64: @@ -156,7 +156,7 @@ var GraphQLUInt64Scalar = graphql.NewScalar(graphql.ScalarConfig{ if val == nil { return nil } - return uint64(*val) + return *val case uint32: return uint64(val) case *uint32: @@ -221,14 +221,14 @@ var GraphQLUInt32Scalar = graphql.NewScalar(graphql.ScalarConfig{ if val == nil { return nil } - return uint32(*val) + return *val case uint: return uint32(val) case *uint: if val == nil { return nil } - return uint(*val) + return *val } return nil @@ -330,7 +330,7 @@ var GraphQLFloat64Scalar = graphql.NewScalar(graphql.ScalarConfig{ if err != nil { return nil } - return float64(value) + return value case *string: if val == nil { return nil @@ -339,7 +339,7 @@ var GraphQLFloat64Scalar = graphql.NewScalar(graphql.ScalarConfig{ if err != nil { return nil } - return float64(value) + return value case float32: return float64(val) case *float32: @@ -366,7 +366,7 @@ var GraphQLFloat64Scalar = graphql.NewScalar(graphql.ScalarConfig{ if err != nil { return nil } - return float64(val) + return val } return nil @@ -426,9 +426,9 @@ var MultipartFile = graphql.NewScalar(graphql.ScalarConfig{ Description: "The `Upload` scalar type represents no data.", Serialize: func(value interface{}) interface{} { switch t := value.(type) { - case multipart_file.MultipartFile: + case multipartfile.MultipartFile: return t.Header.Filename - case *multipart_file.MultipartFile: + case *multipartfile.MultipartFile: return t.Header.Filename } @@ -436,9 +436,9 @@ var MultipartFile = graphql.NewScalar(graphql.ScalarConfig{ }, ParseValue: func(value interface{}) interface{} { switch t := value.(type) { - case multipart_file.MultipartFile: + case multipartfile.MultipartFile: return &t - case *multipart_file.MultipartFile: + case *multipartfile.MultipartFile: return t } diff --git a/cmd/go2gql/main.go b/cmd/go2gql/main.go index 9ec8953..81072e2 100644 --- a/cmd/go2gql/main.go +++ b/cmd/go2gql/main.go @@ -13,14 +13,14 @@ import ( "github.com/EGT-Ukraine/go2gql/generator" ) -var appFlags = []cli.Flag{ - cli.StringFlag{ - Name: "config, c", - Value: "generate.yml", - }, -} - func main() { + var appFlags = []cli.Flag{ + cli.StringFlag{ + Name: "config, c", + Value: "generate.yml", + }, + } + app := cli.App{ Flags: appFlags, Before: func(c *cli.Context) error { diff --git a/example/simple_plugin/plugin.go b/example/simple_plugin/plugin.go index 8e33af3..c5c493a 100644 --- a/example/simple_plugin/plugin.go +++ b/example/simple_plugin/plugin.go @@ -36,9 +36,18 @@ func (p plugin) Generate() error { if len(service.QueryMethods) == 0 { continue } - file.WriteString(service.Name + ":\n") + _, err := file.WriteString(service.Name + ":\n") + + if err != nil { + return errors.Wrap(err, "failed to write to file") + } + for _, method := range service.QueryMethods { - file.WriteString(" " + method.Name + ":\n") + _, err := file.WriteString(" " + method.Name + ":\n") + + if err != nil { + return errors.Wrap(err, "failed to write to file") + } } } } @@ -49,7 +58,7 @@ func (plugin) Prepare() error { return nil } func (plugin) PrintInfo(info generator.Infos) {} func (plugin) Infos() map[string]string { return nil } -func Plugin() generator.Plugin { +func Plugin() generator.Plugin { //nolint:deadcode return new(plugin) } diff --git a/generator/plugins/dataloader/config.go b/generator/plugins/dataloader/config.go index 9d8df9b..bce67db 100644 --- a/generator/plugins/dataloader/config.go +++ b/generator/plugins/dataloader/config.go @@ -3,11 +3,11 @@ package dataloader type DataLoadersConfig struct { OutputPath string `mapstructure:"output_path"` } -type DataLoaderProviderConfig struct { +type ProviderConfig struct { Name string `mapstructure:"name"` WaitDurationMs int `mapstructure:"wait_duration_ms"` } -type DataLoaderFieldConfig struct { +type FieldConfig struct { FieldName string `mapstructure:"field_name"` KeyFieldName string `mapstructure:"key_field_name"` DataLoader string `mapstructure:"data_loader_name"` diff --git a/generator/plugins/dataloader/data_loader_generator.go b/generator/plugins/dataloader/data_loader_generator.go index af6781c..185c170 100644 --- a/generator/plugins/dataloader/data_loader_generator.go +++ b/generator/plugins/dataloader/data_loader_generator.go @@ -3,6 +3,7 @@ package dataloader import ( "bytes" "fmt" + "io" "os" "reflect" "text/template" @@ -32,7 +33,7 @@ type Loader struct { RequestGoType graphql.GoType ResponseGoType graphql.GoType OutputGraphqlType graphql.TypeResolver - Config DataLoaderProviderConfig + Config ProviderConfig } type LoaderGenerator struct { @@ -201,7 +202,7 @@ func (p *LoaderGenerator) generateHead() ([]byte, error) { return buf.Bytes(), nil } -func (p *LoaderGenerator) renderLoaders(out *os.File) error { +func (p *LoaderGenerator) renderLoaders(out io.Writer) error { body, err := p.generateBody() if err != nil { return errors.Wrap(err, "failed to generate body") diff --git a/generator/plugins/dataloader/dataloader.go b/generator/plugins/dataloader/dataloader.go index 3ca49d5..ad8effc 100644 --- a/generator/plugins/dataloader/dataloader.go +++ b/generator/plugins/dataloader/dataloader.go @@ -25,10 +25,10 @@ type LoaderModel struct { OutputGoType graphql.GoType OutputGraphqlType graphql.TypeResolver FetchCode func(importer *importer.Importer) string - Config DataLoaderProviderConfig + Config ProviderConfig } -func (p *Plugin) createDataLoader(config *DataLoadersConfig, vendorPath string, files map[string]*graphql.TypesFile) (*DataLoader, error) { +func (p *Plugin) createDataLoader(config *DataLoadersConfig, vendorPath string) (*DataLoader, error) { if config == nil { return nil, nil } diff --git a/generator/plugins/dataloader/plugin.go b/generator/plugins/dataloader/plugin.go index 456fe1d..81f400d 100644 --- a/generator/plugins/dataloader/plugin.go +++ b/generator/plugins/dataloader/plugin.go @@ -108,7 +108,7 @@ func (p *Plugin) validateOutputObjects(gqlFiles map[string]*graphql.TypesFile) e if dataLoader.InputGoType.ElemType.Kind != outputArgument.GoType.Kind { // TODO: use type casting if possible. - return errors.New("Input argument must be same type as output") + return errors.New("input argument must be same type as output") } } } @@ -129,8 +129,7 @@ func (p *Plugin) Generate() error { return nil } - gqlFiles := p.gqlPlugin.Types() - dataLoader, err := p.createDataLoader(p.dataLoaderConfigs, p.generateCfg.VendorPath, gqlFiles) + dataLoader, err := p.createDataLoader(p.dataLoaderConfigs, p.generateCfg.VendorPath) if err != nil { return errors.Wrap(err, "failed to process dataloader config") @@ -142,7 +141,7 @@ func (p *Plugin) Generate() error { dataLoader: p.dataLoader, }) - if err := p.validateOutputObjects(gqlFiles); err != nil { + if err := p.validateOutputObjects(p.gqlPlugin.Types()); err != nil { return errors.Wrap(err, "failed to validate graphql files") } diff --git a/generator/plugins/graphql/models.go b/generator/plugins/graphql/models.go index c1b95ed..7e559a2 100644 --- a/generator/plugins/graphql/models.go +++ b/generator/plugins/graphql/models.go @@ -238,7 +238,7 @@ type gqlObject struct { } func (gqlObject *gqlObject) TypeName() string { - if gqlObject.QueryObject == true { + if gqlObject.QueryObject { return "Query" } diff --git a/generator/plugins/graphql/plugin.go b/generator/plugins/graphql/plugin.go index 56dd6a3..9b79bfb 100644 --- a/generator/plugins/graphql/plugin.go +++ b/generator/plugins/graphql/plugin.go @@ -83,15 +83,15 @@ func (p *Plugin) parseImportedSchema(cfg *SchemaConfig) error { schema := p.findSchemaByName(importedSchemaName) if schema == nil { - return errors.New("Schema " + importedSchemaName + " not defined") + return errors.New("schema " + importedSchemaName + " not defined") } if cfg.Queries != nil && schema.Queries.Type == SchemaNodeTypeService { - return errors.New("Cannot merge object with service in query") + return errors.New("cannot merge object with service in query") } if cfg.Mutations != nil && schema.Mutations.Type == SchemaNodeTypeService { - return errors.New("Cannot merge object with service in mutations") + return errors.New("cannot merge object with service in mutations") } if cfg.Queries != nil { @@ -221,7 +221,7 @@ func (p *Plugin) SchemasObjects() ([]SchemaObjects, error) { if err != nil { return nil, errors.Wrapf(err, "failed to resolve schema %s output go package", schema.Name) } - parser := NewSchemaParser(schema, p.files) + parser := newSchemaParser(schema, p.files) schemaContext, err := parser.SchemaObjects() diff --git a/generator/plugins/graphql/plugin_test.go b/generator/plugins/graphql/plugin_test.go index 5f83a6a..d22f010 100644 --- a/generator/plugins/graphql/plugin_test.go +++ b/generator/plugins/graphql/plugin_test.go @@ -60,7 +60,9 @@ graphql_schemas: Convey("When the graphql plugin is initialized", func() { graphqlPlugin := new(Plugin) - graphqlPlugin.Init(gc, []generator.Plugin{}) + if err := graphqlPlugin.Init(gc, []generator.Plugin{}); err != nil { + t.Fatalf(err.Error()) + } Convey("Graphql schema should be merged recursively", func() { So(graphqlPlugin.schemaConfigs[0], ShouldResemble, SchemaConfig{ @@ -70,23 +72,23 @@ graphql_schemas: Queries: &SchemaNodeConfig{ Type: "OBJECT", Fields: []SchemaNodeConfig{ - SchemaNodeConfig{ + { Type: "OBJECT", ObjectName: "Common", Field: "common", Fields: []SchemaNodeConfig{ - SchemaNodeConfig{ + { Type: "OBJECT", ObjectName: "CommonNested", Field: "commonNested", Fields: []SchemaNodeConfig{ - SchemaNodeConfig{ + { Type: "SERVICE", Service: "Service1", ObjectName: "Service1Object", Field: "service1Field", }, - SchemaNodeConfig{ + { Type: "SERVICE", Service: "Service2", ObjectName: "Service2Object", diff --git a/generator/plugins/graphql/schema_parser.go b/generator/plugins/graphql/schema_parser.go index eb1b4e9..3d6c505 100644 --- a/generator/plugins/graphql/schema_parser.go +++ b/generator/plugins/graphql/schema_parser.go @@ -19,7 +19,7 @@ type schemaParser struct { types map[string]*TypesFile } -func NewSchemaParser(schemaCfg SchemaConfig, types map[string]*TypesFile) *schemaParser { +func newSchemaParser(schemaCfg SchemaConfig, types map[string]*TypesFile) *schemaParser { return &schemaParser{schemaCfg, types} } @@ -70,7 +70,7 @@ func (g *schemaParser) resolveObjectFields(nodeCfg SchemaNodeConfig, object *gql var serviceMethods []Method - if object.QueryObject == true { + if object.QueryObject { serviceMethods = service.QueryMethods } else { serviceMethods = service.MutationMethods diff --git a/generator/plugins/graphql/schemas_generator.go b/generator/plugins/graphql/schemas_generator.go index ba34f3b..a3205d7 100644 --- a/generator/plugins/graphql/schemas_generator.go +++ b/generator/plugins/graphql/schemas_generator.go @@ -171,7 +171,7 @@ func (p *Plugin) generateSchemas() error { return errors.Wrapf(err, "failed to resolve schema %s output go package", schema.Name) } - parser := NewSchemaParser(schema, p.files) + parser := newSchemaParser(schema, p.files) g := schemaGenerator{ parser: parser, diff --git a/generator/plugins/graphql/types_generator.go b/generator/plugins/graphql/types_generator.go index d4f7944..5541c0e 100644 --- a/generator/plugins/graphql/types_generator.go +++ b/generator/plugins/graphql/types_generator.go @@ -17,7 +17,7 @@ import ( const ( ScalarsPkgPath = "github.com/EGT-Ukraine/go2gql/api/scalars" - MultipartFilePkgPath = "github.com/EGT-Ukraine/go2gql/api/multipart_file" + MultipartFilePkgPath = "github.com/EGT-Ukraine/go2gql/api/multipartfile" InterceptorsPkgPath = "github.com/EGT-Ukraine/go2gql/api/interceptors" GraphqlPkgPath = "github.com/graphql-go/graphql" OpentracingPkgPath = "github.com/opentracing/opentracing-go" diff --git a/generator/plugins/proto2gql/config.go b/generator/plugins/proto2gql/config.go index 7e94a68..54691c9 100644 --- a/generator/plugins/proto2gql/config.go +++ b/generator/plugins/proto2gql/config.go @@ -17,15 +17,15 @@ type FieldsConfig struct { ContextKey string `mapstructure:"context_key"` } type MessageConfig struct { - ErrorField string `mapstructure:"error_field"` - Fields map[string]FieldsConfig `mapstructure:"fields"` - DataLoaders []dataloader.DataLoaderFieldConfig `mapstructure:"data_loaders"` + ErrorField string `mapstructure:"error_field"` + Fields map[string]FieldsConfig `mapstructure:"fields"` + DataLoaders []dataloader.FieldConfig `mapstructure:"data_loaders"` } type MethodConfig struct { - Alias string `mapstructure:"alias"` - RequestType string `mapstructure:"request_type"` // QUERY | MUTATION - DataLoaderProvider dataloader.DataLoaderProviderConfig `mapstructure:"data_loader_provider"` - UnwrapResponseField bool `mapstructure:"unwrap_response_field"` + Alias string `mapstructure:"alias"` + RequestType string `mapstructure:"request_type"` // QUERY | MUTATION + DataLoaderProvider dataloader.ProviderConfig `mapstructure:"data_loader_provider"` + UnwrapResponseField bool `mapstructure:"unwrap_response_field"` } type ServiceConfig struct { ServiceName string `mapstructure:"service_name"` diff --git a/generator/plugins/proto2gql/enums.go b/generator/plugins/proto2gql/enums.go index 565fed0..35d1c06 100644 --- a/generator/plugins/proto2gql/enums.go +++ b/generator/plugins/proto2gql/enums.go @@ -19,7 +19,7 @@ func (g *Proto2GraphQL) enumVariable(enumFile *parsedFile, enum *parser.Enum) st return enumFile.Config.GetGQLEnumsPrefix() + camelCaseSlice(enum.TypeName) } -func (g *Proto2GraphQL) prepareFileEnums(file *parsedFile) ([]graphql.Enum, error) { +func (g *Proto2GraphQL) prepareFileEnums(file *parsedFile) []graphql.Enum { var res []graphql.Enum for _, enum := range file.File.Enums { vals := make([]graphql.EnumValue, len(enum.Values)) @@ -37,5 +37,6 @@ func (g *Proto2GraphQL) prepareFileEnums(file *parsedFile) ([]graphql.Enum, erro Values: vals, }) } - return res, nil + + return res } diff --git a/generator/plugins/proto2gql/generator.go b/generator/plugins/proto2gql/generator.go index 99bb1aa..7a09505 100644 --- a/generator/plugins/proto2gql/generator.go +++ b/generator/plugins/proto2gql/generator.go @@ -1,12 +1,12 @@ package proto2gql import ( - "github.com/EGT-Ukraine/go2gql/generator/plugins/dataloader" "path/filepath" "strings" "github.com/pkg/errors" + "github.com/EGT-Ukraine/go2gql/generator/plugins/dataloader" "github.com/EGT-Ukraine/go2gql/generator/plugins/graphql" "github.com/EGT-Ukraine/go2gql/generator/plugins/proto2gql/parser" ) @@ -88,10 +88,8 @@ func (g *Proto2GraphQL) parsedFile(file *parser.File) (*parsedFile, error) { } func (g *Proto2GraphQL) prepareFile(file *parsedFile) (*graphql.TypesFile, error) { - enums, err := g.prepareFileEnums(file) - if err != nil { - return nil, errors.Wrap(err, "failed to resolve file enums") - } + enums := g.prepareFileEnums(file) + inputs, err := g.fileInputObjects(file) if err != nil { return nil, errors.Wrap(err, "failed to prepare file input objects") diff --git a/generator/plugins/proto2gql/messages_inputs.go b/generator/plugins/proto2gql/messages_inputs.go index 7b975c6..8cd066e 100644 --- a/generator/plugins/proto2gql/messages_inputs.go +++ b/generator/plugins/proto2gql/messages_inputs.go @@ -15,14 +15,14 @@ func (g *Proto2GraphQL) inputMessageVariable(msgFile *parsedFile, message *parse return msgFile.Config.GetGQLMessagePrefix() + snakeCamelCaseSlice(message.TypeName) + "Input" } -func (g *Proto2GraphQL) inputMessageTypeResolver(msgFile *parsedFile, message *parser.Message) (graphql.TypeResolver, error) { +func (g *Proto2GraphQL) inputMessageTypeResolver(msgFile *parsedFile, message *parser.Message) graphql.TypeResolver { if !message.HaveFields() { - return graphql.GqlNoDataTypeResolver, nil + return graphql.GqlNoDataTypeResolver } return func(ctx graphql.BodyContext) string { return ctx.Importer.Prefix(msgFile.OutputPkg) + g.inputMessageVariable(msgFile, message) - }, nil + } } func (g *Proto2GraphQL) inputMessageFieldTypeResolver(file *parsedFile, field *parser.Field) (graphql.TypeResolver, error) { diff --git a/generator/plugins/proto2gql/messages_outputs.go b/generator/plugins/proto2gql/messages_outputs.go index 9deadcf..b38dc88 100644 --- a/generator/plugins/proto2gql/messages_outputs.go +++ b/generator/plugins/proto2gql/messages_outputs.go @@ -18,17 +18,17 @@ func (g *Proto2GraphQL) outputMessageVariable(messageFile *parsedFile, message * return messageFile.Config.GetGQLMessagePrefix() + snakeCamelCaseSlice(message.TypeName) } -func (g *Proto2GraphQL) outputMessageTypeResolver(messageFile *parsedFile, message *parser.Message) (graphql.TypeResolver, error) { +func (g *Proto2GraphQL) outputMessageTypeResolver(messageFile *parsedFile, message *parser.Message) graphql.TypeResolver { if !message.HaveFields() { - return graphql.GqlNoDataTypeResolver, nil + return graphql.GqlNoDataTypeResolver } return func(ctx graphql.BodyContext) string { return ctx.Importer.Prefix(messageFile.OutputPkg) + g.outputMessageVariable(messageFile, message) - }, nil + } } -func (g *Proto2GraphQL) outputMessageFields(msgCfg MessageConfig, file *parsedFile, msg *parser.Message) ([]graphql.ObjectField, error) { +func (g *Proto2GraphQL) outputMessageFields(msgCfg MessageConfig, msg *parser.Message) ([]graphql.ObjectField, error) { var res []graphql.ObjectField for _, field := range msg.Fields { if msgCfg.ErrorField == field.Name { @@ -110,7 +110,7 @@ func (g *Proto2GraphQL) outputMessageMapFields(msgCfg MessageConfig, file *parse return res, nil } -func (g *Proto2GraphQL) dataLoaderFields(configs []dataloader.DataLoaderFieldConfig, msg *parser.Message) ([]*graphql.DataLoaderField, error) { +func (g *Proto2GraphQL) dataLoaderFields(configs []dataloader.FieldConfig, msg *parser.Message) ([]*graphql.DataLoaderField, error) { var fields []*graphql.DataLoaderField for _, cfg := range configs { @@ -141,7 +141,7 @@ func (g *Proto2GraphQL) fileOutputMessages(file *parsedFile) ([]graphql.OutputOb if err != nil { return nil, errors.Wrapf(err, "failed to resolve message %s config", msg.Name) } - fields, err := g.outputMessageFields(cfg, file, msg) + fields, err := g.outputMessageFields(cfg, msg) if err != nil { return nil, errors.Wrapf(err, "failed to resolve message %s fields", msg.Name) } diff --git a/generator/plugins/proto2gql/parser/file.go b/generator/plugins/proto2gql/parser/file.go index e6a2e40..12b7cd3 100644 --- a/generator/plugins/proto2gql/parser/file.go +++ b/generator/plugins/proto2gql/parser/file.go @@ -43,19 +43,19 @@ func (f *File) findTypeInMessage(msg *Message, typ string) (Type, bool) { func (f *File) findSymbol(fullName string) (Type, bool) { symbol, ok := f.Descriptors[fullName] - if ok == true { + if ok { return symbol, ok - } else { - for _, importedFile := range f.Imports { - symbol, ok := importedFile.findSymbol(fullName) + } - if ok == true { - return symbol, ok - } - } + for _, importedFile := range f.Imports { + symbol, ok := importedFile.findSymbol(fullName) - return nil, false + if ok { + return symbol, ok + } } + + return nil, false } func (f *File) findType(name string, relativeToFullName string) (Type, bool) { @@ -87,7 +87,7 @@ func (f *File) findType(name string, relativeToFullName string) (Type, bool) { result, ok = f.findSymbol(scopeToTry) - if ok == true { + if ok { break } @@ -228,7 +228,7 @@ func (f *File) parseMessages() { func (f *File) parseMessagesInMessage(msgTypeName TypeName, msg *Message) { for _, el := range msg.Descriptor.Elements { - switch elv := el.(type) { + switch elv := el.(type) { // nolint:gocritic case *proto.Message: tn := msgTypeName.NewSubTypeName(elv.Name) m := message(f, elv, tn, msg) diff --git a/generator/plugins/proto2gql/parser/parser_test.go b/generator/plugins/proto2gql/parser/parser_test.go index a5c213f..f23d796 100644 --- a/generator/plugins/proto2gql/parser/parser_test.go +++ b/generator/plugins/proto2gql/parser/parser_test.go @@ -344,9 +344,9 @@ func CompareTypes(t1, t2 Type) { So(t1, ShouldNotBeNil) So(t2, ShouldNotBeNil) - switch t1.(type) { + switch typeType := t1.(type) { case *Scalar: - So(t1.(*Scalar).ScalarName, ShouldEqual, t2.(*Scalar).ScalarName) + So(typeType.ScalarName, ShouldEqual, t2.(*Scalar).ScalarName) case *Message: So(t1, ShouldEqual, t2) So(t1.File(), ShouldEqual, t2.File()) diff --git a/generator/plugins/proto2gql/plugin.go b/generator/plugins/proto2gql/plugin.go index 892a34c..5b5a681 100644 --- a/generator/plugins/proto2gql/plugin.go +++ b/generator/plugins/proto2gql/plugin.go @@ -36,10 +36,10 @@ func (p *Plugin) Init(config *generator.GenerateConfig, plugins []generator.Plug } if p.graphql == nil { - return errors.New("'graphql' plugin is not installed.") + return errors.New("'graphql' plugin is not installed") } if p.dataLoaderPlugin == nil { - return errors.New("'dataloader' plugin is not installed.") + return errors.New("'dataloader' plugin is not installed") } cfg := new(Config) err := mapstructure.Decode(config.PluginsConfigs[PluginConfigKey], cfg) @@ -105,9 +105,8 @@ func (p *Plugin) normalizeGenerateConfigPaths() error { func (p *Plugin) prepareFileConfig(fileCfg *ProtoFileConfig) { fileCfg.Paths = append(fileCfg.Paths, p.config.Paths...) - for _, aliases := range p.config.ImportsAliases { - fileCfg.ImportsAliases = append(fileCfg.ImportsAliases, aliases) - } + + fileCfg.ImportsAliases = append(fileCfg.ImportsAliases, p.config.ImportsAliases...) } func (p *Plugin) PrintInfo(info generator.Infos) { diff --git a/generator/plugins/proto2gql/resolvers.go b/generator/plugins/proto2gql/resolvers.go index e49ea34..a7e020a 100644 --- a/generator/plugins/proto2gql/resolvers.go +++ b/generator/plugins/proto2gql/resolvers.go @@ -23,10 +23,8 @@ func (g *Proto2GraphQL) TypeOutputTypeResolver(typeFile *parsedFile, typ parser. if !pType.HaveFieldsExcept(msgCfg.ErrorField) { return graphql.GqlNoDataTypeResolver, nil } - res, err := g.outputMessageTypeResolver(typeFile, pType) - if err != nil { - return nil, errors.Wrap(err, "failed to get message type resolver") - } + res := g.outputMessageTypeResolver(typeFile, pType) + return res, nil case *parser.Enum: file, err := g.parsedFile(pType.File()) @@ -52,10 +50,8 @@ func (g *Proto2GraphQL) TypeInputTypeResolver(typeFile *parsedFile, typ parser.T } return resolver, nil case *parser.Message: - res, err := g.inputMessageTypeResolver(typeFile, pType) - if err != nil { - return nil, errors.Wrap(err, "failed to get message type resolver") - } + res := g.inputMessageTypeResolver(typeFile, pType) + return res, nil case *parser.Enum: res, err := g.enumTypeResolver(typeFile, pType) @@ -177,11 +173,11 @@ func (g *Proto2GraphQL) FieldOutputValueResolver(fieldFile *parsedFile, fieldNam "\n return res" + "\n }(" + arg + ".Get" + camelCase(fieldName) + "())" }, nil - } else { - return func(arg string, ctx graphql.BodyContext) string { - return "int(" + arg + ".Get" + camelCase(fieldName) + "())" - }, nil } + + return func(arg string, ctx graphql.BodyContext) string { + return "int(" + arg + ".Get" + camelCase(fieldName) + "())" + }, nil } return func(arg string, ctx graphql.BodyContext) string { return arg + "// not implemented" diff --git a/generator/plugins/proto2gql/services.go b/generator/plugins/proto2gql/services.go index 98315bb..ad420c2 100644 --- a/generator/plugins/proto2gql/services.go +++ b/generator/plugins/proto2gql/services.go @@ -13,7 +13,7 @@ import ( "github.com/EGT-Ukraine/go2gql/generator/plugins/proto2gql/parser" ) -func (g Proto2GraphQL) serviceMethodArguments(file *parsedFile, cfg MethodConfig, method *parser.Method) ([]graphql.MethodArgument, error) { +func (g Proto2GraphQL) serviceMethodArguments(file *parsedFile, method *parser.Method) ([]graphql.MethodArgument, error) { var args []graphql.MethodArgument for _, field := range method.InputMessage.Fields { typeFile, err := g.parsedFile(field.Type.File()) @@ -207,7 +207,7 @@ func (g Proto2GraphQL) serviceMethod(sc ServiceConfig, cfg MethodConfig, file *p if err != nil { return nil, errors.Wrapf(err, "failed to get request go type for method: %s", method.Name) } - args, err := g.serviceMethodArguments(file, cfg, method) + args, err := g.serviceMethodArguments(file, method) if err != nil { return nil, errors.Wrap(err, "failed to prepare service method arguments") } @@ -297,7 +297,7 @@ func (g Proto2GraphQL) addDataLoaderProvider(sc ServiceConfig, cfg MethodConfig, return errors.Wrap(err, "failed to prepare service method arguments") } - if method.InputMessage.Fields[0].Repeated != true { + if !method.InputMessage.Fields[0].Repeated { return errors.Errorf("Service %s input message %s parameter must be repeated", svc.Name, method.Name) } @@ -359,7 +359,12 @@ func (g Proto2GraphQL) dataLoaderFetchCode(file *parsedFile, method *parser.Meth } } -func (g Proto2GraphQL) dataLoaderFetchCodeUnwrappedSlice(file *parsedFile, method *parser.Method, responseGoType graphql.GoType, outProtoType *parser.Field) func(importer *importer.Importer) string { +func (g Proto2GraphQL) dataLoaderFetchCodeUnwrappedSlice( + file *parsedFile, + method *parser.Method, + responseGoType graphql.GoType, + outProtoType *parser.Field) func(importer *importer.Importer) string { + return func(importer *importer.Importer) string { requestTypeName := method.InputMessage.Name requestFieldName := camelCase(method.InputMessage.Fields[0].Name) diff --git a/generator/plugins/swagger2gql/config.go b/generator/plugins/swagger2gql/config.go index 68ebe9f..305046b 100644 --- a/generator/plugins/swagger2gql/config.go +++ b/generator/plugins/swagger2gql/config.go @@ -13,14 +13,14 @@ type FieldConfig struct { ContextKey string `mapstructure:"context_key"` } type ObjectConfig struct { - Fields map[string]FieldConfig `mapstructure:"fields"` - DataLoaders []dataloader.DataLoaderFieldConfig `mapstructure:"data_loaders"` + Fields map[string]FieldConfig `mapstructure:"fields"` + DataLoaders []dataloader.FieldConfig `mapstructure:"data_loaders"` } type MethodConfig struct { - Alias string `mapstructure:"alias"` - RequestType string `mapstructure:"request_type"` // QUERY | MUTATION - DataLoaderProvider dataloader.DataLoaderProviderConfig `mapstructure:"data_loader_provider"` + Alias string `mapstructure:"alias"` + RequestType string `mapstructure:"request_type"` // QUERY | MUTATION + DataLoaderProvider dataloader.ProviderConfig `mapstructure:"data_loader_provider"` } type TagConfig struct { ClientGoPackage string `mapstructure:"client_go_package"` @@ -94,7 +94,7 @@ func (pc *SwaggerFileConfig) FieldConfig(objName string, fieldName string) (Fiel paramCfg, ok := cfg.Fields[paramGqlName] - if ok == true { + if ok { return paramCfg, nil } } diff --git a/generator/plugins/swagger2gql/helpers.go b/generator/plugins/swagger2gql/helpers.go index d2ecd92..aaba385 100644 --- a/generator/plugins/swagger2gql/helpers.go +++ b/generator/plugins/swagger2gql/helpers.go @@ -129,74 +129,10 @@ func (p *Plugin) goTypeByParserType(typeFile *parsedFile, typ parser.Type, ptrOb return } -// Is c an ASCII lower-case letter? -func isASCIILower(c byte) bool { - return 'a' <= c && c <= 'z' -} - -// Is c an ASCII digit? -func isASCIIDigit(c byte) bool { - return '0' <= c && c <= '9' -} - -func camelCase(s string) string { - if s == "" { - return "" - } - t := make([]byte, 0, 32) - i := 0 - if s[0] == '_' { - // Need a capital letter; drop the '_'. - t = append(t, 'X') - i++ - } - // Invariant: if the next letter is lower case, it must be converted - // to upper case. - // That is, we process a word at a time, where words are marked by _ or - // upper case letter. Digits are treated as words. - for ; i < len(s); i++ { - c := s[i] - if c == '_' && i+1 < len(s) && isASCIILower(s[i+1]) { - continue // Skip the underscore in s. - } - if isASCIIDigit(c) { - t = append(t, c) - continue - } - // Assume we have a letter now - if not, it's a bogus identifier. - // The next word is a sequence of characters that must start upper case. - if isASCIILower(c) { - c ^= ' ' // Make it a capital letter. - } - t = append(t, c) // Guaranteed not lower case. - // Accept lower case sequence that follows. - for i+1 < len(s) && isASCIILower(s[i+1]) { - i++ - t = append(t, s[i]) - } - } - return string(t) -} -func pascalizeWithFirstLower(str string) string { - str = strings.NewReplacer(">=", "Ge", "<=", "Le", ">", "Gt", "<", "Lt", "=", "Eq").Replace(str) - if len(str) == 0 || str[0] > '9' { - return swag.ToVarName(str) - } - if str[0] == '+' { - return swag.ToGoName("Plus " + str[1:]) - } - if str[0] == '-' { - return swag.ToGoName("Minus " + str[1:]) - } - - return swag.ToGoName("Nr " + str) -} - // camelCaseSlice is like camelCase, but the argument is a slice of strings to // be joined with "_". func camelCaseSlice(elem []string) string { return pascalize(strings.Join(elem, "")) } func snakeCamelCaseSlice(elem []string) string { return pascalize(strings.Join(elem, "_")) } -func dotedTypeName(elems []string) string { return pascalize(strings.Join(elems, ".")) } func pascalize(arg string) string { arg = strings.NewReplacer(">=", "Ge", "<=", "Le", ">", "Gt", "<", "Lt", "=", "Eq").Replace(arg) if len(arg) == 0 || arg[0] > '9' { diff --git a/generator/plugins/swagger2gql/input_object_resolvers.go b/generator/plugins/swagger2gql/input_object_resolvers.go index 8dff0df..3ad6739 100644 --- a/generator/plugins/swagger2gql/input_object_resolvers.go +++ b/generator/plugins/swagger2gql/input_object_resolvers.go @@ -11,10 +11,10 @@ import ( "github.com/EGT-Ukraine/go2gql/generator/plugins/swagger2gql/parser" ) -func (p *Plugin) objectResolverFunctionName(file *parsedFile, obj *parser.Object) string { +func (p *Plugin) objectResolverFunctionName(obj *parser.Object) string { return "Resolve" + snakeCamelCaseSlice(obj.Route) } -func (p *Plugin) methodParametersObjectResolverFuncName(file *parsedFile, method parser.Method) string { +func (p *Plugin) methodParametersObjectResolverFuncName(method parser.Method) string { return "Resolve" + pascalize(method.OperationID) + "Params" } @@ -48,7 +48,7 @@ func (p *Plugin) methodParametersInputObjectResolver(file *parsedFile, tag strin } return &graphql.InputObjectResolver{ - FunctionName: p.methodParametersObjectResolverFuncName(file, method), + FunctionName: p.methodParametersObjectResolverFuncName(method), Fields: fields, OutputGoType: graphql.GoType{ Kind: reflect.Ptr, @@ -115,7 +115,7 @@ func (p *Plugin) fileInputMessagesResolvers(file *parsedFile) ([]graphql.InputOb return fields[i].GraphQLInputFieldName > fields[j].GraphQLInputFieldName }) res = append(res, graphql.InputObjectResolver{ - FunctionName: p.objectResolverFunctionName(file, t), + FunctionName: p.objectResolverFunctionName(t), Fields: fields, OutputGoType: resGoType, }) diff --git a/generator/plugins/swagger2gql/input_objects.go b/generator/plugins/swagger2gql/input_objects.go index 39cbf99..a6c0726 100644 --- a/generator/plugins/swagger2gql/input_objects.go +++ b/generator/plugins/swagger2gql/input_objects.go @@ -18,9 +18,6 @@ func (p *Plugin) inputObjectGQLName(file *parsedFile, obj *parser.Object) string func (p *Plugin) inputObjectVariable(msgFile *parsedFile, obj *parser.Object) string { return msgFile.Config.GetGQLMessagePrefix() + pascalize(strings.Join(obj.Route, "")) + "Input" } -func (p *Plugin) methodParamsInputObjectVariable(file *parsedFile, method parser.Method) string { - return file.Config.GetGQLMessagePrefix() + pascalize(method.OperationID+"Params") + "Input" -} func (p *Plugin) methodParamsInputObjectGQLName(file *parsedFile, method parser.Method) string { return file.Config.GetGQLMessagePrefix() + pascalize(method.OperationID+"Params") + "Input" } diff --git a/generator/plugins/swagger2gql/map_input_objects.go b/generator/plugins/swagger2gql/map_input_objects.go index acd66de..d0b8320 100644 --- a/generator/plugins/swagger2gql/map_input_objects.go +++ b/generator/plugins/swagger2gql/map_input_objects.go @@ -16,11 +16,6 @@ func (p *Plugin) mapInputObjectVariable(messageFile *parsedFile, obj *parser.Map return messageFile.Config.GetGQLMessagePrefix() + pascalize(strings.Join(obj.Route, "")) + "Input" } -func (p *Plugin) mapInputMessageTypeResolver(messageFile *parsedFile, obj *parser.Map) (graphql.TypeResolver, error) { - return func(ctx graphql.BodyContext) string { - return ctx.Importer.Prefix(messageFile.OutputPkg) + p.mapInputObjectVariable(messageFile, obj) - }, nil -} func (p *Plugin) fileMapInputMessages(file *parsedFile) ([]graphql.MapInputObject, error) { var res []graphql.MapInputObject handledObjects := map[parser.Type]struct{}{} diff --git a/generator/plugins/swagger2gql/map_input_objects_resolvers.go b/generator/plugins/swagger2gql/map_input_objects_resolvers.go index d9967fb..901849a 100644 --- a/generator/plugins/swagger2gql/map_input_objects_resolvers.go +++ b/generator/plugins/swagger2gql/map_input_objects_resolvers.go @@ -26,6 +26,11 @@ func (p *Plugin) fileInputMapResolvers(file *parsedFile) ([]graphql.MapInputObje return errors.Wrap(err, "failed to resolve map value go type") } valueResolver, valueWithErr, _, err := p.TypeValueResolver(file, t.ElemType, false, "") + + if err != nil { + return err + } + res = append(res, graphql.MapInputObjectResolver{ FunctionName: p.mapResolverFunctionName(file, t), KeyGoType: graphql.GoType{ diff --git a/generator/plugins/swagger2gql/map_output_objects.go b/generator/plugins/swagger2gql/map_output_objects.go index f5201f0..d05161c 100644 --- a/generator/plugins/swagger2gql/map_output_objects.go +++ b/generator/plugins/swagger2gql/map_output_objects.go @@ -16,11 +16,6 @@ func (p *Plugin) mapOutputObjectVariable(messageFile *parsedFile, obj *parser.Ma return messageFile.Config.GetGQLMessagePrefix() + strings.Join(obj.Route, "") } -func (p *Plugin) mapOutputMessageTypeResolver(messageFile *parsedFile, obj *parser.Map) (graphql.TypeResolver, error) { - return func(ctx graphql.BodyContext) string { - return ctx.Importer.Prefix(messageFile.OutputPkg) + p.mapOutputObjectVariable(messageFile, obj) - }, nil -} func (p *Plugin) fileMapOutputMessages(file *parsedFile) ([]graphql.MapOutputObject, error) { var res []graphql.MapOutputObject handledObjects := map[parser.Type]struct{}{} diff --git a/generator/plugins/swagger2gql/output_object.go b/generator/plugins/swagger2gql/output_object.go index f1d8708..fa08935 100644 --- a/generator/plugins/swagger2gql/output_object.go +++ b/generator/plugins/swagger2gql/output_object.go @@ -20,13 +20,13 @@ func (p *Plugin) outputObjectVariable(messageFile *parsedFile, obj *parser.Objec return messageFile.Config.GetGQLMessagePrefix() + pascalize(strings.Join(obj.Route, "")) } -func (p *Plugin) outputMessageTypeResolver(messageFile *parsedFile, obj *parser.Object) (graphql.TypeResolver, error) { +func (p *Plugin) outputMessageTypeResolver(messageFile *parsedFile, obj *parser.Object) graphql.TypeResolver { if len(obj.Properties) == 0 { - return graphql.GqlNoDataTypeResolver, nil + return graphql.GqlNoDataTypeResolver } return func(ctx graphql.BodyContext) string { return ctx.Importer.Prefix(messageFile.OutputPkg) + p.outputObjectVariable(messageFile, obj) - }, nil + } } func (p *Plugin) fileOutputMessages(file *parsedFile) ([]graphql.OutputObject, error) { @@ -136,7 +136,7 @@ func (p *Plugin) fileOutputMessages(file *parsedFile) ([]graphql.OutputObject, e return res, nil } -func (p *Plugin) dataLoaderFields(configs []dataloader.DataLoaderFieldConfig, object *parser.Object) ([]*graphql.DataLoaderField, error) { +func (p *Plugin) dataLoaderFields(configs []dataloader.FieldConfig, object *parser.Object) ([]*graphql.DataLoaderField, error) { var fields []*graphql.DataLoaderField for _, cfg := range configs { diff --git a/generator/plugins/swagger2gql/parser/parser.go b/generator/plugins/swagger2gql/parser/parser.go index 3149c5a..ed336c2 100644 --- a/generator/plugins/swagger2gql/parser/parser.go +++ b/generator/plugins/swagger2gql/parser/parser.go @@ -80,9 +80,9 @@ func resolveScalarType(typ string, format string, enum []interface{}) (Type, err values[i] = enum.(string) } return scalarString, nil - } else { - return scalarString, nil } + + return scalarString, nil case "file": return scalarFile, nil } diff --git a/generator/plugins/swagger2gql/plugin.go b/generator/plugins/swagger2gql/plugin.go index 69a72c6..96927f5 100644 --- a/generator/plugins/swagger2gql/plugin.go +++ b/generator/plugins/swagger2gql/plugin.go @@ -25,8 +25,6 @@ type Plugin struct { dataLoaderPlugin *dataloader.Plugin config *Config generateConfig *generator.GenerateConfig - - parsedFiles []*parsedFile } func (p *Plugin) Init(config *generator.GenerateConfig, plugins []generator.Plugin) error { @@ -39,10 +37,10 @@ func (p *Plugin) Init(config *generator.GenerateConfig, plugins []generator.Plug } } if p.graphql == nil { - return errors.New("'graphql' plugin is not installed.") + return errors.New("'graphql' plugin is not installed") } if p.dataLoaderPlugin == nil { - return errors.New("'dataloader' plugin is not installed.") + return errors.New("'dataloader' plugin is not installed") } cfg := new(Config) err := mapstructure.Decode(config.PluginsConfigs[PluginConfigKey], cfg) diff --git a/generator/plugins/swagger2gql/resolvers.go b/generator/plugins/swagger2gql/resolvers.go index 9ed01cc..5ad2683 100644 --- a/generator/plugins/swagger2gql/resolvers.go +++ b/generator/plugins/swagger2gql/resolvers.go @@ -29,11 +29,7 @@ func (p *Plugin) TypeOutputTypeResolver(typeFile *parsedFile, typ parser.Type, r } res = resolver case *parser.Object: - msgResolver, err := p.outputMessageTypeResolver(typeFile, t) - if err != nil { - return nil, errors.Wrap(err, "failed to get message type resolver") - } - res = msgResolver + res = p.outputMessageTypeResolver(typeFile, t) case *parser.Array: elemResolver, err := p.TypeOutputTypeResolver(typeFile, t.ElemType, true) if err != nil { @@ -77,7 +73,12 @@ func (p *Plugin) TypeInputTypeResolver(typeFile *parsedFile, typ parser.Type) (g } return nil, errors.New("not implemented " + typ.Kind().String()) } -func (p *Plugin) TypeValueResolver(file *parsedFile, typ parser.Type, required bool, ctxKey string) (_ graphql.ValueResolver, withErr, fromArgs bool, err error) { +func (p *Plugin) TypeValueResolver( + file *parsedFile, + typ parser.Type, + required bool, + ctxKey string) (_ graphql.ValueResolver, withErr, fromArgs bool, err error) { + if ctxKey != "" { goType, err := p.goTypeByParserType(file, typ, true) if err != nil { @@ -152,13 +153,13 @@ func (p *Plugin) TypeValueResolver(file *parsedFile, typ parser.Type, required b panic(errors.Wrap(err, "failed to render ptr datetime resolver")) } return res - } else { - res, err := p.renderDatetimeValueResolverTemplate(arg, ctx) - if err != nil { - panic(errors.Wrap(err, "failed to render ptr datetime resolver")) - } - return res } + + res, err := p.renderDatetimeValueResolverTemplate(arg, ctx) + if err != nil { + panic(errors.Wrap(err, "failed to render ptr datetime resolver")) + } + return res }, true, true, nil } return graphql.ResolverCall(file.OutputPkg, "Resolve"+snakeCamelCaseSlice(t.Route)), true, true, nil diff --git a/generator/plugins/swagger2gql/services.go b/generator/plugins/swagger2gql/services.go index 1a53b94..f90de26 100644 --- a/generator/plugins/swagger2gql/services.go +++ b/generator/plugins/swagger2gql/services.go @@ -95,6 +95,9 @@ func (p *Plugin) graphqlMethod(tagCfg TagConfig, methodCfg MethodConfig, file *p panic(errors.Wrap(err, "failed to resolve result go type")) } res, err = p.renderMethodCaller(respType.String(ctx.Importer), reqType.String(ctx.Importer), req, client, pascalize(method.OperationID)) + if err != nil { + panic(errors.Wrap(err, "failed to render method caller")) + } } if err != nil { panic(errors.Wrap(err, "failed to render method caller")) @@ -123,13 +126,21 @@ func (p *Plugin) addDataLoaderProvider( resType, ok := successResponseResultType.(*parser.Array) if !ok { - return errors.New("Response type must be array") + return errors.New("response type must be array") } responseGoType, err := p.goTypeByParserType(file, resType.ElemType, true) + if err != nil { + return err + } + dataLoaderOutType, err := p.TypeOutputTypeResolver(file, resType.ElemType, false) + if err != nil { + return err + } + if len(method.Parameters) != 1 { return errors.Errorf("Method %s %s must have 1 input parameter", method.HTTPMethod, method.Path) } diff --git a/generator/plugins/swagger2gql/templates_resolvers.go b/generator/plugins/swagger2gql/templates_resolvers.go index e4a279d..1177745 100644 --- a/generator/plugins/swagger2gql/templates_resolvers.go +++ b/generator/plugins/swagger2gql/templates_resolvers.go @@ -9,7 +9,13 @@ import ( "github.com/EGT-Ukraine/go2gql/generator/plugins/graphql" ) -func (p *Plugin) renderArrayValueResolver(arg string, resultGoTyp graphql.GoType, ctx graphql.BodyContext, elemResolver graphql.ValueResolver, elemResolverWithErr bool) (string, error) { +func (p *Plugin) renderArrayValueResolver( + arg string, + resultGoTyp graphql.GoType, + ctx graphql.BodyContext, + elemResolver graphql.ValueResolver, + elemResolverWithErr bool) (string, error) { + tplBody, err := templatesValue_resolver_arrayGohtmlBytes() if err != nil { panic(errors.Wrap(err, "failed to get array value resolver template").Error()) diff --git a/tests/Makefile b/tests/Makefile index e4535c3..fd3d002 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -1,3 +1,3 @@ test: $(MAKE) -C dataloader/ - $(MAKE) -C proto_unwrap/ + $(MAKE) -C protounwrap/ diff --git a/tests/dataloader/dataloader_test.go b/tests/dataloader/dataloader_test.go index f6ad31d..b994d6e 100644 --- a/tests/dataloader/dataloader_test.go +++ b/tests/dataloader/dataloader_test.go @@ -433,5 +433,5 @@ func makeRequest(t *testing.T, clients *mock.Clients, opts *handler.RequestOptio ctx = loaders.GetContextWithLoaders(ctx, loadersAPIClients) - return tests.MakeRequest(apiSchema, opts, ctx) + return tests.MakeRequest(ctx, apiSchema, opts) } diff --git a/tests/proto_unwrap/Makefile b/tests/protounwrap/Makefile similarity index 100% rename from tests/proto_unwrap/Makefile rename to tests/protounwrap/Makefile diff --git a/tests/proto_unwrap/apis/items.proto b/tests/protounwrap/apis/items.proto similarity index 81% rename from tests/proto_unwrap/apis/items.proto rename to tests/protounwrap/apis/items.proto index 6e2ede4..2b224f6 100644 --- a/tests/proto_unwrap/apis/items.proto +++ b/tests/protounwrap/apis/items.proto @@ -2,7 +2,7 @@ syntax = "proto3"; package apis; -option go_package = "github.com/EGT-Ukraine/go2gql/tests/proto_unwrap/generated/clients/apis;apis"; +option go_package = "github.com/EGT-Ukraine/go2gql/tests/protounwrap/generated/clients/apis;apis"; import "google/protobuf/empty.proto"; diff --git a/tests/proto_unwrap/generate.yml b/tests/protounwrap/generate.yml similarity index 100% rename from tests/proto_unwrap/generate.yml rename to tests/protounwrap/generate.yml diff --git a/tests/proto_unwrap/mock/item.go b/tests/protounwrap/mock/item.go similarity index 93% rename from tests/proto_unwrap/mock/item.go rename to tests/protounwrap/mock/item.go index 91d9524..044ddaf 100644 --- a/tests/proto_unwrap/mock/item.go +++ b/tests/protounwrap/mock/item.go @@ -1,16 +1,18 @@ // Code generated by MockGen. DO NOT EDIT. -// Source: github.com/EGT-Ukraine/go2gql/tests/proto_unwrap/generated/clients/apis (interfaces: ItemsServiceClient) +// Source: github.com/EGT-Ukraine/go2gql/tests/protounwrap/generated/clients/apis (interfaces: ItemsServiceClient) // Package mock is a generated GoMock package. package mock import ( context "context" - apis "github.com/EGT-Ukraine/go2gql/tests/proto_unwrap/generated/clients/apis" + reflect "reflect" + gomock "github.com/golang/mock/gomock" empty "github.com/golang/protobuf/ptypes/empty" grpc "google.golang.org/grpc" - reflect "reflect" + + apis "github.com/EGT-Ukraine/go2gql/tests/protounwrap/generated/clients/apis" ) // MockItemsServiceClient is a mock of ItemsServiceClient interface diff --git a/tests/proto_unwrap/mock/loader.go b/tests/protounwrap/mock/loader.go similarity index 53% rename from tests/proto_unwrap/mock/loader.go rename to tests/protounwrap/mock/loader.go index 4f13e8a..4ef7d23 100644 --- a/tests/proto_unwrap/mock/loader.go +++ b/tests/protounwrap/mock/loader.go @@ -1,7 +1,7 @@ package mock import ( - "github.com/EGT-Ukraine/go2gql/tests/proto_unwrap/generated/clients/apis" + "github.com/EGT-Ukraine/go2gql/tests/protounwrap/generated/clients/apis" ) type Clients struct { diff --git a/tests/proto_unwrap/proto_unwrap_test.go b/tests/protounwrap/proto_unwrap_test.go similarity index 88% rename from tests/proto_unwrap/proto_unwrap_test.go rename to tests/protounwrap/proto_unwrap_test.go index bde6089..efa4653 100644 --- a/tests/proto_unwrap/proto_unwrap_test.go +++ b/tests/protounwrap/proto_unwrap_test.go @@ -1,4 +1,4 @@ -package proto_unwrap +package protounwrap import ( "context" @@ -10,9 +10,9 @@ import ( "github.com/EGT-Ukraine/go2gql/api/interceptors" "github.com/EGT-Ukraine/go2gql/tests" - "github.com/EGT-Ukraine/go2gql/tests/proto_unwrap/generated/clients/apis" - "github.com/EGT-Ukraine/go2gql/tests/proto_unwrap/generated/schema" - "github.com/EGT-Ukraine/go2gql/tests/proto_unwrap/mock" + "github.com/EGT-Ukraine/go2gql/tests/protounwrap/generated/clients/apis" + "github.com/EGT-Ukraine/go2gql/tests/protounwrap/generated/schema" + "github.com/EGT-Ukraine/go2gql/tests/protounwrap/mock" ) //go:generate mockgen -destination=mock/item.go -package=mock github.com/EGT-Ukraine/go2gql/tests/proto_unwrap/generated/clients/apis ItemsServiceClient @@ -111,5 +111,5 @@ func makeRequest(t *testing.T, clients *mock.Clients, opts *handler.RequestOptio ctx := context.Background() - return tests.MakeRequest(apiSchema, opts, ctx) + return tests.MakeRequest(ctx, apiSchema, opts) } diff --git a/tests/utils.go b/tests/utils.go index cfc6633..b2ffdf8 100644 --- a/tests/utils.go +++ b/tests/utils.go @@ -10,7 +10,7 @@ import ( "github.com/graphql-go/handler" ) -func MakeRequest(schema graphql.Schema, opts *handler.RequestOptions, ctx context.Context) *graphql.Result { +func MakeRequest(ctx context.Context, schema graphql.Schema, opts *handler.RequestOptions) *graphql.Result { return graphql.Do(graphql.Params{ Schema: schema, RequestString: opts.Query, From 4d18834c812e9cf5a1b8f8caebd53853aee780af Mon Sep 17 00:00:00 2001 From: Dmitriy Garanzha Date: Thu, 24 Jan 2019 11:59:27 +0200 Subject: [PATCH 2/2] Linter. --- .travis.yml | 1 + cmd/go2gql/main.go | 14 +++++++------- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/.travis.yml b/.travis.yml index 7bd0ea4..bf3bdda 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,6 +13,7 @@ install: - curl -L https://github.com/google/protobuf/releases/download/v3.6.1/protoc-3.6.1-linux-x86_64.zip -o /tmp/protoc.zip - unzip /tmp/protoc.zip -d "$HOME"/protoc - mkdir -p "$HOME"/src && ln -s "$HOME"/protoc "$HOME"/src/protobuf + - curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s -- -b $(go env GOPATH)/bin v1.12.3 env: - PATH=$HOME/protoc/bin:$PATH diff --git a/cmd/go2gql/main.go b/cmd/go2gql/main.go index 81072e2..9ec8953 100644 --- a/cmd/go2gql/main.go +++ b/cmd/go2gql/main.go @@ -13,14 +13,14 @@ import ( "github.com/EGT-Ukraine/go2gql/generator" ) -func main() { - var appFlags = []cli.Flag{ - cli.StringFlag{ - Name: "config, c", - Value: "generate.yml", - }, - } +var appFlags = []cli.Flag{ + cli.StringFlag{ + Name: "config, c", + Value: "generate.yml", + }, +} +func main() { app := cli.App{ Flags: appFlags, Before: func(c *cli.Context) error {