mirror of
https://github.com/ent/ent.git
synced 2026-05-24 09:31:56 +03:00
Summary: Pull Request resolved: https://github.com/facebookincubator/ent/pull/72 Reviewed By: alexsn Differential Revision: D17783580 fbshipit-source-id: 597f124a28415fef66b0b16811ad2acac8df631d
136 lines
3.8 KiB
Go
136 lines
3.8 KiB
Go
// 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.
|
|
|
|
// Package entc provides an interface for interacting with
|
|
// entc (ent codegen) as a package rather than an executable.
|
|
|
|
package entc
|
|
|
|
import (
|
|
"os"
|
|
"path"
|
|
"path/filepath"
|
|
"text/template"
|
|
|
|
"github.com/facebookincubator/ent/entc/gen"
|
|
"github.com/facebookincubator/ent/entc/load"
|
|
)
|
|
|
|
// LoadGraph loads the schema package from the given schema path,
|
|
// and construct a *gen.Graph.
|
|
func LoadGraph(schemaPath string, cfg *gen.Config) (*gen.Graph, error) {
|
|
spec, err := (&load.Config{Path: schemaPath}).Load()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
cfg.Schema = spec.PkgPath
|
|
if cfg.Package == "" {
|
|
// default package-path for codegen is one package
|
|
// above the schema package (`<project>/ent/schema`).
|
|
cfg.Package = path.Dir(spec.PkgPath)
|
|
}
|
|
return gen.NewGraph(cfg, spec.Schemas...)
|
|
}
|
|
|
|
// Generate runs the codegen on the schema path. The default target
|
|
// directory for the assets, is one directory above the schema path.
|
|
// Hence, if the schema package resides in "<project>/ent/schema",
|
|
// the base directory for codegen will be "<project>/ent".
|
|
//
|
|
// If no storage driver provided by option, SQL driver will be used.
|
|
//
|
|
// entc.Generate("./ent/path", &gen.Config{
|
|
// Header: "// Custom header",
|
|
// IDType: &field.TypeInfo{Type: field.TypeInt},
|
|
// })
|
|
//
|
|
func Generate(schemaPath string, cfg *gen.Config, options ...Option) error {
|
|
if cfg.Target == "" {
|
|
abs, err := filepath.Abs(schemaPath)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
// default target-path for codegen is one dir above
|
|
// the schema.
|
|
cfg.Target = filepath.Dir(abs)
|
|
}
|
|
for _, opt := range options {
|
|
if err := opt(cfg); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
if len(cfg.Storage) == 0 {
|
|
driver, err := gen.NewStorage("sql")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
cfg.Storage = append(cfg.Storage, driver)
|
|
}
|
|
graph, err := LoadGraph(schemaPath, cfg)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return graph.Gen()
|
|
}
|
|
|
|
// Option allows for managing codegen configuration using functional options.
|
|
type Option func(*gen.Config) error
|
|
|
|
// Storage sets the list of storage-driver types to support by the codegen.
|
|
func Storage(types ...string) Option {
|
|
return func(cfg *gen.Config) error {
|
|
for _, t := range types {
|
|
storage, err := gen.NewStorage(t)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
cfg.Storage = append(cfg.Storage, storage)
|
|
}
|
|
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
|
|
})
|
|
}
|
|
|
|
// 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
|
|
})
|
|
}
|
|
|
|
// 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) (err error) {
|
|
return filepath.Walk(path, func(path string, info os.FileInfo, err error) error {
|
|
if info.IsDir() {
|
|
return nil
|
|
}
|
|
cfg.Template, err = cfg.Template.ParseFiles(path)
|
|
return err
|
|
})
|
|
})
|
|
}
|
|
|
|
// templateOption ensures the template instantiate
|
|
// once for config and execute the given Option.
|
|
func templateOption(next Option) Option {
|
|
return func(cfg *gen.Config) (err error) {
|
|
if cfg.Template == nil {
|
|
cfg.Template = template.New("external").Funcs(gen.Funcs)
|
|
}
|
|
return next(cfg)
|
|
}
|
|
}
|