diff --git a/entc/entc.go b/entc/entc.go index d90995e29..68bfbb0b4 100644 --- a/entc/entc.go +++ b/entc/entc.go @@ -17,6 +17,7 @@ import ( "github.com/facebook/ent/entc/gen" "github.com/facebook/ent/entc/load" + "github.com/facebook/ent/schema/field" ) // LoadGraph loads the schema package from the given schema path, @@ -57,6 +58,9 @@ func Generate(schemaPath string, cfg *gen.Config, options ...Option) (err error) // the schema. cfg.Target = filepath.Dir(abs) } + if cfg.IDType == nil { + cfg.IDType = &field.TypeInfo{Type: field.TypeInt} + } for _, opt := range options { if err := opt(cfg); err != nil { return err diff --git a/entc/gen/graph.go b/entc/gen/graph.go index 3464807fd..c9bbaa9ff 100644 --- a/entc/gen/graph.go +++ b/entc/gen/graph.go @@ -85,9 +85,10 @@ func NewGraph(c *Config, schemas ...*load.Schema) (g *Graph, err error) { func (g *Graph) Gen() (err error) { defer catch(&err) var ( - written []string - templates, external = g.templates() + written []string + external []GraphTemplate ) + templates, external = g.templates() for _, n := range g.Nodes { path := filepath.Join(g.Config.Target, n.Package()) check(os.MkdirAll(path, os.ModePerm), "create dir %q", path) @@ -402,24 +403,25 @@ 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) { - templates = template.Must(templates.Clone()) if g.Template == nil { return templates, nil } - external := make([]GraphTemplate, 0) + g.Template.Funcs(Funcs) + external := make([]GraphTemplate, 0, len(g.Template.Templates())) for _, tmpl := range g.Template.Templates() { name := tmpl.Name() - // Check that is not defined in the default templates - // if it's not the root. + // 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 = template.Must(templates.AddParseTree(name, tmpl.Tree)) } - return templates, external + for _, tmpl := range templates.Templates() { + g.Template = template.Must(g.Template.AddParseTree(tmpl.Name(), tmpl.Tree)) + } + return g.Template, external } // ModuleInfo returns the entc binary module version. diff --git a/examples/entcpkg/ent/entc.go b/examples/entcpkg/ent/entc.go index 50c1f1b23..c827f043f 100644 --- a/examples/entcpkg/ent/entc.go +++ b/examples/entcpkg/ent/entc.go @@ -8,10 +8,11 @@ package main import ( "log" + "strings" + "text/template" "github.com/facebook/ent/entc" "github.com/facebook/ent/entc/gen" - "github.com/facebook/ent/schema/field" ) func main() { @@ -23,7 +24,10 @@ func main() { // Code generated by entc, DO NOT EDIT. `, - IDType: &field.TypeInfo{Type: field.TypeInt}, + // A usage for custom templates with external functions. + Template: template.Must(template.New("template"). + Funcs(template.FuncMap{"title": strings.ToTitle}). + ParseFiles("template/static.tmpl")), }) if err != nil { log.Fatal("running ent codegen:", err) diff --git a/examples/entcpkg/ent/template/static.tmpl b/examples/entcpkg/ent/template/static.tmpl new file mode 100644 index 000000000..4c4cc86d0 --- /dev/null +++ b/examples/entcpkg/ent/template/static.tmpl @@ -0,0 +1,9 @@ +{{/* A template for adding additional static fields to specific types. */}} +{{ define "model/fields/additional" }} + {{- /* Add static fields to the "Card" entity. */}} + {{- if eq $.Name "User" }} + {{- /* A usage of an external function. */ -}} + // StaticField defined by templates (titled {{ title "staticField" }}). + StaticField string `json:"static_field,omitempty"` + {{- end }} +{{ end }} \ No newline at end of file diff --git a/examples/entcpkg/ent/user.go b/examples/entcpkg/ent/user.go index edae26a80..8c57f1b39 100644 --- a/examples/entcpkg/ent/user.go +++ b/examples/entcpkg/ent/user.go @@ -19,6 +19,9 @@ type User struct { config // ID of the ent. ID int `json:"id,omitempty"` + + // StaticField defined by templates (titled STATICFIELD). + StaticField string `json:"static_field,omitempty"` } // scanValues returns the types for scanning values from sql.Rows. diff --git a/go.mod b/go.mod index 4f56c4774..0262fcb0d 100644 --- a/go.mod +++ b/go.mod @@ -26,6 +26,6 @@ require ( github.com/stretchr/testify v1.6.1 go.opencensus.io v0.22.4 golang.org/x/mod v0.3.0 // indirect - golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a - golang.org/x/tools v0.0.0-20200615222825-6aa8f57aacd9 + golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208 + golang.org/x/tools v0.0.0-20200904185747-39188db58858 ) diff --git a/go.sum b/go.sum index c8eb8168f..1a8eb9fe9 100644 --- a/go.sum +++ b/go.sum @@ -173,6 +173,7 @@ github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGr github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.opencensus.io v0.22.3 h1:8sGtKOrtQqkN1bp2AtX+misvLIlOmsEsNd+9NIcPEm8= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= @@ -184,6 +185,7 @@ go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= 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/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= @@ -206,6 +208,7 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20200202094626-16171245cfb2/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-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -216,6 +219,8 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a h1:WXEvlFVvvGxCJLG6REjsT03iWnKLEWinaScsxF2Vm2o= golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208 h1:qwRHBd0NqMbJxfbotnDhm2ByMI1Shq4Y6oRJo21SGJA= +golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -236,12 +241,16 @@ golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3 golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200615222825-6aa8f57aacd9 h1:cwgUY+1ja2qxWb2dyaCoixaA66WGWmrijSlxaM+JM/g= golang.org/x/tools v0.0.0-20200615222825-6aa8f57aacd9/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200904185747-39188db58858 h1:xLt+iB5ksWcZVxqc+g9K41ZHy+6MKWfXCDsjSThnsPA= +golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7 h1:9zdDQZ7Thm29KFXgAX/+yaf3eVbP7djjWp/dXAppNCc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898 h1:/atklqdjdhuosWIl6AIbOeHJjicWYPqR9bpxqxYG2pA= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= 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= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=