diff --git a/cmd/protoc-gen-goclay/genhandler/handler.go b/cmd/protoc-gen-goclay/genhandler/handler.go index f16af31..4f695a5 100644 --- a/cmd/protoc-gen-goclay/genhandler/handler.go +++ b/cmd/protoc-gen-goclay/genhandler/handler.go @@ -99,6 +99,31 @@ func (g *Generator) generateDesc(file *descriptor.File) (*plugin.CodeGeneratorRe }, nil } +func (g *Generator) generateSwaggerFile(file *descriptor.File) *plugin.CodeGeneratorResponse_File { + if g.options.SwaggerPath == "" || len(g.options.SwaggerDef) == 0 { + return nil + } + + swaggerContent := g.options.SwaggerDef[file.GetName()] + if swaggerContent == nil { + return nil + } + + name := filepath.Base(file.GetName()) + ext := filepath.Ext(name) + base := strings.TrimSuffix(name, ext) + + output := fmt.Sprintf(filepath.Join(g.options.SwaggerPath, "%s.json"), base) + output = filepath.Clean(output) + + glog.V(1).Infof("Will emit %s", output) + + return &plugin.CodeGeneratorResponse_File{ + Name: proto.String(output), + Content: proto.String(string(swaggerContent)), + } +} + func (g *Generator) generateImpl(file *descriptor.File) (files []*plugin.CodeGeneratorResponse_File, err error) { guessModule() var pkg *ast.Package @@ -242,6 +267,10 @@ func (g *Generator) Generate(targets []*descriptor.File) ([]*plugin.CodeGenerato return nil, err } + if swaggerFile := g.generateSwaggerFile(file); swaggerFile != nil { + files = append(files, swaggerFile) + } + if g.options.Impl { if code, err := g.generateImpl(file); err == nil { files = append(files, code...) diff --git a/cmd/protoc-gen-goclay/genhandler/options.go b/cmd/protoc-gen-goclay/genhandler/options.go index e427bcc..a069be1 100644 --- a/cmd/protoc-gen-goclay/genhandler/options.go +++ b/cmd/protoc-gen-goclay/genhandler/options.go @@ -4,6 +4,7 @@ type options struct { ImplPath string DescPath string SwaggerDef map[string][]byte + SwaggerPath string Impl bool Force bool ServiceSubDir bool @@ -21,6 +22,13 @@ func SwaggerDef(swaggerDef map[string][]byte) Option { } } +// SwaggerPath sets path to store separate swagger files +func SwaggerPath(swaggerPath string) Option { + return func(o *options) { + o.SwaggerPath = swaggerPath + } +} + // ApplyDefaultMiddlewares toggles application of httpruntime/httpmw.DefaultChain to // every generated handler. func ApplyDefaultMiddlewares(apply bool) Option { diff --git a/cmd/protoc-gen-goclay/main.go b/cmd/protoc-gen-goclay/main.go index df6e4fc..4a666d5 100644 --- a/cmd/protoc-gen-goclay/main.go +++ b/cmd/protoc-gen-goclay/main.go @@ -22,6 +22,7 @@ var ( grpcAPIConfiguration = flag.String("grpc_api_configuration", "", "path to gRPC API Configuration in YAML format") withImpl = flag.Bool("impl", false, "generate simple implementations for proto Services. Implementation will not be generated if it already exists. See also `force` option") withSwagger = flag.Bool("swagger", true, "generate swagger.json") + withSwaggerPath = flag.String("swagger_path", "", "in addition to swagger in pb.goclay.go, generate separate swagger file at provided path") applyHTTPMiddlewares = flag.Bool("http_middlewares", true, "apply default HTTP millewares") implPath = flag.String("impl_path", "", "path where the implementation is generated (for impl = true)") forceImpl = flag.Bool("force", false, "force regenerate implementation if it already exists (for impl = true)") @@ -112,6 +113,10 @@ func main() { opts = append(opts, genhandler.SwaggerDef(swagBuf)) } + if *withSwaggerPath != "" { + opts = append(opts, genhandler.SwaggerPath(*withSwaggerPath)) + } + g := genhandler.New(reg, opts...) var targets []*descriptor.File