Segregate base code generation logic to a new package ()

This commit is contained in:
sunboyy 2022-10-18 19:37:50 +07:00 committed by GitHub
parent 737c1a4044
commit ec08a5a918
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
22 changed files with 1761 additions and 937 deletions

View file

@ -1,75 +1,40 @@
package generator
import (
"bytes"
"html/template"
"github.com/sunboyy/repogen/internal/code"
"github.com/sunboyy/repogen/internal/codegen"
"github.com/sunboyy/repogen/internal/mongo"
"github.com/sunboyy/repogen/internal/spec"
"golang.org/x/tools/imports"
)
// GenerateRepository generates repository implementation from repository interface specification
func GenerateRepository(packageName string, structModel code.Struct, interfaceName string,
methodSpecs []spec.MethodSpec) (string, error) {
// GenerateRepository generates repository implementation code from repository
// interface specification.
func GenerateRepository(packageName string, structModel code.Struct,
interfaceName string, methodSpecs []spec.MethodSpec) (string, error) {
repositoryGenerator := repositoryGenerator{
PackageName: packageName,
StructModel: structModel,
InterfaceName: interfaceName,
MethodSpecs: methodSpecs,
Generator: mongo.NewGenerator(structModel, interfaceName),
}
generator := mongo.NewGenerator(structModel, interfaceName)
return repositoryGenerator.Generate()
}
codeBuilder := codegen.NewBuilder(
"repogen",
packageName,
generator.Imports(),
)
type repositoryGenerator struct {
PackageName string
StructModel code.Struct
InterfaceName string
MethodSpecs []spec.MethodSpec
Generator mongo.RepositoryGenerator
}
func (g repositoryGenerator) Generate() (string, error) {
buffer := new(bytes.Buffer)
if err := g.generateBase(buffer); err != nil {
constructorBuilder, err := generator.GenerateConstructor()
if err != nil {
return "", err
}
if err := g.Generator.GenerateConstructor(buffer); err != nil {
return "", err
}
codeBuilder.AddImplementer(constructorBuilder)
codeBuilder.AddImplementer(generator.GenerateStruct())
for _, method := range g.MethodSpecs {
if err := g.Generator.GenerateMethod(method, buffer); err != nil {
for _, method := range methodSpecs {
methodBuilder, err := generator.GenerateMethod(method)
if err != nil {
return "", err
}
codeBuilder.AddImplementer(methodBuilder)
}
formattedCode, err := imports.Process("", buffer.Bytes(), nil)
if err != nil {
return "", err
}
return string(formattedCode), nil
}
func (g repositoryGenerator) generateBase(buffer *bytes.Buffer) error {
tmpl, err := template.New("file_base").Parse(baseTemplate)
if err != nil {
return err
}
tmplData := baseTemplateData{
PackageName: g.PackageName,
}
if err := tmpl.Execute(buffer, tmplData); err != nil {
return err
}
return nil
return codeBuilder.Build()
}

View file

@ -22,7 +22,7 @@ var (
}
ageField = code.StructField{
Name: "Age",
Type: code.SimpleType("int"),
Type: code.TypeInt,
Tags: map[string][]string{"bson": {"age"}},
}
)
@ -34,7 +34,7 @@ func TestGenerateMongoRepository(t *testing.T) {
idField,
code.StructField{
Name: "Username",
Type: code.SimpleType("string"),
Type: code.TypeString,
Tags: map[string][]string{"bson": {"username"}},
},
genderField,
@ -49,7 +49,7 @@ func TestGenerateMongoRepository(t *testing.T) {
{Name: "ctx", Type: code.ExternalType{PackageAlias: "context", Name: "Context"}},
{Name: "id", Type: code.ExternalType{PackageAlias: "primitive", Name: "ObjectID"}},
},
Returns: []code.Type{code.PointerType{ContainedType: code.SimpleType("UserModel")}, code.SimpleType("error")},
Returns: []code.Type{code.PointerType{ContainedType: code.SimpleType("UserModel")}, code.TypeError},
Operation: spec.FindOperation{
Mode: spec.QueryModeOne,
Query: spec.QuerySpec{
@ -65,11 +65,11 @@ func TestGenerateMongoRepository(t *testing.T) {
Params: []code.Param{
{Name: "ctx", Type: code.ExternalType{PackageAlias: "context", Name: "Context"}},
{Name: "gender", Type: code.SimpleType("Gender")},
{Name: "age", Type: code.SimpleType("int")},
{Name: "age", Type: code.TypeInt},
},
Returns: []code.Type{
code.PointerType{ContainedType: code.SimpleType("UserModel")},
code.SimpleType("error"),
code.TypeError,
},
Operation: spec.FindOperation{
Mode: spec.QueryModeMany,
@ -86,11 +86,11 @@ func TestGenerateMongoRepository(t *testing.T) {
Name: "FindByAgeLessThanEqualOrderByAge",
Params: []code.Param{
{Name: "ctx", Type: code.ExternalType{PackageAlias: "context", Name: "Context"}},
{Name: "age", Type: code.SimpleType("int")},
{Name: "age", Type: code.TypeInt},
},
Returns: []code.Type{
code.ArrayType{ContainedType: code.PointerType{ContainedType: code.SimpleType("UserModel")}},
code.SimpleType("error"),
code.TypeError,
},
Operation: spec.FindOperation{
Mode: spec.QueryModeMany,
@ -108,11 +108,11 @@ func TestGenerateMongoRepository(t *testing.T) {
Name: "FindByAgeGreaterThanOrderByAgeAsc",
Params: []code.Param{
{Name: "ctx", Type: code.ExternalType{PackageAlias: "context", Name: "Context"}},
{Name: "age", Type: code.SimpleType("int")},
{Name: "age", Type: code.TypeInt},
},
Returns: []code.Type{
code.ArrayType{ContainedType: code.PointerType{ContainedType: code.SimpleType("UserModel")}},
code.SimpleType("error"),
code.TypeError,
},
Operation: spec.FindOperation{
Mode: spec.QueryModeMany,
@ -130,11 +130,11 @@ func TestGenerateMongoRepository(t *testing.T) {
Name: "FindByAgeGreaterThanEqualOrderByAgeDesc",
Params: []code.Param{
{Name: "ctx", Type: code.ExternalType{PackageAlias: "context", Name: "Context"}},
{Name: "age", Type: code.SimpleType("int")},
{Name: "age", Type: code.TypeInt},
},
Returns: []code.Type{
code.ArrayType{ContainedType: code.PointerType{ContainedType: code.SimpleType("UserModel")}},
code.SimpleType("error"),
code.TypeError,
},
Operation: spec.FindOperation{
Mode: spec.QueryModeMany,
@ -152,12 +152,12 @@ func TestGenerateMongoRepository(t *testing.T) {
Name: "FindByAgeBetween",
Params: []code.Param{
{Name: "ctx", Type: code.ExternalType{PackageAlias: "context", Name: "Context"}},
{Name: "fromAge", Type: code.SimpleType("int")},
{Name: "toAge", Type: code.SimpleType("int")},
{Name: "fromAge", Type: code.TypeInt},
{Name: "toAge", Type: code.TypeInt},
},
Returns: []code.Type{
code.ArrayType{ContainedType: code.PointerType{ContainedType: code.SimpleType("UserModel")}},
code.SimpleType("error"),
code.TypeError,
},
Operation: spec.FindOperation{
Mode: spec.QueryModeMany,
@ -173,11 +173,11 @@ func TestGenerateMongoRepository(t *testing.T) {
Params: []code.Param{
{Name: "ctx", Type: code.ExternalType{PackageAlias: "context", Name: "Context"}},
{Name: "gender", Type: code.SimpleType("Gender")},
{Name: "age", Type: code.SimpleType("int")},
{Name: "age", Type: code.TypeInt},
},
Returns: []code.Type{
code.ArrayType{ContainedType: code.PointerType{ContainedType: code.SimpleType("UserModel")}},
code.SimpleType("error"),
code.TypeError,
},
Operation: spec.FindOperation{
Mode: spec.QueryModeMany,

View file

@ -1,9 +0,0 @@
package generator
const baseTemplate = `// Code generated by repogen. DO NOT EDIT.
package {{.PackageName}}
`
type baseTemplateData struct {
PackageName string
}