mirror of
https://github.com/SamyRai/tercul-backend.git
synced 2025-12-27 02:51:34 +00:00
144 lines
3.4 KiB
Go
144 lines
3.4 KiB
Go
//go:build tools
|
|
|
|
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"go/ast"
|
|
"go/parser"
|
|
"go/token"
|
|
"io/ioutil"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
)
|
|
|
|
func main() {
|
|
sqlDir := "internal/data/sql"
|
|
domainDir := "internal/domain"
|
|
|
|
files, err := ioutil.ReadDir(sqlDir)
|
|
if err != nil {
|
|
fmt.Println("Error reading sql directory:", err)
|
|
return
|
|
}
|
|
|
|
for _, file := range files {
|
|
if strings.HasSuffix(file.Name(), "_repository.go") {
|
|
repoName := strings.TrimSuffix(file.Name(), "_repository.go")
|
|
repoInterfaceName := strings.Title(repoName) + "Repository"
|
|
domainPackageName := repoName
|
|
|
|
// Create domain directory
|
|
domainRepoDir := filepath.Join(domainDir, domainPackageName)
|
|
if err := os.MkdirAll(domainRepoDir, 0755); err != nil {
|
|
fmt.Printf("Error creating directory %s: %v\n", domainRepoDir, err)
|
|
continue
|
|
}
|
|
|
|
// Read the sql repository file
|
|
filePath := filepath.Join(sqlDir, file.Name())
|
|
src, err := ioutil.ReadFile(filePath)
|
|
if err != nil {
|
|
fmt.Printf("Error reading file %s: %v\n", filePath, err)
|
|
continue
|
|
}
|
|
|
|
// Parse the file
|
|
fset := token.NewFileSet()
|
|
node, err := parser.ParseFile(fset, "", src, parser.ParseComments)
|
|
if err != nil {
|
|
fmt.Printf("Error parsing file %s: %v\n", filePath, err)
|
|
continue
|
|
}
|
|
|
|
// Find public methods
|
|
var methods []string
|
|
ast.Inspect(node, func(n ast.Node) bool {
|
|
if fn, ok := n.(*ast.FuncDecl); ok {
|
|
if fn.Recv != nil && len(fn.Recv.List) > 0 {
|
|
if star, ok := fn.Recv.List[0].Type.(*ast.StarExpr); ok {
|
|
if ident, ok := star.X.(*ast.Ident); ok {
|
|
if strings.HasSuffix(ident.Name, "Repository") && fn.Name.IsExported() {
|
|
methods = append(methods, getFuncSignature(fn))
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return true
|
|
})
|
|
|
|
// Create the repo.go file
|
|
repoFilePath := filepath.Join(domainRepoDir, "repo.go")
|
|
repoFileContent := fmt.Sprintf(`package %s
|
|
|
|
import (
|
|
"context"
|
|
"tercul/internal/domain"
|
|
)
|
|
|
|
// %s defines CRUD methods specific to %s.
|
|
type %s interface {
|
|
domain.BaseRepository[domain.%s]
|
|
%s
|
|
}
|
|
`, domainPackageName, repoInterfaceName, strings.Title(repoName), repoInterfaceName, strings.Title(repoName), formatMethods(methods))
|
|
|
|
if err := ioutil.WriteFile(repoFilePath, []byte(repoFileContent), 0644); err != nil {
|
|
fmt.Printf("Error writing file %s: %v\n", repoFilePath, err)
|
|
} else {
|
|
fmt.Printf("Created %s\n", repoFilePath)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func getFuncSignature(fn *ast.FuncDecl) string {
|
|
params := ""
|
|
for _, p := range fn.Type.Params.List {
|
|
if len(p.Names) > 0 {
|
|
params += p.Names[0].Name + " "
|
|
}
|
|
params += getTypeString(p.Type) + ", "
|
|
}
|
|
if len(params) > 0 {
|
|
params = params[:len(params)-2]
|
|
}
|
|
|
|
results := ""
|
|
if fn.Type.Results != nil {
|
|
for _, r := range fn.Type.Results.List {
|
|
results += getTypeString(r.Type) + ", "
|
|
}
|
|
if len(results) > 0 {
|
|
results = "(" + results[:len(results)-2] + ")"
|
|
}
|
|
}
|
|
return fmt.Sprintf("\t%s(%s) %s", fn.Name.Name, params, results)
|
|
}
|
|
|
|
func getTypeString(expr ast.Expr) string {
|
|
switch t := expr.(type) {
|
|
case *ast.Ident:
|
|
return t.Name
|
|
case *ast.SelectorExpr:
|
|
return getTypeString(t.X) + "." + t.Sel.Name
|
|
case *ast.StarExpr:
|
|
return "*" + getTypeString(t.X)
|
|
case *ast.ArrayType:
|
|
return "[]" + getTypeString(t.Elt)
|
|
case *ast.InterfaceType:
|
|
return "interface{}"
|
|
default:
|
|
return ""
|
|
}
|
|
}
|
|
|
|
func formatMethods(methods []string) string {
|
|
if len(methods) == 0 {
|
|
return ""
|
|
}
|
|
return "\n" + strings.Join(methods, "\n")
|
|
}
|