Update handler to render all methods if there was no previous file

This commit is contained in:
Adam Ryman 2016-11-08 13:54:28 -08:00
Родитель 652f0237a8
Коммит 396200aa78
2 изменённых файлов: 46 добавлений и 64 удалений

Просмотреть файл

@ -14,7 +14,7 @@ import (
"github.com/TuneLab/go-truss/gengokit"
"github.com/TuneLab/go-truss/gengokit/handler"
templateFileAssets "github.com/TuneLab/go-truss/gengokit/template"
templFiles "github.com/TuneLab/go-truss/gengokit/template"
"github.com/TuneLab/go-truss/svcdef"
"github.com/TuneLab/go-truss/truss"
@ -44,7 +44,7 @@ func GenerateGokit(sd *svcdef.Svcdef, conf gengokit.Config) ([]truss.NamedReadWr
var codeGenFiles []truss.NamedReadWriter
for _, templFP := range templateFileAssets.AssetNames() {
for _, templFP := range templFiles.AssetNames() {
file, err := generateResponseFile(templFP, te, fpm)
if err != nil {
return nil, errors.Wrap(err, "cannot render template")
@ -74,18 +74,15 @@ func generateResponseFile(templFP string, te *gengokit.TemplateExecutor, prevGen
// If we are rendering the server and or the client
if templFP == "NAME-service/handlers/server/server_handler.gotemplate" ||
templFP == "NAME-service/handlers/client/client_handler.gotemplate" {
// and they were previously generated
if file := prevGenMap[actualFP]; file != nil {
var h gengokit.Renderable
h, err = handler.New(te.Service, file)
if err != nil {
return nil, errors.Wrapf(err, "previous handler invalid: %q", actualFP)
}
if genCode, err = h.Render(templFP, te); err != nil {
return nil, errors.Wrap(err, "cannot render template")
}
file := prevGenMap[actualFP]
h, err := handler.New(te.Service, file)
if err != nil {
return nil, errors.Wrapf(err, "cannot parse previous handler: %q", actualFP)
}
if genCode, err = h.Render(templFP, te); err != nil {
return nil, errors.Wrap(err, "cannot render template")
}
}
// if no code has been generated just apply the template
@ -130,8 +127,7 @@ func templatePathToActual(templFilePath, packageName string) string {
// applyTemplateFromPath calls applyTemplate with the template at templFilePath
func applyTemplateFromPath(templFilePath string, executor *gengokit.TemplateExecutor) (io.Reader, error) {
templBytes, err := templateFileAssets.Asset(templFilePath)
templBytes, err := templFiles.Asset(templFilePath)
if err != nil {
return nil, errors.Wrapf(err, "unable to find template file: %v", templFilePath)
}

Просмотреть файл

@ -17,34 +17,40 @@ import (
"github.com/pkg/errors"
"github.com/TuneLab/go-truss/gengokit"
templFiles "github.com/TuneLab/go-truss/gengokit/template"
"github.com/TuneLab/go-truss/svcdef"
// Will be removed when cliclient is fully generated
"github.com/TuneLab/go-truss/gengokit/clientarggen"
)
// NewService is an exported func that creates a new service
// it will not be defined in the service definition but is required
const ignoredFunc = "NewService"
// New returns a truss.Renderable capable of updating server or cli-client handlers
// New should be passed the previous version of the server or cli-client handler to parse
func New(svc *svcdef.Service, prev io.Reader) (gengokit.Renderable, error) {
fset := token.NewFileSet()
f, err := parser.ParseFile(fset, "", prev, parser.ParseComments)
if err != nil {
return nil, err
}
var h handler
log.WithField("Service Methods", len(svc.Methods)).Debug("Handler being created")
mMap := make(map[string]*svcdef.ServiceMethod, len(svc.Methods))
for _, m := range svc.Methods {
mMap[m.Name] = m
}
h.mMap = mMap
h.service = svc
return &handler{
fset: fset,
ast: f,
mMap: mMap,
service: svc,
}, nil
if prev == nil {
return &h, nil
}
h.fset = token.NewFileSet()
var err error
if h.ast, err = parser.ParseFile(h.fset, "", prev, parser.ParseComments); err != nil {
return nil, err
}
return &h, nil
}
// methodMap stores all defined service methods by name
@ -68,17 +74,34 @@ type handlerExecutor struct {
Methods []*svcdef.ServiceMethod
}
func (h *handler) renderFirst(f string, te *gengokit.TemplateExecutor) (io.Reader, error) {
log.WithField("Template", f).
Debug("Rendering for the first time from assets")
t, err := templFiles.Asset(f)
if err != nil {
return nil, errors.Wrapf(err, "cannot access template: %q", f)
}
return applyTemplate(string(t), f, te)
}
// Render returns
func (h *handler) Render(f string, te *gengokit.TemplateExecutor) (io.Reader, error) {
if h.ast == nil {
return h.renderFirst(f, te)
}
// Remove exported methods not defined in service definition
// and remove methods defined in the previous file from methodMap
log.WithField("Service Methods", len(h.mMap)).Debug("Before prune")
h.ast.Decls = h.mMap.pruneDecls(h.ast.Decls)
log.WithField("Service Methods", len(h.mMap)).Debug("After prune")
// create a new executor, and add all methods not defined in the previous file
ex := handlerExecutor{
PackageName: te.PackageName,
}
// If there are no methods to template than exit early
// If there are no methods to template then exit early
if len(h.mMap) == 0 {
return h.buffer()
}
@ -194,43 +217,6 @@ func applyServerTempl(exec handlerExecutor) (io.Reader, error) {
return applyTemplate(serverTempl, "ServerTempl", exec)
}
const clientTempl = `
{{ with $te := .}}
{{range $i := $te.Methods}}
// {{$i.Name}} implements Service.
func {{$i.Name}}({{with index $te.ClientArgs.MethArgs $i.Name}}{{GoName .FunctionArgs}}{{end}}) (*pb.{{GoName $i.RequestType.Name}}, error){
{{- with $meth := index $te.ClientArgs.MethArgs $i.Name -}}
{{- range $param := $meth.Args -}}
{{- if not $param.IsBaseType -}}
// Add custom business logic for interpreting {{$param.FlagArg}},
{{- end -}}
{{- end -}}
{{- end -}}
request := pb.{{GoName $i.RequestType.Name}}{
{{- with $meth := index $te.ClientArgs.MethArgs $i.Name -}}
{{range $param := $meth.Args -}}
{{- if $param.IsBaseType}}
{{GoName $param.Name}} : {{GoName $param.FlagArg}},
{{- end -}}
{{end -}}
{{- end -}}
}
return &request, nil
}
{{end}}
{{- end}}
`
func applyClientTempl(exec handlerExecutor, h handler) (io.Reader, error) {
newService := *h.service
newService.Methods = exec.Methods
c := cliHandlerExecutor{
handlerExecutor: exec,
ClientArgs: clientarggen.New(&newService),
}
return applyTemplate(clientTempl, "ClientTemplate", c)
}
func applyTemplate(templ string, templName string, exec interface{}) (io.Reader, error) {
funcMap := template.FuncMap{
"ToLower": strings.ToLower,