Skip to content

Commit

Permalink
Move e2e generation logic to internal/generation (#50)
Browse files Browse the repository at this point in the history
  • Loading branch information
sunboyy authored May 17, 2024
1 parent 0c72075 commit c49ddcc
Show file tree
Hide file tree
Showing 16 changed files with 413 additions and 775 deletions.
1 change: 0 additions & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,3 @@ jobs:
with:
flags: unittests
token: ${{ secrets.CODECOV_TOKEN }}
exclude: examples
5 changes: 5 additions & 0 deletions codecov.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,8 @@ coverage:
patch:
default:
target: 80%

ignore:
- "examples"
- "internal/teststub"
- "internal/testutils"
10 changes: 10 additions & 0 deletions internal/generator/errors.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package generator

import "errors"

var (
ErrStructNotFound = errors.New("struct not found")
ErrNotNamedStruct = errors.New("not a named struct")
ErrInterfaceNotFound = errors.New("interface not found")
ErrNotInterface = errors.New("not an interface")
)
78 changes: 71 additions & 7 deletions internal/generator/generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,80 @@ package generator

import (
"go/types"
"log"

"github.com/sunboyy/repogen/internal/codegen"
"github.com/sunboyy/repogen/internal/mongo"
"github.com/sunboyy/repogen/internal/spec"
)

// GenerateRepository generates repository implementation code from repository
// interface specification.
func GenerateRepository(pkg *types.Package, namedStruct *types.Named,
interfaceName string, methodSpecs []spec.MethodSpec) (string, error) {
func GenerateRepositoryImpl(pkg *types.Package, structModelName,
repoInterfaceName string) (string, error) {

namedStruct, intf, err := deriveSourceTypes(pkg, structModelName,
repoInterfaceName)
if err != nil {
return "", err
}

methodSpecs, err := constructRepositorySpec(pkg, namedStruct, intf)
if err != nil {
return "", err
}

codeBuilder, err := constructCodeBuilder(pkg, namedStruct,
repoInterfaceName, methodSpecs)
if err != nil {
return "", err
}

return codeBuilder.Build()
}

func deriveSourceTypes(pkg *types.Package, structModelName string,
repositoryInterfaceName string) (*types.Named, *types.Interface, error) {

structModelObj := pkg.Scope().Lookup(structModelName)
if structModelObj == nil {
return nil, nil, ErrStructNotFound
}
namedStruct := structModelObj.Type().(*types.Named)
if _, ok := namedStruct.Underlying().(*types.Struct); !ok {
return nil, nil, ErrNotNamedStruct
}

intfObj := pkg.Scope().Lookup(repositoryInterfaceName)
if intfObj == nil {
return nil, nil, ErrInterfaceNotFound
}
intf, ok := intfObj.Type().Underlying().(*types.Interface)
if !ok {
return nil, nil, ErrNotInterface
}

return namedStruct, intf, nil
}

func constructRepositorySpec(pkg *types.Package, namedStruct *types.Named,
intf *types.Interface) ([]spec.MethodSpec, error) {

var methodSpecs []spec.MethodSpec
for i := 0; i < intf.NumMethods(); i++ {
method := intf.Method(i)
log.Println("Generating method:", method.Name())

methodSpec, err := spec.ParseInterfaceMethod(pkg, namedStruct, method)
if err != nil {
return nil, err
}
methodSpecs = append(methodSpecs, methodSpec)
}

return methodSpecs, nil
}

func constructCodeBuilder(pkg *types.Package, namedStruct *types.Named,
interfaceName string, methodSpecs []spec.MethodSpec) (*codegen.Builder, error) {

generator := mongo.NewGenerator(pkg, namedStruct, interfaceName)

Expand All @@ -23,7 +87,7 @@ func GenerateRepository(pkg *types.Package, namedStruct *types.Named,

constructorBuilder, err := generator.GenerateConstructor()
if err != nil {
return "", err
return nil, err
}

codeBuilder.AddImplementer(constructorBuilder)
Expand All @@ -32,10 +96,10 @@ func GenerateRepository(pkg *types.Package, namedStruct *types.Named,
for _, method := range methodSpecs {
methodBuilder, err := generator.GenerateMethod(method)
if err != nil {
return "", err
return nil, err
}
codeBuilder.AddImplementer(methodBuilder)
}

return codeBuilder.Build()
return codeBuilder, nil
}
Loading

0 comments on commit c49ddcc

Please sign in to comment.