From e26e99b6434f434519aef05cb4205ee195e93dd1 Mon Sep 17 00:00:00 2001 From: Ariel Mashraki Date: Tue, 15 Sep 2020 15:16:42 +0300 Subject: [PATCH] entc/gen: improve the api for custom templates --- entc/entc.go | 44 ++++++++++----- entc/gen/graph.go | 69 +++++++++++++++++------- entc/gen/internal/bindata.go | 4 +- entc/gen/template.go | 7 +-- entc/gen/template/client.tmpl | 2 +- examples/entcpkg/ent/debug.go | 17 ++++++ examples/entcpkg/ent/entc.go | 18 +++++-- examples/entcpkg/ent/template/debug.tmpl | 22 ++++++++ 8 files changed, 139 insertions(+), 44 deletions(-) create mode 100644 examples/entcpkg/ent/debug.go create mode 100644 examples/entcpkg/ent/template/debug.tmpl diff --git a/entc/entc.go b/entc/entc.go index 68bfbb0b4..4a6eff0ac 100644 --- a/entc/entc.go +++ b/entc/entc.go @@ -119,48 +119,66 @@ func Storage(typ string) Option { } } +// Funcs specifies external functions to add to the template execution. +func Funcs(funcMap template.FuncMap) Option { + return func(cfg *gen.Config) error { + if cfg.Funcs == nil { + cfg.Funcs = funcMap + return nil + } + for name, fn := range funcMap { + cfg.Funcs[name] = fn + } + return nil + } +} + // TemplateFiles parses the named files and associates the resulting templates // with codegen templates. func TemplateFiles(filenames ...string) Option { - return templateOption(func(cfg *gen.Config) (err error) { - cfg.Template, err = cfg.Template.ParseFiles(filenames...) - return + return templateOption(func(t *template.Template) (*template.Template, error) { + return t.ParseFiles(filenames...) }) } // TemplateGlob parses the template definitions from the files identified // by the pattern and associates the resulting templates with codegen templates. func TemplateGlob(pattern string) Option { - return templateOption(func(cfg *gen.Config) (err error) { - cfg.Template, err = cfg.Template.ParseGlob(pattern) - return + return templateOption(func(t *template.Template) (*template.Template, error) { + return t.ParseGlob(pattern) }) } // TemplateDir parses the template definitions from the files in the directory // and associates the resulting templates with codegen templates. func TemplateDir(path string) Option { - return templateOption(func(cfg *gen.Config) error { - return filepath.Walk(path, func(path string, info os.FileInfo, err error) error { + return templateOption(func(t *template.Template) (*template.Template, error) { + err := filepath.Walk(path, func(path string, info os.FileInfo, err error) error { if err != nil { return fmt.Errorf("load template: %v", err) } if info.IsDir() || strings.HasSuffix(path, ".go") { return nil } - cfg.Template, err = cfg.Template.ParseFiles(path) + t, err = t.ParseFiles(path) return err }) + if err != nil { + return nil, err + } + return t, nil }) } // templateOption ensures the template instantiate // once for config and execute the given Option. -func templateOption(next Option) Option { +func templateOption(next func(t *template.Template) (*template.Template, error)) Option { return func(cfg *gen.Config) (err error) { - if cfg.Template == nil { - cfg.Template = template.New("external").Funcs(gen.Funcs) + tmpl, err := next(template.New("external").Funcs(gen.Funcs).Funcs(cfg.Funcs)) + if err != nil { + return err } - return next(cfg) + cfg.Templates = append(cfg.Templates, tmpl) + return nil } } diff --git a/entc/gen/graph.go b/entc/gen/graph.go index c9bbaa9ff..e9d5f938c 100644 --- a/entc/gen/graph.go +++ b/entc/gen/graph.go @@ -37,15 +37,31 @@ type ( Header string // Storage to support in codegen. Storage *Storage + // IDType specifies the type of the id field in the codegen. // The supported types are string and int, which also the default. IDType *field.TypeInfo - // Template specifies an alternative template to execute or to override - // the default. If nil, the default template is used. + + // Template specifies an alternative template to execute or + // to override the default. If nil, the default template is used. + // + // Deprecated: the Template option predates the Templates option and it + // is planned be removed in v0.5.0. New code should use Templates instead. + Template *template.Template + + // Templates specifies a list of alternative templates to execute or + // to override the default. If nil, the default template is used. // // Note that, additional templates are executed on the Graph object and // the execution output is stored in a file derived by the template name. - Template *template.Template + Templates []*template.Template + + // Funcs specifies external functions to add to the template execution. + // + // Templates that use custom functions and override (or extend) the default + // templates will need to provide the same FuncMap that was used for parsing + // the template. + Funcs template.FuncMap } // Graph holds the nodes/entities of the loaded graph schema. Note that, it doesn't // hold the edges of the graph. Instead, each Type holds the edges for other Types. @@ -109,7 +125,11 @@ func (g *Graph) Gen() (err error) { check(os.MkdirAll(path, os.ModePerm), "create dir %q", path) } b := bytes.NewBuffer(nil) - check(templates.ExecuteTemplate(b, tmpl.Name, g), "execute template %q", tmpl.Name) + execT := templates + if tmpl.external != nil { + execT = tmpl.external + } + check(execT.ExecuteTemplate(b, tmpl.Name, g), "execute template %q", tmpl.Name) target := filepath.Join(g.Config.Target, tmpl.Format) check(ioutil.WriteFile(target, b.Bytes(), 0644), "write file %s", target) written = append(written, target) @@ -403,25 +423,34 @@ func (g *Graph) typ(name string) (*Type, bool) { // templates returns the template.Template for the code and external templates // to execute on the Graph object if provided. func (g *Graph) templates() (*template.Template, []GraphTemplate) { - if g.Template == nil { - return templates, nil + if g.Template != nil { + g.Templates = append(g.Templates, g.Template) } - g.Template.Funcs(Funcs) - external := make([]GraphTemplate, 0, len(g.Template.Templates())) - for _, tmpl := range g.Template.Templates() { - name := tmpl.Name() - // Check that the template is not defined in the default templates if it's not the root. - if templates.Lookup(name) == nil && !parse.IsEmptyTree(tmpl.Root) && !extendExisting(name) { - external = append(external, GraphTemplate{ - Name: name, - Format: snake(name) + ".go", - }) + templates.Funcs(g.Funcs) + external := make([]GraphTemplate, 0, len(g.Templates)) + for _, rootT := range g.Templates { + rootT.Funcs(Funcs) + rootT.Funcs(g.Funcs) + // Make sure external-templates have access to the default-templates. + for _, defaultT := range templates.Templates() { + rootT = template.Must(rootT.AddParseTree(defaultT.Name(), defaultT.Tree)) + } + for _, tmpl := range rootT.Templates() { + switch name := tmpl.Name(); { + case parse.IsEmptyTree(tmpl.Root): + // If this template overrides or extends one of the default templates. + case templates.Lookup(name) != nil || extendExisting(name): + templates = template.Must(templates.AddParseTree(name, tmpl.Tree)) + default: + external = append(external, GraphTemplate{ + Name: name, + Format: snake(name) + ".go", + external: rootT, + }) + } } } - for _, tmpl := range templates.Templates() { - g.Template = template.Must(g.Template.AddParseTree(tmpl.Name(), tmpl.Tree)) - } - return g.Template, external + return templates, external } // ModuleInfo returns the entc binary module version. diff --git a/entc/gen/internal/bindata.go b/entc/gen/internal/bindata.go index d466ed894..56811a1c6 100644 --- a/entc/gen/internal/bindata.go +++ b/entc/gen/internal/bindata.go @@ -266,7 +266,7 @@ func templateBuilderUpdateTmpl() (*asset, error) { return a, nil } -var _templateClientTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xc4\x59\x5f\x73\xe3\xb6\x11\x7f\x16\x3f\xc5\x96\xe3\xbb\x92\x1e\x19\x4c\xf3\x56\x75\xfc\x70\xb1\xaf\x89\x66\x12\x3b\xe9\x39\x6d\x67\x32\x99\x1c\x0c\x82\x12\x62\x0a\xa0\x41\xd0\x96\x47\xf5\x77\xef\xec\x02\xfc\x27\xd1\x3a\x27\x97\x4e\x5f\x6c\x11\x20\x76\x17\xbf\xfd\xed\x62\x17\xdc\xed\xb2\xd3\xe8\xc2\x54\x4f\x56\xad\xd6\x0e\xbe\xfc\xe2\x2f\x7f\x3d\xab\xac\xac\xa5\x76\xf0\x77\x2e\xe4\xad\x31\x77\xb0\xd4\x82\xc1\xbb\xb2\x04\x7a\xa9\x06\x9c\xb7\x0f\x32\x67\xd1\xcd\x5a\xd5\x50\x9b\xc6\x0a\x09\xc2\xe4\x12\x54\x0d\xa5\x12\x52\xd7\x32\x87\x46\xe7\xd2\x82\x5b\x4b\x78\x57\x71\xb1\x96\xf0\x25\xfb\xa2\x9d\x85\xc2\x34\x3a\x8f\x94\xa6\xf9\x6f\x97\x17\xef\xaf\x3e\xbc\x87\x42\x95\x12\xc2\x98\x35\xc6\x41\xae\xac\x14\xce\xd8\x27\x30\x05\xb8\x81\x32\x67\xa5\x64\xd1\x69\xf6\xfc\x1c\x45\xbb\x1d\xe4\xb2\x50\x5a\x42\x2c\x4a\x25\xb5\x8b\x21\x0c\x9f\x54\x77\x2b\x58\x9c\xc3\x2d\xaf\x25\x9c\xb0\x0b\xa3\x0b\xb5\x62\xdf\x73\x71\xc7\x57\x12\x5f\xda\xed\xc0\xc9\x4d\x55\x72\x27\x21\x5e\x4b\x9e\x4b\x1b\xc3\x09\x2d\x57\x9b\xca\x58\x07\x49\x34\x8b\x4b\xb3\x8a\xa3\x68\x16\xa3\xc4\x43\x21\xd9\x46\xad\x2c\x77\x32\x8e\x66\xbb\x1d\x58\xae\x57\x12\x4e\x7e\x99\xc3\x89\x46\xd5\x27\xec\xca\xe4\xb2\x46\x91\x33\x2f\x41\x4f\x88\xf0\xe3\xfd\x00\xc9\x3a\x03\xa9\x73\xb2\x65\x16\xaf\x94\x5b\x37\xb7\x4c\x98\x4d\x56\x04\xb7\x64\x52\xbb\x2c\x57\xbc\x94\xc2\x1d\xe8\x0e\xd6\x93\x01\x1f\x9c\xb1\x7c\x25\xd9\x92\xc6\x6a\x38\xeb\x6d\x09\xaf\x05\x85\xa4\x0f\x67\xd3\x28\xca\x32\xb8\x20\x30\xd1\xa5\xe8\x0f\x0f\x2d\xb8\x35\x77\xb0\x36\x65\x5e\x03\x2f\x4b\xc0\xa1\xdb\x46\x95\xb9\xb4\x35\x8b\xdc\x53\x25\xdb\x65\xb5\xb3\x8d\x70\xb0\x8b\x66\x82\xb6\xeb\x77\xa4\x0a\x34\xa8\xa9\x50\xed\x77\x1e\x37\x0f\x4d\x96\xc1\x07\xb1\x96\x1b\xbe\xa7\xaf\x30\x16\x84\x95\xdc\x29\xbd\x9a\x83\x87\x5a\xe9\x15\x70\x9d\x43\x6e\x4d\x55\xe1\x43\x4d\x2b\x59\x34\x9b\x05\x19\xa7\xc1\x27\xcc\x3f\x8f\xd0\xa4\xdf\x01\xaa\x43\x17\x65\x19\x78\x67\x5c\xf1\x0d\x9a\x36\x61\x8e\xd2\x4e\x5a\x2e\xc8\x8c\x47\xe5\xd6\x34\x3f\x5e\xd4\x43\x32\x9b\x8d\x67\x4e\x47\x8f\x1e\xab\x7d\xf3\x06\x9c\xf4\x6a\xb3\x42\xc9\x32\xaf\x33\x9e\xe7\xca\x29\xa3\x79\x19\x58\xfa\x4c\x8e\xba\x92\x8f\x01\x74\x42\x4a\xd6\xc0\x41\xcb\xc7\xd6\x66\x8f\x7f\x63\x65\xde\x9b\xbb\x52\x0f\x52\x83\xa9\x50\x5a\xcd\xa2\xa2\xd1\xa2\x17\x93\x98\xca\xd5\xc0\x18\xbb\xa6\xf9\x14\x4e\x83\x78\x74\x66\x41\x11\xe5\x65\xee\x4a\xb3\x5a\x40\x69\x56\xec\x7b\xab\xb4\x2b\xf5\x1c\xd6\xc6\xdc\xd5\x0b\x78\x4b\xff\x77\xb8\x1f\x51\xac\x58\x50\x44\x82\x19\x63\x69\x34\x0b\xb6\x2d\xce\xe1\xad\x17\xbe\xf3\x22\x17\x20\x8a\xd5\x73\x3b\xcf\x94\x56\x2e\x49\xa3\x99\x95\xae\xb1\x3a\xec\x08\xb7\x4d\x16\x27\xa2\x35\x2d\x05\xff\x26\x9a\x78\x94\x67\x22\x50\x02\xce\xa1\xe5\xc8\x95\x7c\xf4\x63\x89\x60\xb9\x55\x0f\xd2\xa6\xaf\x26\x0c\x00\xc0\x4c\xb0\xb1\x8f\xcf\x01\xb1\x9c\x70\x74\x22\x98\xdf\xe5\x58\x81\xf7\xe2\x75\x45\x1e\x91\x1a\xdd\x97\x73\xc7\x31\x6b\x65\xf5\x7d\xc9\x2e\xbf\x82\xba\x92\x42\x15\x4a\xe6\x70\xfb\x44\x0e\xf4\x86\x82\x46\xf1\x5c\xe7\x28\x80\x86\xb9\xe3\x6d\x8e\xc4\xb9\x39\x05\x8a\x47\x6f\x8f\x16\xdc\x39\xcc\xca\x39\x38\x03\xca\x31\x6f\x82\x67\x17\x54\xdc\xf2\x8d\x74\xd2\xd6\x20\xb8\x86\x5b\x09\x3c\xcf\x65\xee\xa3\x31\xd0\x09\xe9\xdf\x47\x46\xe0\x10\x6e\x22\xf1\xb6\x5d\x91\x7a\x34\xe8\x03\xd9\x43\x48\xd4\xce\x52\x20\x07\x42\x0c\x49\x96\x04\x57\xce\x41\x5a\x6b\x2c\xb9\xb2\x7e\x54\x4e\xac\xa1\x17\x48\x14\xc4\x6c\xbe\xdb\xc1\xaf\x46\xe9\x41\x7a\xbb\xf4\xa9\xb0\x86\x78\x0e\x78\x02\x2c\x28\xf6\xce\xe0\xc4\x6d\xaa\x12\xdd\x56\x21\x47\x0b\x88\x43\xce\xcc\xde\xd4\x59\x08\x2f\x44\x3d\xee\x45\x85\x0c\x89\x8b\xb7\x5d\x28\x7a\x31\xcc\xcf\xe5\xb2\xe0\x4d\xe9\x50\x45\x60\xa6\x56\xe5\x1c\x8a\x8d\x63\xef\xd1\xf8\x22\x89\x1b\x5d\x7b\xfa\xc9\x3c\xd8\xbf\x80\x37\xf7\xf1\x7c\xb0\x99\x34\x9a\xb5\xce\xbf\xd9\xee\x39\xc9\x59\xae\x6b\x4c\x32\xe4\x8f\x80\x31\xdc\xac\x25\x54\xd6\x3c\x28\x74\x86\x30\xda\xc9\xad\xc3\xe5\xaa\x86\xc6\x1f\xb9\x4e\x95\xe4\x95\xc1\x7a\x9c\x15\x66\xb3\x51\x0e\x6d\x31\x16\xac\x29\x4b\x64\x12\x17\x77\xec\x30\x90\x6e\xb6\x89\x70\xdb\x56\x3a\x1e\x56\xf8\x1f\xfd\x73\xb3\x1d\xfa\x46\x15\xf0\xcb\x1c\xcc\x1d\xa5\x83\x10\x38\x2c\x39\x75\xdb\x4b\x1f\x43\x7f\xc3\xb9\xdd\x11\x84\xda\x03\xfa\xf9\x79\x81\x2c\xd3\x06\x0f\x0d\x6e\x1d\xf0\x91\xf5\x98\xb3\x94\x1e\x0f\xc6\x04\xdd\xcc\x79\x83\xd0\x02\x2d\x1f\xbd\xe1\x73\x18\x44\xb1\x2a\x68\xfe\x4f\xe7\xa8\xfd\xd5\xc6\x90\x15\x74\xc8\x0c\x75\x2e\xe0\xcd\x43\x4c\xfa\xbc\xf2\x71\x26\x6c\x5d\x8c\x06\x50\x56\x14\xac\x34\xab\x39\xe4\xf2\xb6\xa1\x27\xfa\xd1\xe5\x47\xc1\xe8\xc7\x73\x97\xd9\xde\xde\x6c\xd1\x3c\xe1\xb6\x0b\xc0\x5d\xe0\xef\x3e\x21\xce\xfd\x39\xf2\x52\x71\xe1\xf9\x3a\x3e\x69\x16\x2f\xe6\xa0\x62\x95\x06\x79\xed\x79\x3f\x7b\x9e\x23\x22\x11\x55\x4d\x67\x90\x9d\xc2\xb2\x20\x16\xd5\x21\x20\x42\xb6\x09\x8c\xae\xe1\x66\x7b\x1d\x02\x38\x29\xd5\x9d\x84\x0f\x3f\x7c\x9b\x02\x55\x63\x7d\xc4\x4d\x06\x9c\xdb\x86\xc8\x1f\x86\x5b\x58\xa6\x0a\x58\xf3\xfa\x66\x1c\x70\x21\xc7\x4e\xc7\x62\x58\xd8\x96\x49\x59\x06\x97\x88\xf2\x5e\x28\x11\xf2\x67\x6d\x08\x2d\xdd\x9f\x43\xb0\x38\x03\x2b\xe9\xe0\x41\xda\x5b\x53\x4b\xf4\xda\x0a\x9d\x6e\x74\x9b\x6d\x05\xa6\x63\xac\x37\xe8\x8c\xcc\xb2\x28\xcb\xda\x73\x89\xf4\x24\x29\x8e\x12\x92\x89\xd2\xb9\xdc\x76\x0e\xf9\x22\x6d\x41\xf7\x6f\xfc\xd0\x48\xfb\xd4\xbe\x7e\x61\x1a\x74\x83\xdb\xa6\x28\xf3\x20\xfe\x82\xe8\xe1\xa1\xab\x8a\x96\x40\x43\x0e\x8b\x23\x34\x0c\x90\x07\x3b\xdb\x88\x98\x7b\x56\xa6\x93\x14\x75\xb6\x91\x13\xfc\xfc\xdc\x83\x9a\x0a\x49\xc4\x57\xe0\xdf\xba\x3b\xa5\xa8\x26\x17\x46\x6b\xe9\xc3\x1c\xcf\xa9\xca\xca\x07\xa9\x5d\x4d\x6e\xbb\x6f\xa4\x55\xb2\x86\xc2\x9a\x4d\x17\x92\x13\xf9\x8a\xa4\x27\xa9\xcf\x4c\x88\x4f\x6b\x42\x9b\x93\xc2\x0b\xc1\x98\x1f\x6b\x3a\xcc\xbc\x21\x9b\xc6\x91\x7b\xfd\xb6\x91\x11\x58\xd4\xe2\x8c\xd4\x4e\xb9\xa7\xb0\x0f\xf2\x3e\x2c\x35\x18\x4b\x2d\x8d\x41\x09\x83\x35\x3d\x61\x44\x38\xc2\x04\x2f\xcb\x05\x7c\x0c\xe0\x20\x29\xd8\x8f\xb5\x4c\xb0\xf6\xf9\x38\xb1\x07\x9c\xf3\xe2\x18\x63\xdf\x18\x73\xd7\x15\x32\x47\xfb\x89\xbd\xc2\x83\x75\x62\x7c\x8d\x35\x2e\x31\xa2\xe3\xdd\x09\x4a\xea\x7d\x4d\xa1\xdb\x89\x8e\x2f\xfa\xbe\x2a\x14\xc8\xe1\x55\x5f\x20\xf3\x61\x79\x7c\x58\x0d\xb7\xe5\x39\xb5\x07\xe3\xc5\x07\x5d\x42\x68\xdc\xac\x14\x64\x9f\x66\xff\x90\x42\x52\xf2\x79\x7e\xde\xed\x30\x47\xc8\x7b\x3f\x1d\x8b\xd8\x8f\xd1\x53\x9f\x6d\xde\xb0\x2f\x31\xbb\x04\xf5\xff\x81\xd2\x3c\xb6\xab\x07\x89\x22\x24\xc7\xde\x92\x3e\x67\x1c\xdd\x0b\xb1\xb1\xaf\xa0\xbd\xd5\x7d\x01\x3d\x92\x99\x88\x30\x9f\xfa\xb2\xbf\x57\xd6\xb3\xf4\xed\x68\xa2\x8f\xad\xe7\x7d\xba\x72\x28\x55\xed\xb0\x0f\x3e\x24\x2d\xda\xe3\x1f\x6a\x47\x87\x7a\x96\xc1\x3b\xe2\x20\xce\x7e\x44\x5a\x14\x73\xc0\xd3\x27\xfd\x08\xf2\xbe\xe1\x25\x2d\xfb\xb8\xdf\x76\x12\xf5\xea\xa4\x48\x56\xc9\x3a\x49\xd3\x74\xc4\xd5\x91\xa1\x2f\x51\x36\xe4\x8d\x83\x82\x98\x57\x95\xd4\x79\x32\x39\x1d\x92\x0e\x71\x36\x24\x0c\x6a\x63\x86\x2e\xf1\x03\xa1\xad\x22\xd7\x8c\x99\xff\xa2\x99\x5e\x54\x92\xb6\x8d\x97\x7f\x6e\x0d\xdb\x45\xb3\x0e\x4d\x5f\x44\xf8\xb7\xbe\x0b\x83\xe1\xbd\xae\x6e\x9f\xc3\x75\xe5\x25\xa4\x63\x0f\xee\x09\xee\xfd\xd8\x2d\xec\x12\xab\xc7\x38\x9d\x77\x7e\x5c\x74\xbf\x5a\xa7\x7f\xd5\x94\x77\x07\x18\x0c\x37\xdf\x76\xc4\x34\x5c\xde\x21\x2b\xc6\x88\x53\xfa\x52\xb2\xfe\x14\x30\xa8\x29\x69\xbb\x55\xf4\xe4\x14\x4c\x7b\xe0\xe1\x9a\x01\x80\x53\x30\x0c\x5e\x99\x80\xa2\xd5\xb7\xe8\x7e\x75\x6c\xaf\xf2\xd1\xa6\x35\x34\x7e\xe4\x77\x78\xde\xcb\xea\x3d\xef\x9f\x3f\xc7\xf3\x5e\xc2\x81\xe7\x47\x82\x3f\xd3\xf3\x5e\xd6\xb5\xfe\x14\x06\x7d\x06\xf2\x07\xd5\xa7\x60\xb8\xd6\x32\x69\x53\xe5\xc1\x2d\xc4\x1e\x44\xd7\xfa\x0f\x40\xe9\x5a\xcb\x39\x7a\xca\x1f\x24\x31\x16\xf1\xf1\x40\xe5\xc0\x98\xf4\x05\x40\x7b\x33\xfe\x28\x4c\x97\x97\xaf\x46\x55\xe5\xaf\x40\x74\x79\x99\xa8\x3c\xd0\x71\x79\xc9\x6e\xf0\x78\xfb\x3f\xa0\x19\x2f\x2f\xf1\x24\x4c\x54\xfe\x3f\x87\xf2\x52\x96\x72\x94\x94\x72\x3f\xf0\x3b\xc2\xd3\x8b\xea\xc3\xd3\x3f\x7f\x0e\x54\x5e\xc2\x01\x04\x23\xc1\x7f\xc8\xfe\x47\xe1\x39\x05\xc1\xeb\xa3\xb3\x13\xf8\x8a\xe8\xec\xde\x3d\x4c\xbe\xa2\x9f\x5c\x5e\x0e\x44\xb1\xe5\x65\xba\x6f\xfa\x30\x0a\x8e\x1b\x7f\x2c\x08\x86\xfa\x8e\x05\xc1\x94\xd1\xad\x36\xba\x38\x68\x79\xc0\xfe\xb5\x96\xd6\xc3\x30\x2a\x49\x48\x3e\x12\x3b\xac\x62\xad\x4f\x98\xca\xe1\x1c\xde\xaa\x7c\x62\xca\x54\x70\xde\x31\xe2\x5a\xcb\x69\x4e\x0c\xc2\x22\x48\x68\xfd\x4c\xfd\xda\x00\xa6\x7b\x7a\xfe\x1d\x2c\x0f\x8d\x5f\x8b\x06\x3d\xbe\x78\x76\x0e\x67\x0f\x88\xda\x9a\xf6\xb5\x74\x03\xc3\x26\x4e\xfd\x27\xb8\x7d\x02\xe5\xea\xa3\xee\xfb\x5a\xba\xa9\x5b\x9e\x39\x4c\xfa\x32\x39\xdd\x2b\xd8\xfa\x5b\xa0\x8e\x80\x6d\x8b\x7b\xdc\x8d\xec\x5a\x97\x4f\xbe\xf7\xed\xb6\xf3\x6f\xff\xd5\xe8\x4e\xe2\x03\x56\x07\x0e\x2a\xae\x95\xa8\xb1\xda\xe7\x3a\x34\x76\x46\x88\xc6\x1e\xa9\x67\x50\xd0\x6f\xd8\xd2\x78\x47\xb8\x13\x73\xfb\x6b\x77\x9b\x24\x58\x00\x08\x57\x4f\xde\x23\x91\x85\x49\x77\x19\x14\x60\x30\xb7\xbf\x86\x0e\x66\xd0\x69\xc9\xd0\xc9\xbc\xcf\x57\x7d\xab\x35\x88\x81\x13\x49\x66\x8d\xdc\xdf\x91\x10\x93\x3e\xaf\x05\x2f\xf1\xb5\xd6\xda\xb6\x35\x6e\xdb\x93\x7e\x46\xe6\x2b\x89\xd5\x20\xff\x4d\x04\x9d\x52\xf2\xc9\x84\xd4\xee\xc0\xa3\xe7\x23\x64\x71\xee\xb9\xdc\xcf\x4d\xf0\xd8\xbf\xcb\x2a\xee\xd6\x70\x0e\x68\xd8\x0b\x17\x8e\xd8\x6b\xfd\x93\x36\xd2\x5d\xf2\x7e\xd5\x09\x9e\xc3\x2f\x03\x1a\x52\xaf\x4b\x5f\x37\xe4\xd6\x61\x9b\x77\xa2\x21\x6e\x5b\xc7\x38\x34\x8c\xe8\x80\x18\xfd\x11\x2f\x73\x6a\x67\x63\xd2\x10\x43\x7f\x7d\x76\xe4\xae\x98\xac\xce\x70\xc5\xde\xdd\xd5\xec\xe8\x55\x71\xd7\x85\xfb\xa7\x40\x14\x52\xec\x2f\xdd\x06\xf4\x21\x15\x11\x11\x64\xd0\xaa\xd2\xb9\xd4\xc5\xfc\xe0\x63\x94\x6f\x9b\x5e\x74\x6d\x38\xcf\xe0\xa7\x9f\xf1\xd7\xe0\xcb\x88\xb1\xe4\xcd\x66\xe3\x25\x9f\x68\xf6\x0d\xaf\xbf\x37\xa5\x12\x4f\x7e\x3f\xbe\xaf\xa3\x38\x98\xe8\xd7\xfa\x5d\x84\xae\x8e\xde\xf9\x69\x51\x4a\xed\x7f\xa6\x83\x9f\x3f\xcf\x61\xba\xcb\xfc\x69\xf1\xf3\xe0\x96\xa2\xac\xc7\x92\x5f\x50\x3c\xbe\xd1\xe8\x61\x1a\x00\xb6\xdb\x65\xa7\xf0\xae\xff\x84\x46\x1f\x2c\xc3\x47\x0c\xf3\x20\xad\xa5\xbb\x73\xb5\x77\x97\xd3\x7f\x59\x03\xff\xad\xad\x6d\xab\xc3\x0d\x4e\xb8\xdb\xdc\xfb\xd0\x3c\xf5\x5d\x6e\x74\xd1\xf0\xdf\x00\x00\x00\xff\xff\x08\x95\xba\x14\x5f\x1f\x00\x00") +var _templateClientTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xc4\x59\x5f\x73\xe3\xb6\x11\x7f\x16\x3f\xc5\x96\xe3\xbb\x92\x1e\x19\x4c\xf3\x56\x75\xfc\x70\xb1\xaf\x89\x66\x12\x3b\xe9\x39\x6d\x67\x32\x99\x1c\x0c\x82\x12\x62\x0a\xa0\x41\xd0\x96\x47\xf5\x77\xef\xec\x02\xfc\x27\xd1\x3a\x27\x97\x4e\x5f\x6c\x11\x20\x76\x17\xbf\xfd\xed\x62\x17\xdc\xed\xb2\xd3\xe8\xc2\x54\x4f\x56\xad\xd6\x0e\xbe\xfc\xe2\x2f\x7f\x3d\xab\xac\xac\xa5\x76\xf0\x77\x2e\xe4\xad\x31\x77\xb0\xd4\x82\xc1\xbb\xb2\x04\x7a\xa9\x06\x9c\xb7\x0f\x32\x67\xd1\xcd\x5a\xd5\x50\x9b\xc6\x0a\x09\xc2\xe4\x12\x54\x0d\xa5\x12\x52\xd7\x32\x87\x46\xe7\xd2\x82\x5b\x4b\x78\x57\x71\xb1\x96\xf0\x25\xfb\xa2\x9d\x85\xc2\x34\x3a\x8f\x94\xa6\xf9\x6f\x97\x17\xef\xaf\x3e\xbc\x87\x42\x95\x12\xc2\x98\x35\xc6\x41\xae\xac\x14\xce\xd8\x27\x30\x05\xb8\x81\x32\x67\xa5\x64\xd1\x69\xf6\xfc\x1c\x45\xbb\x1d\xe4\xb2\x50\x5a\x42\x2c\x4a\x25\xb5\x8b\x21\x0c\x9f\x54\x77\x2b\x58\x9c\xc3\x2d\xaf\x25\x9c\xb0\x0b\xa3\x0b\xb5\x62\xdf\x73\x71\xc7\x57\x12\x5f\xda\xed\xc0\xc9\x4d\x55\x72\x27\x21\x5e\x4b\x9e\x4b\x1b\xc3\x09\x2d\x57\x9b\xca\x58\x07\x49\x34\x8b\x4b\xb3\x8a\xa3\x68\x16\xa3\xc4\x43\x21\xd9\x46\xad\x2c\x77\x32\x8e\x66\xbb\x1d\x58\xae\x57\x12\x4e\x7e\x99\xc3\x89\x46\xd5\x27\xec\xca\xe4\xb2\x46\x91\x33\x2f\x41\x4f\x88\xf0\xe3\xfd\x00\xc9\x3a\x03\xa9\x73\xb2\x65\x16\xaf\x94\x5b\x37\xb7\x4c\x98\x4d\x56\x04\xb7\x64\x52\xbb\x2c\x57\xbc\x94\xc2\x1d\xe8\x0e\xd6\x93\x01\x1f\x9c\xb1\x7c\x25\xd9\x92\xc6\x6a\x38\xeb\x6d\x09\xaf\x05\x85\xa4\x0f\x67\xd3\x28\xca\x32\xb8\x20\x30\xd1\xa5\xe8\x0f\x0f\x2d\xb8\x35\x77\xb0\x36\x65\x5e\x03\x2f\x4b\xc0\xa1\xdb\x46\x95\xb9\xb4\x35\x8b\xdc\x53\x25\xdb\x65\xb5\xb3\x8d\x70\xb0\x8b\x66\x82\xb6\xeb\x77\xa4\x0a\x34\xa8\xa9\x50\xed\x77\x1e\x37\x0f\x4d\x96\xc1\x07\xb1\x96\x1b\xbe\xa7\xaf\x30\x16\x84\x95\xdc\x29\xbd\x9a\x83\x87\x5a\xe9\x15\x70\x9d\x43\x6e\x4d\x55\xe1\x43\x4d\x2b\x59\x34\x9b\x05\x19\xa7\xc1\x27\xcc\x3f\x8f\xd0\xa4\xdf\x01\xaa\x43\x17\x65\x19\x78\x67\x5c\xf1\x0d\x9a\x36\x61\x8e\xd2\x4e\x5a\x2e\xc8\x8c\x47\xe5\xd6\x34\x3f\x5e\xd4\x43\x32\x9b\x8d\x67\x4e\x47\x8f\x1e\xab\x7d\xf3\x06\x9c\xf4\x6a\xb3\x42\xc9\x32\xaf\x33\x9e\xe7\xca\x29\xa3\x79\x19\x58\xfa\x4c\x8e\xba\x92\x8f\x01\x74\x42\x4a\xd6\xc0\x41\xcb\xc7\xd6\x66\x8f\x7f\x63\x65\xde\x9b\xbb\x52\x0f\x52\x83\xa9\x50\x5a\xcd\xa2\xa2\xd1\xa2\x17\x93\x98\xca\xd5\xc0\x18\xbb\xa6\xf9\x14\x4e\x83\x78\x74\x66\x41\x11\xe5\x65\xee\x4a\xb3\x5a\x40\x69\x56\xec\x7b\xab\xb4\x2b\xf5\x1c\xd6\xc6\xdc\xd5\x0b\x78\x4b\xff\x77\xb8\x1f\x51\xac\x58\x50\x44\x82\x19\x63\x69\x34\x0b\xb6\x2d\xce\xe1\xad\x17\xbe\xf3\x22\x17\x20\x8a\xd5\x73\x3b\xcf\x94\x56\x2e\x49\xa3\x99\x95\xae\xb1\x3a\xec\x08\xb7\x4d\x16\x27\xa2\x35\x2d\x05\xff\x26\x9a\x78\x94\x67\x22\x50\x02\xce\xa1\xe5\xc8\x95\x7c\xf4\x63\x89\x60\xb9\x55\x0f\xd2\xa6\xaf\x26\x0c\x00\xc0\x4c\xb0\xb1\x8f\xcf\x01\xb1\x9c\x70\x74\x22\x98\xdf\xe5\x58\x81\xf7\xe2\x75\x45\x1e\x91\x1a\xdd\x97\x73\xc7\x31\x6b\x65\xf5\x7d\xc9\x2e\xbf\x82\xba\x92\x42\x15\x4a\xe6\x70\xfb\x44\x0e\xf4\x86\x82\x46\xf1\x5c\xe7\x28\x80\x86\xb9\xe3\x6d\x8e\xc4\xb9\x39\x05\x8a\x47\x6f\x8f\x16\xdc\x39\xcc\xca\x39\x38\x03\xca\x31\x6f\x82\x67\x17\x54\xdc\xf2\x8d\x74\xd2\xd6\x20\xb8\x86\x5b\x09\x3c\xcf\x65\xee\xa3\x31\xd0\x09\xe9\xdf\x47\x46\xe0\x10\x6e\x22\xf1\xb6\x5d\x91\x7a\x34\xe8\x03\xd9\x43\x48\xd4\xce\x52\x20\x07\x42\x0c\x49\x96\x04\x57\xce\x41\x5a\x6b\x2c\xb9\xb2\x7e\x54\x4e\xac\xa1\x17\x48\x14\xc4\x6c\xbe\xdb\xc1\xaf\x46\xe9\x41\x7a\xbb\xf4\xa9\xb0\x86\x78\x0e\x78\x02\x2c\x28\xf6\xce\xe0\xc4\x6d\xaa\x12\xdd\x56\x21\x47\x0b\x88\x43\xce\xcc\xde\xd4\x59\x08\x2f\x44\x3d\xee\x45\x85\x0c\x89\x8b\xb7\x5d\x28\x7a\x31\xcc\xcf\xe5\xb2\xe0\x4d\xe9\x50\x45\x60\xa6\x56\xe5\x1c\x8a\x8d\x63\xef\xd1\xf8\x22\x89\x1b\x5d\x7b\xfa\xc9\x3c\xd8\xbf\x80\x37\xf7\xf1\x7c\xb0\x99\x34\x9a\xb5\xce\xbf\xd9\xee\x39\xc9\x59\xae\x6b\x4c\x32\xe4\x8f\x80\x31\xdc\xac\x25\x54\xd6\x3c\x28\x74\x86\x30\xda\xc9\xad\xc3\xe5\xaa\x86\xc6\x1f\xb9\x4e\x95\xe4\x95\xc1\x7a\x9c\x15\x66\xb3\x51\x0e\x6d\x31\x16\xac\x29\x4b\x64\x12\x17\x77\xec\x30\x90\x6e\xb6\x89\x70\xdb\x56\x3a\x1e\x56\xf8\x1f\xfd\x73\xb3\x1d\xfa\x46\x15\xf0\xcb\x1c\xcc\x1d\xa5\x83\x10\x38\x2c\x39\x75\xdb\x4b\x1f\x43\x7f\xc3\xb9\xdd\x11\x84\xda\x03\xfa\xf9\x79\x81\x2c\xd3\x06\x0f\x0d\x6e\x1d\xf0\x91\xf5\x98\xb3\x94\x1e\x0f\xc6\x04\xdd\xcc\x79\x83\xd0\x02\x2d\x1f\xbd\xe1\x73\x18\x44\xb1\x2a\x68\xfe\x4f\xe7\xa8\xfd\xd5\xc6\x90\x15\x74\xc8\x0c\x75\x2e\xe0\xcd\x43\x4c\xfa\xbc\xf2\x71\x26\x6c\x5d\x8c\x06\x50\x56\x14\xac\x34\xab\x39\xe4\xf2\xb6\xa1\x27\xfa\xd1\xe5\x47\xc1\xe8\xc7\x73\x97\xd9\xde\xde\x6c\xd1\x3c\xe1\xb6\x0b\xc0\x5d\xe0\xef\x3e\x21\xce\xfd\x39\xf2\x52\x71\xe1\xf9\x3a\x3e\x69\x16\x2f\xe6\xa0\x62\x95\x06\x79\xed\x79\x3f\x7b\x9e\x23\x22\x11\x55\x4d\x67\x90\x9d\xc2\xb2\x20\x16\xd5\x21\x20\x42\xb6\x09\x8c\xae\xe1\x66\x7b\x1d\x02\x38\x29\xd5\x9d\x84\x0f\x3f\x7c\x9b\x02\x55\x63\x7d\xc4\x4d\x06\x9c\xdb\x86\xc8\x1f\x86\x5b\x58\xa6\x0a\x58\xf3\xfa\x66\x1c\x70\x21\xc7\x4e\xc7\x62\x58\xd8\x96\x49\x59\x06\x97\x88\xf2\x5e\x28\x11\xf2\x67\x6d\x08\x2d\xdd\x9f\x43\xb0\x38\x03\x2b\xe9\xe0\x41\xda\x5b\x53\x4b\xf4\xda\x0a\x9d\x6e\x74\x9b\x6d\x05\xa6\x63\xac\x37\xe8\x8c\xcc\xb2\x28\xcb\xda\x73\x89\xf4\x24\x29\x8e\x12\x92\x89\xd2\xb9\xdc\x76\x0e\xf9\x22\x6d\x41\xf7\x6f\xfc\xd0\x48\xfb\xd4\xbe\x7e\x61\x1a\x74\x83\xdb\xa6\x28\xf3\x20\xfe\x82\xe8\xe1\xa1\xab\x8a\x96\x40\x43\x0e\x8b\x23\x34\x0c\x90\x07\x3b\xdb\x88\x98\x7b\x56\xa6\x93\x14\x75\xb6\x91\x13\xfc\xfc\xdc\x83\x9a\x0a\x49\xc4\x57\xe0\xdf\xba\x3b\xa5\xa8\x26\x17\x46\x6b\xe9\xc3\x1c\xcf\xa9\xca\xca\x07\xa9\x5d\x4d\x6e\xbb\x6f\xa4\x55\xb2\x86\xc2\x9a\x4d\x17\x92\x13\xf9\x8a\xa4\x27\xa9\xcf\x4c\x88\x4f\x6b\x42\x9b\x93\xc2\x0b\xc1\x98\x1f\x6b\x3a\xcc\xbc\x21\x9b\xc6\x91\x7b\xfd\xb6\x91\x11\x58\xd4\xe2\x8c\xd4\x4e\xb9\xa7\xb0\x0f\xf2\x3e\x2c\x35\x18\x4b\x2d\x8d\x41\x09\x83\x35\x3d\x61\x44\x38\xc2\x04\x2f\xcb\x05\x7c\x0c\xe0\x20\x29\xd8\x8f\xb5\x4c\xb0\xf6\xf9\x38\xb1\x07\x9c\xf3\xe2\x18\x63\xdf\x18\x73\xd7\x15\x32\x47\xfb\x89\xbd\xc2\x83\x75\x62\x7c\x8d\x35\x2e\x31\xa2\x3e\x81\xec\x4b\x42\x29\xbd\x9f\x29\x6c\x3b\xb1\xf1\x45\xdf\x53\x85\xe2\x38\xbc\xea\x8b\x63\x3e\x2c\x8d\x0f\x2b\xe1\xb6\x34\xa7\xd6\x60\xbc\xf8\xa0\x43\x08\x4d\x9b\x95\x82\xec\xd3\xec\x1f\x52\x48\x4a\x3c\xcf\xcf\xbb\x1d\xe6\x07\x79\xef\xa7\x63\x11\xfb\x31\x7a\xea\x33\xcd\x1b\xf6\x25\x66\x96\xa0\xfe\x3f\x50\x9a\xc7\x76\xf5\x20\x49\x84\xc4\xd8\x5b\xd2\xe7\x8b\xa3\x7b\x21\x26\xf6\xd5\xb3\xb7\xba\x2f\x9e\x47\x32\x13\x11\xe6\x53\x5f\xf2\xf7\xca\x7a\x86\xbe\x1d\x4d\xf4\x71\xf5\xbc\x4f\x55\x0e\xa5\xaa\x1d\xf6\xc0\x87\x84\x45\x7b\xfc\x43\xed\xe8\x40\xcf\x32\x78\x47\xfc\xc3\xd9\x8f\x48\x89\x62\x0e\x78\xf2\xa4\x1f\x41\xde\x37\xbc\xa4\x65\x1f\xf7\x5b\x4e\xa2\x5d\x9d\x14\xc9\x2a\x59\x27\x69\x9a\x8e\x78\x3a\x32\xf4\x25\xba\x86\x9c\x71\x50\x0c\xf3\xaa\x92\x3a\x4f\x26\xa7\x43\xc2\x21\xbe\x86\x64\x41\x2d\xcc\xd0\x25\x7e\x20\xb4\x54\xe4\x9a\x31\xeb\x5f\x34\xd3\x8b\x4a\xd2\xb6\xe9\xf2\xcf\xad\x61\xbb\x68\xd6\xa1\xe9\x0b\x08\xff\xd6\x77\x61\x30\xbc\xd7\xd5\xec\x73\xb8\xae\xbc\x84\x74\xec\xc1\x3d\xc1\xbd\x1f\xbb\x85\x5d\x52\xf5\x18\xa7\xf3\xce\x8f\x8b\xee\x57\xeb\xf4\xaf\x9a\xf2\xee\x00\x83\xe1\xe6\xdb\x6e\x98\x86\xcb\x3b\x64\xc5\x18\x71\x4a\x5d\x4a\xd6\x9f\x02\x06\x35\x25\x6d\xa7\x8a\x9e\x9c\x82\x69\x0f\x3c\x5c\x33\x00\x70\x0a\x86\xc1\x2b\x13\x50\xb4\xfa\x16\xdd\xaf\x8e\xed\x55\x3e\xda\xb4\x86\xc6\x8f\xfc\x0e\xcf\x7b\x59\xbd\xe7\xfd\xf3\xe7\x78\xde\x4b\x38\xf0\xfc\x48\xf0\x67\x7a\xde\xcb\xba\xd6\x9f\xc2\xa0\xcf\x40\xfe\x90\xfa\x14\x0c\xd7\x5a\x26\x6d\xaa\x3c\xb8\x81\xd8\x83\xe8\x5a\xff\x01\x28\x5d\x6b\x39\x47\x4f\xf9\x83\x24\xc6\x02\x3e\x1e\xa8\x1c\x18\x93\xbe\x00\x68\x6f\xc6\x1f\x85\xe9\xf2\xf2\xd5\xa8\xaa\xfc\x15\x88\x2e\x2f\x13\x95\x07\x3a\x2e\x2f\xd9\x0d\x1e\x6f\xff\x07\x34\xe3\xe5\x25\x9e\x84\x89\xca\xff\xe7\x50\x5e\xca\x52\x8e\x92\x52\xee\x07\x7e\x47\x78\x7a\x51\x7d\x78\xfa\xe7\xcf\x81\xca\x4b\x38\x80\x60\x24\xf8\x0f\xd9\xff\x28\x3c\xa7\x20\x78\x7d\x74\x76\x02\x5f\x11\x9d\xdd\xbb\x87\xc9\x57\xf4\x93\xcb\xcb\x81\x28\xb6\xbc\x4c\xf7\x4d\x1f\x46\xc1\x71\xe3\x8f\x05\xc1\x50\xdf\xb1\x20\x98\x32\xba\xd5\x46\x97\x06\x2d\x0f\xd8\xbf\xd6\xd2\x7a\x18\x46\x25\x09\xc9\x47\x62\x87\x55\xac\xf5\x09\x53\x39\x9c\xc3\x5b\x95\x4f\x4c\x99\x0a\xce\x3b\x46\x5c\x6b\x39\xcd\x89\x41\x58\x04\x09\xad\x9f\xa9\x57\x1b\xc0\x74\x4f\xcf\xbf\x83\xe5\xa1\xe9\x6b\xd1\xa0\xc7\x17\xcf\xce\xe1\xec\x01\x51\x5b\xd3\xbe\x96\x6e\x60\xd8\xc4\xa9\xff\x04\xb7\x4f\xa0\x5c\x7d\xd4\x7d\x5f\x4b\x37\x75\xc3\x33\x87\x49\x5f\x26\xa7\x7b\x05\x5b\x7f\x03\xd4\x11\xb0\x6d\x6f\x8f\xbb\x91\x5d\xeb\xf2\xc9\xf7\xbd\xdd\x76\xfe\xed\xbf\x18\xdd\x49\x7c\xc0\xea\xc0\x41\xc5\xb5\x12\x35\x56\xfb\x5c\x87\xa6\xce\x08\xd1\xd8\x23\xf5\x0c\x0a\xfa\x0d\x5b\x1a\xef\x08\x77\x62\x6e\x7f\xed\x6e\x92\x04\x0b\x00\xe1\xea\xc9\x3b\x24\xb2\x30\xe9\x2e\x82\x02\x0c\xe6\xf6\xd7\xd0\xc1\x0c\x7a\x36\x19\x3a\x99\xf7\xf9\xaa\x6f\xb5\x06\x31\x70\x22\xc9\xac\x91\xfb\x3b\x12\x62\xd2\xe7\xb5\xe0\x25\xbe\xd6\x5a\xdb\xb6\xc5\x6d\x7b\xd2\xcf\xc8\x7c\x25\xb1\x1a\xe4\xbf\x89\xa0\x53\x4a\x3e\x99\x90\xda\x1d\x78\xf4\x7c\x84\x2c\xce\x3d\x97\xfb\xb9\x09\x1e\xfb\x77\x59\xc5\xdd\x1a\xce\x01\x0d\x7b\xe1\xb2\x11\x7b\xad\x7f\xd2\x46\xba\x0b\xde\xaf\x3a\xc1\x73\xf8\x65\x40\x43\xea\x73\xe9\xcb\x86\xdc\x3a\x6c\xf3\x4e\x34\xc4\x6d\xeb\x18\x87\x86\x11\x1d\x10\xa3\x3f\xe2\x65\x4e\xed\x6c\x4c\x1a\x62\xe8\xaf\xce\x8e\xdc\x13\x93\xd5\x19\xae\xd8\xbb\xb7\x9a\x1d\xbd\x26\xee\x3a\x70\xff\x14\x88\x42\x8a\xfd\x85\xdb\x80\x3e\xa4\x22\x22\x82\x0c\x5a\x55\x3a\x97\xba\x98\x1f\x7c\x88\xf2\x6d\xd3\x8b\xae\x0d\xe7\x19\xfc\xf4\x33\xfe\x1a\x7c\x15\x31\x96\xbc\xd9\x6c\xbc\xe4\x13\xcd\xbe\xe1\xf5\xf7\xa6\x54\xe2\xc9\xef\xc7\xf7\x75\x14\x07\x13\xfd\x5a\xbf\x8b\xd0\xd5\xd1\x3b\x3f\x2d\x4a\xa9\xfd\xcf\x74\xf0\xf3\xe7\x39\x4c\x77\x99\x3f\x2d\x7e\x1e\xdc\x50\x94\xf5\x58\xf2\x0b\x8a\xc7\xb7\x19\x3d\x4c\x03\xc0\x76\xbb\xec\x14\xde\xf5\x9f\xcf\xe8\x63\x65\xf8\x80\x61\x1e\xa4\xb5\x74\x6f\xae\xf6\xee\x71\xfa\xaf\x6a\xe0\xbf\xb3\xb5\x6d\x75\xb8\xbd\x09\xf7\x9a\x7b\x1f\x99\xa7\xbe\xc9\x8d\x2e\x1a\xfe\x1b\x00\x00\xff\xff\x16\x82\xd7\xa9\x5b\x1f\x00\x00") func templateClientTmplBytes() ([]byte, error) { return bindataRead( @@ -281,7 +281,7 @@ func templateClientTmpl() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "template/client.tmpl", size: 8031, mode: os.FileMode(420), modTime: time.Unix(1, 0)} + info := bindataFileInfo{name: "template/client.tmpl", size: 8027, mode: os.FileMode(420), modTime: time.Unix(1, 0)} a := &asset{bytes: bytes, info: info} return a, nil } diff --git a/entc/gen/template.go b/entc/gen/template.go index 13a84686b..78d72e930 100644 --- a/entc/gen/template.go +++ b/entc/gen/template.go @@ -29,9 +29,10 @@ type ( // GraphTemplate specifies a template that is executed with // the Graph object. GraphTemplate struct { - Name string // template name. - Skip func(*Graph) bool // skip condition. - Format string // file name format. + Name string // template name. + Skip func(*Graph) bool // skip condition. + Format string // file name format. + external *template.Template // external template. } ) diff --git a/entc/gen/template/client.tmpl b/entc/gen/template/client.tmpl index b3faced0c..d1ee4b230 100644 --- a/entc/gen/template/client.tmpl +++ b/entc/gen/template/client.tmpl @@ -125,7 +125,7 @@ func (c *Client) Use(hooks ...Hook) { } -{{ range $_, $n := $.Nodes }} +{{ range $n := $.Nodes }} {{ $client := print $n.Name "Client" }} // {{ $client }} is a client for the {{ $n.Name }} schema. type {{ $client }} struct { diff --git a/examples/entcpkg/ent/debug.go b/examples/entcpkg/ent/debug.go new file mode 100644 index 000000000..1981dfb4b --- /dev/null +++ b/examples/entcpkg/ent/debug.go @@ -0,0 +1,17 @@ +// Copyright 2019-present Facebook Inc. All rights reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package ent + +import "github.com/facebook/ent/dialect" + +func (c *UserClient) Debug() *UserClient { + if c.debug { + return c + } + cfg := config{driver: dialect.Debug(c.driver, c.log), log: c.log, debug: true, hooks: c.hooks} + return &UserClient{config: cfg} +} diff --git a/examples/entcpkg/ent/entc.go b/examples/entcpkg/ent/entc.go index c827f043f..915650fc5 100644 --- a/examples/entcpkg/ent/entc.go +++ b/examples/entcpkg/ent/entc.go @@ -16,6 +16,13 @@ import ( ) func main() { + // A usage for custom templates with external functions. + // One template is defined in the option below, and the + // second template is provided with the `Templates` field. + opts := []entc.Option{ + entc.Funcs(template.FuncMap{"title": strings.ToTitle}), + entc.TemplateFiles("template/static.tmpl"), + } err := entc.Generate("./schema", &gen.Config{ Header: ` // Copyright 2019-present Facebook Inc. All rights reserved. @@ -24,11 +31,12 @@ func main() { // Code generated by entc, DO NOT EDIT. `, - // A usage for custom templates with external functions. - Template: template.Must(template.New("template"). - Funcs(template.FuncMap{"title": strings.ToTitle}). - ParseFiles("template/static.tmpl")), - }) + Templates: []*template.Template{ + template.Must(template.New("debug"). + Funcs(gen.Funcs). + ParseFiles("template/debug.tmpl")), + }, + }, opts...) if err != nil { log.Fatal("running ent codegen:", err) } diff --git a/examples/entcpkg/ent/template/debug.tmpl b/examples/entcpkg/ent/template/debug.tmpl new file mode 100644 index 000000000..2028c64f4 --- /dev/null +++ b/examples/entcpkg/ent/template/debug.tmpl @@ -0,0 +1,22 @@ +{{ define "debug" }} + +{{/* A template that will be generated to a file named "debug.go" and + add the functionality for running each client in debug mode */}} + +{{/* Add the base header for the generated file */}} +{{ $pkg := base $.Config.Package }} +{{ template "header" $ }} + +{{/* Loop over all nodes and add option the "Debug()" method */}} +{{ range $n := $.Nodes }} + {{ $client := print $n.Name "Client" }} + func (c *{{ $client }}) Debug() *{{ $client }} { + if c.debug { + return c + } + cfg := config{driver: dialect.Debug(c.driver, c.log), log: c.log, debug: true, hooks: c.hooks} + return &{{ $client }}{config: cfg} + } +{{ end }} + +{{ end }} \ No newline at end of file