From 171640bb25ea05a8a4c6bf3f5461a3498ebd364c Mon Sep 17 00:00:00 2001 From: Trock Date: Wed, 14 Sep 2022 19:14:06 +0800 Subject: [PATCH] fix: template refactor --- Makefile | 6 +- cmd/truss/main.go | 3 + commit_date.sh | 22 ------ deftree/gogo/helper.go | 39 +++-------- gengokit/handlers/handler_test.go | 58 ++++++---------- gengokit/handlers/handlers.go | 7 +- gengokit/handlers/templates/hook.go | 22 ------ gengokit/httptransport/get_source.go | 29 +++----- gengokit/httptransport/httptransport.go | 33 +++++---- gengokit/httptransport/templates/client.go | 7 +- gengokit/httptransport/templates/server.go | 9 ++- .../svc/client/grpc/client.gotemplate | 6 +- .../svc/client/http/client.gotemplate | 2 +- .../NAME-service/svc/endpoints.gotemplate | 68 ++++++++----------- .../svc/transport_grpc.gotemplate | 2 +- .../svc/transport_http.gotemplate | 2 +- go.mod | 2 +- go.sum | 21 ++---- svcdef/consolidate_http.go | 2 +- svcdef/svcparse/parser.go | 32 +++++---- svcdef/svcparse/scanner.go | 32 ++++----- truss/parsesvcname/parsesvcname.go | 10 ++- truss/parsesvcname/parsesvcname_test.go | 3 + 23 files changed, 152 insertions(+), 265 deletions(-) delete mode 100644 commit_date.sh delete mode 100644 gengokit/handlers/templates/hook.go diff --git a/Makefile b/Makefile index 83d281e..260ff0d 100644 --- a/Makefile +++ b/Makefile @@ -3,16 +3,12 @@ SHA := $(shell git rev-parse --short=10 HEAD) MAKEFILE_PATH := $(dir $(abspath $(lastword $(MAKEFILE_LIST)))) -VERSION_DATE := $(shell $(MAKEFILE_PATH)/commit_date.sh) # Build native Truss by default. default: truss dependencies: go get -u google.golang.org/genproto - go get -u github.com/gogo/protobuf/protoc-gen-gogo - go get -u github.com/gogo/protobuf/protoc-gen-gogofaster - go get -u github.com/gogo/protobuf/protoc-gen-gofast go get -u github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway go get -u github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2 go get -u google.golang.org/grpc/cmd/protoc-gen-go-grpc @@ -21,7 +17,7 @@ dependencies: # Install truss truss: - go install -ldflags '-X "main.version=$(SHA)" -X "main.date=$(VERSION_DATE)"' github.com/DoNewsCode/truss/cmd/truss + go install -ldflags '-X "main.version=$(SHA)"' github.com/DoNewsCode/truss/cmd/truss # Run the go tests and the truss integration tests test: test-go diff --git a/cmd/truss/main.go b/cmd/truss/main.go index ad66f88..9948f0f 100644 --- a/cmd/truss/main.go +++ b/cmd/truss/main.go @@ -349,6 +349,9 @@ func readPreviousGeneration(serviceDir string) (map[string]io.Reader, error) { files := make(map[string]io.Reader) addFileToFiles := func(path string, info os.FileInfo, err error) error { + if err != nil { + return err + } if info.IsDir() { switch info.Name() { // Only files within the handlers dir are used to diff --git a/commit_date.sh b/commit_date.sh deleted file mode 100644 index 8de0171..0000000 --- a/commit_date.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/usr/bin/env bash -# commit_date.sh outputs the date of the last commit in UTC -# Works with both gnu date and bsd date - -set -e -[[ -z $DEBUG ]] || set -x - -# get the epoc time of the commit -head_commit=$(git rev-parse HEAD) -git_commit_epoc="$(git show -s --format=%ct $head_commit)" - -# use date for fomatting -# bsd date does not have `--version` -if [[ "$(date --version 2>/dev/null 1>/dev/null; echo $?)" -eq "1" ]]; then - # bsd date - commit_date=$(date -r $git_commit_epoc -u +"%Y-%m-%dT%H:%M:%SZ") -else - # gnu date - commit_date=$(date --date="@$git_commit_epoc" -u +"%Y-%m-%dT%H:%M:%SZ") -fi - -echo $commit_date diff --git a/deftree/gogo/helper.go b/deftree/gogo/helper.go index 390d4e4..ddd5de2 100644 --- a/deftree/gogo/helper.go +++ b/deftree/gogo/helper.go @@ -84,12 +84,12 @@ func IsStdBytes(field *google_protobuf.FieldDescriptorProto) bool { } func IsStdType(field *google_protobuf.FieldDescriptorProto) bool { - return (IsStdTime(field) || IsStdDuration(field) || + return IsStdTime(field) || IsStdDuration(field) || IsStdDouble(field) || IsStdFloat(field) || IsStdInt64(field) || IsStdUInt64(field) || IsStdInt32(field) || IsStdUInt32(field) || IsStdBool(field) || - IsStdString(field) || IsStdBytes(field)) + IsStdString(field) || IsStdBytes(field) } func IsWktPtr(field *google_protobuf.FieldDescriptorProto) bool { @@ -109,34 +109,22 @@ func NeedsNilCheck(proto3 bool, field *google_protobuf.FieldDescriptorProto) boo func IsCustomType(field *google_protobuf.FieldDescriptorProto) bool { typ := GetCustomType(field) - if len(typ) > 0 { - return true - } - return false + return len(typ) > 0 } func IsCastType(field *google_protobuf.FieldDescriptorProto) bool { typ := GetCastType(field) - if len(typ) > 0 { - return true - } - return false + return len(typ) > 0 } func IsCastKey(field *google_protobuf.FieldDescriptorProto) bool { typ := GetCastKey(field) - if len(typ) > 0 { - return true - } - return false + return len(typ) > 0 } func IsCastValue(field *google_protobuf.FieldDescriptorProto) bool { typ := GetCastValue(field) - if len(typ) > 0 { - return true - } - return false + return len(typ) > 0 } func HasEnumDecl(file *google_protobuf.FileDescriptorProto, enum *google_protobuf.EnumDescriptorProto) bool { @@ -201,26 +189,17 @@ func GetCastValue(field *google_protobuf.FieldDescriptorProto) string { func IsCustomName(field *google_protobuf.FieldDescriptorProto) bool { name := GetCustomName(field) - if len(name) > 0 { - return true - } - return false + return len(name) > 0 } func IsEnumCustomName(field *google_protobuf.EnumDescriptorProto) bool { name := GetEnumCustomName(field) - if len(name) > 0 { - return true - } - return false + return len(name) > 0 } func IsEnumValueCustomName(field *google_protobuf.EnumValueDescriptorProto) bool { name := GetEnumValueCustomName(field) - if len(name) > 0 { - return true - } - return false + return len(name) > 0 } func GetCustomName(field *google_protobuf.FieldDescriptorProto) string { diff --git a/gengokit/handlers/handler_test.go b/gengokit/handlers/handler_test.go index d2d0df4..be8ca02 100644 --- a/gengokit/handlers/handler_test.go +++ b/gengokit/handlers/handler_test.go @@ -31,6 +31,12 @@ func init() { log.SetLevel(log.DebugLevel) } +func fatalError(t *testing.T, err error) { + if err != nil { + t.Fatal(err) + } +} + func TestServerMethsTempl(t *testing.T) { const def = ` syntax = "proto3"; @@ -63,19 +69,16 @@ func TestServerMethsTempl(t *testing.T) { } ` sd, err := svcdef.NewFromString(def, gopath) - if err != nil { - t.Fatal(err) - } + fatalError(t, err) var he handlerData he.Methods = sd.Service.Methods he.ServiceName = sd.Service.Name gen, err := applyServerMethsTempl(he) - if err != nil { - t.Fatal(err) - } + fatalError(t, err) genBytes, err := ioutil.ReadAll(gen) + fatalError(t, err) const expected = ` func (s Service) ProtoMethod(ctx context.Context, in *pb.RequestMessage) (*pb.ResponseMessage, error){ var resp pb.ResponseMessage @@ -124,13 +127,14 @@ func TestApplyServerTempl(t *testing.T) { PBPackage: "github.com/DoNewsCode/truss/gengokit/general-service", } sd, err := svcdef.NewFromString(def, gopath) - if err != nil { - t.Fatal(err) - } + fatalError(t, err) te, err := gengokit.NewData(sd, conf) + fatalError(t, err) gen, err := applyServerTempl(te) + fatalError(t, err) genBytes, err := ioutil.ReadAll(gen) + fatalError(t, err) expected := ` package proto @@ -212,9 +216,7 @@ func TestIsValidFunc(t *testing.T) { } ` sd, err := svcdef.NewFromString(def, gopath) - if err != nil { - t.Fatal(err) - } + fatalError(t, err) m := newMethodMap(sd.Service.Methods) const validUnexported = `package p; @@ -297,9 +299,7 @@ func TestPruneDecls(t *testing.T) { } ` sd, err := svcdef.NewFromString(def, gopath) - if err != nil { - t.Fatal(err) - } + fatalError(t, err) m := newMethodMap(sd.Service.Methods) @@ -429,9 +429,7 @@ func TestUpdateMethods(t *testing.T) { ` sd, err := svcdef.NewFromString(def, gopath) - if err != nil { - t.Fatal(err) - } + fatalError(t, err) svc := sd.Service allMethods := svc.Methods @@ -442,21 +440,15 @@ func TestUpdateMethods(t *testing.T) { } te, err := gengokit.NewData(sd, conf) - if err != nil { - t.Fatal(err) - } + fatalError(t, err) svc.Methods = []*svcdef.ServiceMethod{allMethods[0]} firstCode, err := renderService(svc, "", te) - if err != nil { - t.Fatal(err) - } + fatalError(t, err) secondCode, err := renderService(svc, firstCode, te) - if err != nil { - t.Fatal(err) - } + fatalError(t, err) if len(firstCode) != len(secondCode) { t.Fatal("Generated service differs after regenerated with same definition\n" + @@ -466,9 +458,7 @@ func TestUpdateMethods(t *testing.T) { svc.Methods = append(svc.Methods, allMethods[1]) thirdCode, err := renderService(svc, secondCode, te) - if err != nil { - t.Fatal(err) - } + fatalError(t, err) if len(thirdCode) <= len(secondCode) { t.Fatal("Generated service not longer after regenerated with additional service method\n" + @@ -479,9 +469,7 @@ func TestUpdateMethods(t *testing.T) { svc.Methods = svc.Methods[1:] forthCode, err := renderService(svc, thirdCode, te) - if err != nil { - t.Fatal(err) - } + fatalError(t, err) if len(forthCode) >= len(thirdCode) { t.Fatal("Generated service not shorter after regenerated with fewer service method\n" + @@ -491,9 +479,7 @@ func TestUpdateMethods(t *testing.T) { svc.Methods = allMethods fifthCode, err := renderService(svc, forthCode, te) - if err != nil { - t.Fatal(err) - } + fatalError(t, err) if len(fifthCode) <= len(forthCode) { t.Fatal("Generated service not longer after regenerated with additional service method\n" + diff --git a/gengokit/handlers/handlers.go b/gengokit/handlers/handlers.go index 9c818c1..d586c86 100644 --- a/gengokit/handlers/handlers.go +++ b/gengokit/handlers/handlers.go @@ -161,7 +161,7 @@ func (m methodMap) pruneDecls(decls []ast.Decl, svcName string) []ast.Decl { newDecls = append(newDecls, x) continue } - if ok := isValidFunc(x, m, svcName); ok == true { + if ok := isValidFunc(x, m, svcName); ok { updateParams(x, m[name]) updateResults(x, m[name]) newDecls = append(newDecls, x) @@ -265,11 +265,6 @@ func exprString(e ast.Expr) string { } // *foo.Foo or foo.Foo if sel, _ := e.(*ast.SelectorExpr); sel != nil { - // *foo.Foo -> foo.Foo - if ptr, _ := e.(*ast.StarExpr); ptr != nil { - prefix = "*" - e = ptr.X - } // foo.Foo if x, _ := sel.X.(*ast.Ident); x != nil { return prefix + x.Name + "." + sel.Sel.Name diff --git a/gengokit/handlers/templates/hook.go b/gengokit/handlers/templates/hook.go deleted file mode 100644 index b2dea10..0000000 --- a/gengokit/handlers/templates/hook.go +++ /dev/null @@ -1,22 +0,0 @@ -package templates - -const Hook = ` -package handlers - -import ( - "fmt" - "os" - "os/signal" - "syscall" -) - -func InterruptHandler(errc chan<- error) { - c := make(chan os.Signal, 1) - signal.Notify(c, syscall.SIGINT, syscall.SIGTERM) - terminateError := fmt.Errorf("%s", <-c) - - // Place whatever shutdown handling you want here - - errc <- terminateError -} -` diff --git a/gengokit/httptransport/get_source.go b/gengokit/httptransport/get_source.go index adc1f9e..77411f3 100644 --- a/gengokit/httptransport/get_source.go +++ b/gengokit/httptransport/get_source.go @@ -19,9 +19,8 @@ func FuncSourceCode(val interface{}) (string, error) { ptr := reflect.ValueOf(val).Pointer() fpath, _ := runtime.FuncForPC(ptr).FileLine(ptr) - funcName := runtime.FuncForPC(ptr).Name() - parts := strings.Split(funcName, ".") - funcName = parts[len(parts)-1] + parts := strings.Split(runtime.FuncForPC(ptr).Name(), ".") + funcName := parts[len(parts)-1] // Parse the go file into the ast fset := token.NewFileSet() @@ -32,13 +31,9 @@ func FuncSourceCode(val interface{}) (string, error) { // Search ast for function declaration with name of function passed var fAst *ast.FuncDecl - for _, decs := range fileAst.Decls { - switch decs.(type) { - case *ast.FuncDecl: - f := decs.(*ast.FuncDecl) - if f.Name.String() == funcName { - fAst = f - } + for _, decl := range fileAst.Decls { + if decl, ok := decl.(*ast.FuncDecl); ok && funcName == decl.Name.String() { + fAst = decl } } code := bytes.NewBuffer(nil) @@ -59,10 +54,6 @@ func AllFuncSourceCode(val interface{}) (string, error) { ptr := reflect.ValueOf(val).Pointer() fpath, _ := runtime.FuncForPC(ptr).FileLine(ptr) - funcName := runtime.FuncForPC(ptr).Name() - parts := strings.Split(funcName, ".") - funcName = parts[len(parts)-1] - // Parse the go file into the ast fset := token.NewFileSet() fileAst, err := parser.ParseFile(fset, fpath, nil, parser.ParseComments) @@ -71,12 +62,10 @@ func AllFuncSourceCode(val interface{}) (string, error) { } // Search ast for all function declarations - fncSlc := []*ast.FuncDecl{} - for _, decs := range fileAst.Decls { - switch decs.(type) { - case *ast.FuncDecl: - f := decs.(*ast.FuncDecl) - fncSlc = append(fncSlc, f) + var fncSlc []*ast.FuncDecl + for _, decl := range fileAst.Decls { + if decl, ok := decl.(*ast.FuncDecl); ok { + fncSlc = append(fncSlc, decl) } } diff --git a/gengokit/httptransport/httptransport.go b/gengokit/httptransport/httptransport.go index ea87fdb..5f69389 100644 --- a/gengokit/httptransport/httptransport.go +++ b/gengokit/httptransport/httptransport.go @@ -11,12 +11,11 @@ import ( "text/template" "unicode" + "github.com/DoNewsCode/truss/gengokit/httptransport/templates" + "github.com/DoNewsCode/truss/svcdef" gogen "github.com/gogo/protobuf/protoc-gen-gogo/generator" "github.com/pkg/errors" log "github.com/sirupsen/logrus" - - "github.com/DoNewsCode/truss/gengokit/httptransport/templates" - "github.com/DoNewsCode/truss/svcdef" ) // Helper is the base struct for the data structure containing all the @@ -64,7 +63,7 @@ func NewMethod(meth *svcdef.ServiceMethod) *Method { // NewBinding creates a Binding struct based on a svcdef.HTTPBinding. Because // NewBinding requires access to some of it's parent method's fields, instead -// of passing a svcdef.HttpBinding directly, you instead pass a +// of passing a svcdef.HTTPBinding directly, you instead pass a // svcdef.ServiceMethod and the index of the HTTPBinding within that methods // "HTTPBinding" slice. func NewBinding(i int, meth *svcdef.ServiceMethod) *Binding { @@ -247,7 +246,7 @@ func (b *Binding) PathSections() []string { } } - rv := []string{} + var rv []string parts := strings.Split(b.PathTemplate, "/") for _, part := range parts { if len(part) > 2 && part[0] == '{' && part[len(part)-1] == '}' { @@ -500,16 +499,16 @@ func basePath(path string) string { // DigitEnglish is a map of runes of digits zero to nine to their lowercase // english language spellings. var DigitEnglish = map[rune]string{ - '0': "zero", - '1': "one", - '2': "two", - '3': "three", - '4': "four", - '5': "five", - '6': "six", - '7': "seven", - '8': "eight", - '9': "nine", + '0': "Zero", + '1': "One", + '2': "Two", + '3': "Three", + '4': "Four", + '5': "Five", + '6': "Six", + '7': "Seven", + '8': "Eight", + '9': "Nine", } // EnglishNumber takes an integer and returns the english words that represents @@ -522,8 +521,8 @@ func EnglishNumber(i int) string { n := strconv.Itoa(i) rv := "" for _, c := range n { - if engl, ok := DigitEnglish[rune(c)]; ok { - rv += strings.Title(engl) + if v, ok := DigitEnglish[c]; ok { + rv += v } } return rv diff --git a/gengokit/httptransport/templates/client.go b/gengokit/httptransport/templates/client.go index f310676..d3dd372 100644 --- a/gengokit/httptransport/templates/client.go +++ b/gengokit/httptransport/templates/client.go @@ -94,7 +94,7 @@ var ClientEncodeTemplate = ` if err := encoder.Encode(toRet); err != nil { return errors.Wrapf(err, "couldn't encode body as json %v", toRet) } - r.Body = ioutil.NopCloser(&buf) + r.Body = io.NopCloser(&buf) {{- end }} return nil } @@ -115,7 +115,6 @@ import ( "encoding/json" "fmt" "io" - "io/ioutil" "net/http" "net/url" "strings" @@ -139,7 +138,7 @@ var ( _ = kithttp.NewClient _ = fmt.Sprint _ = bytes.Compare - _ = ioutil.NopCloser + _ = io.NopCloser ) // New returns a service backed by an HTTP server living at the remote @@ -181,7 +180,7 @@ func New(instance string, options ...kithttp.ClientOption) (pb.{{.Service.Name}} {{range $method := .HTTPHelper.Methods -}} {{ if $method.Bindings -}} {{ with $binding := index $method.Bindings 0 -}} - {{$method.Name}}Endpoint: {{$binding.Label}}Endpoint, + svc.{{$method.Name}}: {{$binding.Label}}Endpoint, {{end}} {{- end}} {{- end}} diff --git a/gengokit/httptransport/templates/server.go b/gengokit/httptransport/templates/server.go index 2e09dcc..bafb943 100644 --- a/gengokit/httptransport/templates/server.go +++ b/gengokit/httptransport/templates/server.go @@ -10,7 +10,7 @@ var ServerDecodeTemplate = ` func DecodeHTTP{{$binding.Label}}Request(_ context.Context, r *http.Request) (interface{}, error) { defer r.Body.Close() var req pb.{{GoName $binding.Parent.RequestType}} - buf, err := ioutil.ReadAll(r.Body) + buf, err := io.ReadAll(r.Body) if err != nil { return nil, errors.Wrapf(err, "cannot read body of http request") } @@ -72,7 +72,6 @@ import ( "bytes" "encoding/json" "fmt" - "io/ioutil" "net/http" "strconv" "strings" @@ -98,7 +97,7 @@ var ( _ = bytes.Compare _ = strconv.Atoi _ = kithttp.NewServer - _ = ioutil.NopCloser + _ = io.NopCloser _ = pb.New{{.Service.Name}}Client _ = io.Copy _ = errors.Wrap @@ -119,8 +118,8 @@ func MakeHTTPHandler(endpoints Endpoints, options ...kithttp.ServerOption) http. {{range $method := .HTTPHelper.Methods}} {{range $binding := $method.Bindings}} - m.Methods("{{$binding.Verb | ToUpper}}").Path("{{$binding.PathTemplate}}").Handler(kithttp.NewServer( - endpoints.{{$method.Name}}Endpoint, + m.Methods("{{$binding.Verb | ToUpper}}").Path(PathPrefix+"{{$binding.PathTemplate}}").Handler(kithttp.NewServer( + endpoints[{{$method.Name}}], DecodeHTTP{{$binding.Label}}Request, EncodeHTTPGenericResponse, serverOptions..., diff --git a/gengokit/template/NAME-service/svc/client/grpc/client.gotemplate b/gengokit/template/NAME-service/svc/client/grpc/client.gotemplate index 0796969..23a9fc3 100644 --- a/gengokit/template/NAME-service/svc/client/grpc/client.gotemplate +++ b/gengokit/template/NAME-service/svc/client/grpc/client.gotemplate @@ -29,8 +29,8 @@ func New(conn *grpc.ClientConn, options ...kitgrpc.ClientOption) (svc.Endpoints, { {{ToLower $i.Name}}Endpoint = kitgrpc.NewClient( conn, - "{{$pkgName}}.{{$te.Service.Name}}", - "{{$i.Name}}", + string(svc.ServiceName), + string(svc.{{$i.Name}}), EncodeGRPC{{$i.Name}}Request, DecodeGRPC{{$i.Name}}Response, pb.{{GoName $i.ResponseType.Name}}{}, @@ -43,7 +43,7 @@ func New(conn *grpc.ClientConn, options ...kitgrpc.ClientOption) (svc.Endpoints, return svc.Endpoints{ {{range $i := .Service.Methods -}} - {{$i.Name}}Endpoint: {{ToLower $i.Name}}Endpoint, + svc.{{$i.Name}}: {{ToLower $i.Name}}Endpoint, {{end}} }, nil } diff --git a/gengokit/template/NAME-service/svc/client/http/client.gotemplate b/gengokit/template/NAME-service/svc/client/http/client.gotemplate index b4a63d4..fcf7e0c 100644 --- a/gengokit/template/NAME-service/svc/client/http/client.gotemplate +++ b/gengokit/template/NAME-service/svc/client/http/client.gotemplate @@ -1,2 +1,2 @@ -{{/* See go-truss/gengokit/kithttp/template.go for code */}} +{{/* See go-truss/gengokit/httptransport/template.go for code */}} {{call .HTTPHelper.ClientTemplate .}} diff --git a/gengokit/template/NAME-service/svc/endpoints.gotemplate b/gengokit/template/NAME-service/svc/endpoints.gotemplate index 065a4de..be8ae1c 100644 --- a/gengokit/template/NAME-service/svc/endpoints.gotemplate +++ b/gengokit/template/NAME-service/svc/endpoints.gotemplate @@ -11,7 +11,6 @@ package svc // formats. import ( - "fmt" "context" "github.com/go-kit/kit/endpoint" @@ -32,11 +31,18 @@ import ( // In a client, it's useful to collect individually constructed endpoints into a // single type that implements the Service interface. For example, you might // construct individual endpoints using transport/http.NewClient, combine them into an Endpoints, and return it to the caller as a Service. -type Endpoints struct { +type Endpoints map[Name]endpoint.Endpoint + +type Name string + +const ( + ServiceName Name = "{{.PBPackageName}}.{{.Service.Name}}" {{range $i := .Service.Methods}} - {{$i.Name}}Endpoint endpoint.Endpoint + {{$i.Name}} Name = "{{$i.Name}}" {{- end}} -} + + PathPrefix = "/{{.PBPackageName}}.{{.Service.Name}}" +) func NewEndpoints(service pb.{{.Service.Name}}Server) Endpoints { @@ -49,7 +55,7 @@ func NewEndpoints(service pb.{{.Service.Name}}Server) Endpoints { endpoints := Endpoints{ {{range $i := .Service.Methods -}} - {{$i.Name}}Endpoint: {{ToLower $i.Name}}Endpoint, + {{$i.Name}}: {{ToLower $i.Name}}Endpoint, {{end}} } @@ -59,7 +65,7 @@ func NewEndpoints(service pb.{{.Service.Name}}Server) Endpoints { // Endpoints {{range $i := .Service.Methods}} func (e Endpoints) {{$i.Name}}(ctx context.Context, in *pb.{{GoName $i.RequestType.Name}}) (*pb.{{GoName $i.ResponseType.Name}}, error) { - response, err := e.{{$i.Name}}Endpoint(ctx, in) + response, err := e[{{$i.Name}}](ctx, in) if err != nil { return nil, err } @@ -88,57 +94,41 @@ func NewEndpoints(service pb.{{.Service.Name}}Server) Endpoints { // Use this for applying a set of middlewares to every endpoint in the service. // Optionally, endpoints can be passed in by name to be excluded from being wrapped. // WrapAllExcept(middleware, "Status", "Ping") -func (e *Endpoints) WrapAllExcept(middleware endpoint.Middleware, excluded ...string) { - included := map[string]struct{}{ - {{- range $i := .Service.Methods}} - "{{$i.Name}}": {}, - {{- end}} - } +func (e Endpoints) WrapAllExcept(middleware endpoint.Middleware, excluded ...Name) { + excludedMap := map[Name]struct{}{} for _, ex := range excluded { - if _, ok := included[ex]; !ok { - panic(fmt.Sprintf("Excluded endpoint '%s' does not exist; see middlewares/endpoints.go", ex)) - } - delete(included, ex) + excludedMap[ex] = struct{}{} } - for inc := range included { - {{- range $i := .Service.Methods}} - if inc == "{{$i.Name}}" { - e.{{$i.Name}}Endpoint = middleware(e.{{$i.Name}}Endpoint) - } - {{- end}} + for inc, end := range e { + if _, ok := excludedMap[inc]; ok { + continue + } + e[inc] = middleware(end) } } // LabeledMiddleware will get passed the endpoint name when passed to // WrapAllLabeledExcept, this can be used to write a generic metrics // middleware which can send the endpoint name to the metrics collector. -type LabeledMiddleware func(string, endpoint.Endpoint) endpoint.Endpoint +type LabeledMiddleware func(Name, endpoint.Endpoint) endpoint.Endpoint // WrapAllLabeledExcept wraps each Endpoint field of struct Endpoints with a // LabeledMiddleware, which will receive the name of the endpoint. See // LabeldMiddleware. See method WrapAllExept for details on excluded // functionality. -func (e *Endpoints) WrapAllLabeledExcept(middleware func(string, endpoint.Endpoint) endpoint.Endpoint, excluded ...string) { - included := map[string]struct{}{ - {{- range $i := .Service.Methods}} - "{{$i.Name}}": {}, - {{- end}} - } +func (e Endpoints) WrapAllLabeledExcept(middleware func(Name, endpoint.Endpoint) endpoint.Endpoint, excluded ...Name) { + excludedMap := map[Name]struct{}{} for _, ex := range excluded { - if _, ok := included[ex]; !ok { - panic(fmt.Sprintf("Excluded endpoint '%s' does not exist; see middlewares/endpoints.go", ex)) - } - delete(included, ex) + excludedMap[ex] = struct{}{} } - for inc := range included { - {{- range $i := .Service.Methods}} - if inc == "{{$i.Name}}" { - e.{{$i.Name}}Endpoint = middleware("{{$i.Name}}", e.{{$i.Name}}Endpoint) - } - {{- end}} + for inc, end := range e { + if _, ok := excludedMap[inc]; ok { + continue + } + e[inc] = middleware(inc, end) } } diff --git a/gengokit/template/NAME-service/svc/transport_grpc.gotemplate b/gengokit/template/NAME-service/svc/transport_grpc.gotemplate index ff2702b..049d332 100644 --- a/gengokit/template/NAME-service/svc/transport_grpc.gotemplate +++ b/gengokit/template/NAME-service/svc/transport_grpc.gotemplate @@ -30,7 +30,7 @@ func MakeGRPCServer(endpoints Endpoints, options ...kitgrpc.ServerOption) pb.{{. // {{ ToLower .Service.Name }} {{range $i := .Service.Methods}} {{ToLower $i.Name}}: kitgrpc.NewServer( - endpoints.{{$i.Name}}Endpoint, + endpoints[{{$i.Name}}], DecodeGRPC{{$i.Name}}Request, EncodeGRPC{{$i.Name}}Response, serverOptions..., diff --git a/gengokit/template/NAME-service/svc/transport_http.gotemplate b/gengokit/template/NAME-service/svc/transport_http.gotemplate index 4944287..dc8eecf 100644 --- a/gengokit/template/NAME-service/svc/transport_http.gotemplate +++ b/gengokit/template/NAME-service/svc/transport_http.gotemplate @@ -1,2 +1,2 @@ -{{/* See go-truss/gengokit/kithttp/templates.go for code */}} +{{/* See go-truss/gengokit/httptransport/templates.go for code */}} {{call .HTTPHelper.ServerTemplate .}} diff --git a/go.mod b/go.mod index 1e62516..664c5ea 100644 --- a/go.mod +++ b/go.mod @@ -10,5 +10,5 @@ require ( github.com/sirupsen/logrus v1.9.0 github.com/spf13/pflag v1.0.5 github.com/stretchr/testify v1.8.0 // indirect - golang.org/x/tools v0.1.12 + golang.org/x/tools v0.0.0-20210106214847-113979e3529a ) diff --git a/go.sum b/go.sum index b64e488..31a4a68 100644 --- a/go.sum +++ b/go.sum @@ -21,48 +21,35 @@ github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PK github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 h1:0A+M6Uqn+Eje4kHMK80dtF3JCXC4ykBgQG4Fe06QRhQ= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f h1:v4INt8xihDGvnrfjMDVXGxw9wrfxYyCjk0KbXjhR55s= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a h1:CB3a9Nez8M13wwlr/E2YtwoU+qYHKfC+JrDa45RXXoQ= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/svcdef/consolidate_http.go b/svcdef/consolidate_http.go index 989b53f..fa4f958 100644 --- a/svcdef/consolidate_http.go +++ b/svcdef/consolidate_http.go @@ -41,7 +41,7 @@ func isEOF(err error) bool { func consolidateHTTP(sd *Svcdef, protoFiles map[string]io.Reader) error { for _, pfile := range protoFiles { f, _ := ioutil.ReadAll(pfile) - submatch := regexp.MustCompile("[^\\w_]package ([^;]*);").FindSubmatch(f) + submatch := regexp.MustCompile(`[^\w_]package ([^;]*);`).FindSubmatch(f) if len(submatch) < 2 { return errors.New("missing package name") } diff --git a/svcdef/svcparse/parser.go b/svcdef/svcparse/parser.go index 1e69c7e..018d7ff 100644 --- a/svcdef/svcparse/parser.go +++ b/svcdef/svcparse/parser.go @@ -396,7 +396,6 @@ func ParseMethod(lex *SvcLexer) (*Method, error) { } - return toret, nil } @@ -406,7 +405,7 @@ func ParseHttpBindings(lex *SvcLexer) ([]*HTTPBinding, error) { rv := make([]*HTTPBinding, 0) new_opt := &HTTPBinding{} - start: +start: tk, val := lex.GetTokenIgnoreWhitespace() // If there's a comment before the declaration of a new HttpBinding, then // we set that comment as the description of that HttpBinding. Since we're @@ -432,13 +431,19 @@ func ParseHttpBindings(lex *SvcLexer) ([]*HTTPBinding, error) { } } - switch { - case val == "option": + switch val { + case "option": err := fastForwardTill(lex, "(") + if err != nil { + return nil, err + } - tk, val := lex.GetTokenIgnoreWhitespace() + _, val = lex.GetTokenIgnoreWhitespace() for val != "google" { err = fastForwardTill(lex, ";") + if err != nil { + return nil, err + } goto start } @@ -461,7 +466,7 @@ func ParseHttpBindings(lex *SvcLexer) ([]*HTTPBinding, error) { } else if tk == COMMENT { good_position = lex.GetPosition() } else if val == "additional_bindings" { - lex.UnGetToPosition(good_position) + _ = lex.UnGetToPosition(good_position) more_bindings, err := ParseHttpBindings(lex) if err != nil { return nil, err @@ -483,7 +488,7 @@ func ParseHttpBindings(lex *SvcLexer) ([]*HTTPBinding, error) { } tk, val = lex.GetTokenIgnoreWhitespace() } - case val == "additional_bindings": + case "additional_bindings": err := fastForwardTill(lex, "{") if err != nil { return nil, err @@ -499,7 +504,7 @@ func ParseHttpBindings(lex *SvcLexer) ([]*HTTPBinding, error) { return nil, err } return append(rv, new_opt), nil - case val == "}": + case "}": // End of RPC return nil, nil } @@ -528,11 +533,8 @@ func ParseBindingFields(lex *SvcLexer) (fields []*Field, custom []*Field, err er } } // No longer any more fields - if tk == CLOSE_BRACE && val == "}" { - lex.UnGetToken() - break - } else if val == "additional_bindings" { - lex.UnGetToken() + if (tk == CLOSE_BRACE && val == "}") || val == "additional_bindings" { + _ = lex.UnGetToken() break } // Use recursion to parse custom HTTP verb sections @@ -576,11 +578,11 @@ func ParseBindingFields(lex *SvcLexer) (fields []*Field, custom []*Field, err er } } - noqoute, err := strconv.Unquote(val) + unquote, err := strconv.Unquote(val) if err != nil { return nil, nil, errors.Wrapf(err, "cannot unquote value %q", val) } - field.Value = noqoute + field.Value = unquote fields = append(fields, field) field = &Field{} diff --git a/svcdef/svcparse/scanner.go b/svcdef/svcparse/scanner.go index 329a8f4..4ca158b 100644 --- a/svcdef/svcparse/scanner.go +++ b/svcdef/svcparse/scanner.go @@ -17,7 +17,7 @@ type RuneReader struct { LineNo int } -func (self *RuneReader) ReadRune() (rune, error) { +func (self *RuneReader) Read() (rune, error) { var toret rune = 0 var err error @@ -33,7 +33,7 @@ func (self *RuneReader) ReadRune() (rune, error) { return toret, err } -func (self *RuneReader) UnreadRune() error { +func (self *RuneReader) Unread() error { if self.RunePos == 0 { return bufio.ErrInvalidUnreadRune } @@ -112,7 +112,7 @@ func BuildScanUnit(rr *RuneReader) (*ScanUnit, error) { // Populate the buffer with at least one rune so even if it's an unknown // character it will at least return this - ch, err := rr.ReadRune() + ch, err := rr.Read() if err != nil { return setReturn(), err } @@ -121,14 +121,14 @@ func BuildScanUnit(rr *RuneReader) (*ScanUnit, error) { switch { case ch == '/': // Searching for comments beginning with '/' - ch, err = rr.ReadRune() + ch, err = rr.Read() if err != nil { return setReturn(), err } else if ch == '/' { // Handle single line comments of the form '//' buf = append(buf, ch) for { - ch, err = rr.ReadRune() + ch, err = rr.Read() if err != nil { return setReturn(), err } else if ch == '\n' { @@ -141,12 +141,12 @@ func BuildScanUnit(rr *RuneReader) (*ScanUnit, error) { // Handle (potentially) multi-line comments of the form '/**/' buf = append(buf, ch) for { - ch, err = rr.ReadRune() + ch, err = rr.Read() if err != nil { return setReturn(), err } else if ch == '*' { buf = append(buf, ch) - ch, err = rr.ReadRune() + ch, err = rr.Read() if err != nil { return setReturn(), err } else if ch == '/' { @@ -160,19 +160,19 @@ func BuildScanUnit(rr *RuneReader) (*ScanUnit, error) { } } else { // Not a comment, so unread the last Rune and return this '/' only - rr.UnreadRune() + rr.Unread() return setReturn(), nil } case ch == '"': // Handle strings for { - ch, err = rr.ReadRune() + ch, err = rr.Read() if err != nil { return setReturn(), err } else if ch == '\\' { // Handle escape sequences within strings buf = append(buf, ch) - ch, err = rr.ReadRune() + ch, err = rr.Read() if err != nil { return setReturn(), err } else { @@ -189,7 +189,7 @@ func BuildScanUnit(rr *RuneReader) (*ScanUnit, error) { case unicode.IsSpace(ch): // Group consecutive white space characters for { - ch, err = rr.ReadRune() + ch, err = rr.Read() if err != nil { // Don't pass along this EOF since we did find a valid 'Unit' // to return. This way, the next call of this function will @@ -199,7 +199,7 @@ func BuildScanUnit(rr *RuneReader) (*ScanUnit, error) { } return setReturn(), err } else if !unicode.IsSpace(ch) { - rr.UnreadRune() + rr.Unread() break } buf = append(buf, ch) @@ -207,14 +207,14 @@ func BuildScanUnit(rr *RuneReader) (*ScanUnit, error) { case isIdent(ch): // Group consecutive letters for { - ch, err = rr.ReadRune() + ch, err = rr.Read() if err != nil { if err == io.EOF { return setReturn(), nil } return setReturn(), err } else if !isIdent(ch) { - rr.UnreadRune() + rr.Unread() if string(buf) == "service" { withinDef = true } @@ -224,13 +224,13 @@ func BuildScanUnit(rr *RuneReader) (*ScanUnit, error) { } case ch == '{': braceLev += 1 - if withinDef == true { + if withinDef { withinDef = false withinBody = true } case ch == '}': braceLev -= 1 - if withinBody == true && braceLev == 0 { + if withinBody && braceLev == 0 { withinBody = false } } diff --git a/truss/parsesvcname/parsesvcname.go b/truss/parsesvcname/parsesvcname.go index ea15cef..43c40b3 100644 --- a/truss/parsesvcname/parsesvcname.go +++ b/truss/parsesvcname/parsesvcname.go @@ -19,17 +19,17 @@ import ( // name of the service in that protobuf definition file. func FromPaths(gopath []string, protoDefPaths []string) (string, error) { td, err := ioutil.TempDir("", "parsesvcname") - defer os.RemoveAll(td) if err != nil { return "", errors.Wrap(err, "failed to create temporary directory for .pb.go files") } + defer os.RemoveAll(td) err = execprotoc.GeneratePBDotGo(protoDefPaths, gopath, td) if err != nil { return "", errors.Wrap(err, "failed to generate .pb.go files from proto definition files") } // Get path names of .pb.go files - pbgoPaths := []string{} + var pbgoPaths []string for _, p := range protoDefPaths { base := filepath.Base(p) barename := strings.TrimSuffix(base, filepath.Ext(p)) @@ -81,12 +81,16 @@ func FromReaders(gopath []string, protoDefReaders []io.Reader) (string, error) { protoDefPaths := []string{} for _, rdr := range protoDefReaders { f, err := ioutil.TempFile(protoDir, "parsesvcname-fromreader") + if err != nil { + return "", errors.Wrap(err, "create temp file error") + } _, err = io.Copy(f, rdr) if err != nil { + f.Close() return "", errors.Wrap(err, "couldn't copy contents of our proto file into the os.File: ") } - path := f.Name() f.Close() + path := f.Name() protoDefPaths = append(protoDefPaths, path) } return FromPaths(gopath, protoDefPaths) diff --git a/truss/parsesvcname/parsesvcname_test.go b/truss/parsesvcname/parsesvcname_test.go index d67889e..08a8aad 100644 --- a/truss/parsesvcname/parsesvcname_test.go +++ b/truss/parsesvcname/parsesvcname_test.go @@ -38,6 +38,9 @@ func TestFromPaths(t *testing.T) { } defer os.RemoveAll(protoDir) f, err := ioutil.TempFile(protoDir, "trusstest") + if err != nil { + t.Fatal(err) + } _, err = io.Copy(f, strings.NewReader(protoStr)) if err != nil { t.Fatal("couldn't copy contents of our proto file into the os.File: ", err)