// 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. //go:build ignore // +build ignore package main import ( "fmt" "log" "net/http" "strings" "text/template" "entgo.io/ent/entc" "entgo.io/ent/entc/gen" "entgo.io/ent/schema" "entgo.io/ent/schema/field" ) func main() { ex, err := NewExtension("json") if err != nil { log.Fatalf("creating extension: %v", err) } // A usage for custom options to configure the code generator to use // an extension and inject external dependencies in the generated API. opts := []entc.Option{ entc.Extensions(ex), entc.Dependency( entc.DependencyType(&http.Client{}), ), entc.Dependency( entc.DependencyName("Writer"), entc.DependencyTypeInfo(&field.TypeInfo{ Ident: "io.Writer", PkgPath: "io", }), ), } err = entc.Generate("./schema", &gen.Config{ Header: ` // 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 ent, DO NOT EDIT. `, Templates: []*gen.Template{ // Custom templates can be provided by entc.Extension (see below), // or by setting templates on the gen.Config object. // // gen.MustParse(gen.NewTemplate("static"). // Funcs(template.FuncMap{"title": strings.ToTitle}). // ParseFiles("template/static.tmpl")), // }, Hooks: []gen.Hook{ // Hooks can be provided by entc.Extension (see below), // or by setting hooks on the gen.Config object. // // CustomHook1("config 1"), // CustomHook2("config 2"), // }, }, opts...) if err != nil { log.Fatalf("running ent codegen: %v", err) } } // Extension is an example implementation of entc.Extension. type Extension struct { entc.DefaultExtension tag string templates []*gen.Template } // NewExtension creates a new entc.Extension. func NewExtension(tag string) (*Extension, error) { ex := &Extension{tag: tag} t, err := gen.NewTemplate("static"). Funcs(template.FuncMap{"title": strings.ToTitle}). ParseFiles("template/static.tmpl") if err != nil { return nil, err } ex.templates = append(ex.templates, t) t, err = gen.NewTemplate("debug"). Funcs(template.FuncMap{"byName": byName}). ParseFiles("template/debug.tmpl") if err != nil { return nil, err } ex.templates = append(ex.templates, t) return ex, nil } // Templates of the extension. func (e *Extension) Templates() []*gen.Template { return e.templates } // Hooks of the extension. func (e *Extension) Hooks() []gen.Hook { return []gen.Hook{ TagFields(e.tag), } } // Annotations of the extension. func (e *Extension) Annotations() []entc.Annotation { return []entc.Annotation{ Annotation{StructTag: "rql"}, } } // Options provides additional options for the extension. func (e *Extension) Options() []entc.Option { return []entc.Option{ entc.TemplateFiles("template/stringer.tmpl"), } } var _ entc.Extension = (*Extension)(nil) // byName returns a node in the graph by its label/name. func byName(g *gen.Graph, name string) (*gen.Type, error) { for _, n := range g.Nodes { if n.Name == name { return n, nil } } return nil, fmt.Errorf("node %q was not found in the graph", name) } // TagFields tags all fields defined in the schema with the given struct-tag. func TagFields(name string) gen.Hook { return func(next gen.Generator) gen.Generator { return gen.GenerateFunc(func(g *gen.Graph) error { for _, node := range g.Nodes { for _, field := range node.Fields { field.StructTag = fmt.Sprintf("%s:%q", name, field.Name) } } return next.Generate(g) }) } } const AnnotationName = "RQL" // Annotation defines a custom annotation // to be inject globally to all templates. type Annotation struct { StructTag string } func (Annotation) Name() string { return AnnotationName } var _ schema.Annotation = (*Annotation)(nil)