repogen/main.go

126 lines
2.7 KiB
Go
Raw Normal View History

2021-01-23 13:03:16 +00:00
package main
import (
"errors"
"flag"
"fmt"
2021-01-23 13:03:16 +00:00
"go/parser"
"go/token"
"log"
2021-01-23 13:03:16 +00:00
"os"
"path/filepath"
"github.com/sunboyy/repogen/internal/code"
"github.com/sunboyy/repogen/internal/generator"
"github.com/sunboyy/repogen/internal/spec"
)
2021-06-02 11:39:15 +00:00
const usageText = `repogen generates MongoDB repository implementation from repository interface
Find more information at: https://github.com/sunboyy/repogen
Supported options:`
// version indicates the version of repogen.
const version = "v0.3-next"
2021-01-23 13:03:16 +00:00
func main() {
flag.Usage = printUsage
2021-06-02 11:39:15 +00:00
versionPtr := flag.Bool("version", false, "print version of repogen")
pkgDirPtr := flag.String("pkg", ".", "package directory to scan for model struct and repository interface")
2021-01-23 13:03:16 +00:00
destPtr := flag.String("dest", "", "destination file")
modelPtr := flag.String("model", "", "model struct name")
repoPtr := flag.String("repo", "", "repository interface name")
flag.Parse()
if *versionPtr {
printVersion()
return
}
2021-01-23 13:03:16 +00:00
if *modelPtr == "" {
printUsage()
log.Fatal("-model flag required")
2021-01-23 13:03:16 +00:00
}
if *repoPtr == "" {
printUsage()
log.Fatal("-repo flag required")
2021-01-23 13:03:16 +00:00
}
code, err := generateFromRequest(*pkgDirPtr, *modelPtr, *repoPtr)
2021-02-12 15:19:31 +00:00
if err != nil {
panic(err)
}
2021-01-23 13:03:16 +00:00
dest := os.Stdout
if *destPtr != "" {
if err := os.MkdirAll(filepath.Dir(*destPtr), os.ModePerm); err != nil {
panic(err)
}
file, err := os.Create(*destPtr)
if err != nil {
panic(err)
}
defer file.Close()
dest = file
}
if _, err := dest.WriteString(code); err != nil {
panic(err)
}
}
func printUsage() {
2021-06-02 11:39:15 +00:00
fmt.Println(usageText)
flag.PrintDefaults()
}
func printVersion() {
2021-06-02 11:39:15 +00:00
fmt.Println(version)
}
func generateFromRequest(pkgDir, structModelName, repositoryInterfaceName string) (string, error) {
2021-01-23 13:03:16 +00:00
fset := token.NewFileSet()
dir, err := parser.ParseDir(fset, pkgDir, nil, parser.ParseComments)
2021-01-23 13:03:16 +00:00
if err != nil {
return "", err
2021-01-23 13:03:16 +00:00
}
pkg, err := code.ParsePackage(dir)
if err != nil {
return "", err
}
return generateRepository(pkg, structModelName, repositoryInterfaceName)
}
2021-01-23 13:03:16 +00:00
var (
errStructNotFound = errors.New("struct not found")
errInterfaceNotFound = errors.New("interface not found")
)
func generateRepository(pkg code.Package, structModelName, repositoryInterfaceName string) (string, error) {
structModel, ok := pkg.Structs[structModelName]
2021-01-23 13:03:16 +00:00
if !ok {
return "", errStructNotFound
2021-01-23 13:03:16 +00:00
}
intf, ok := pkg.Interfaces[repositoryInterfaceName]
2021-01-23 13:03:16 +00:00
if !ok {
return "", errInterfaceNotFound
2021-01-23 13:03:16 +00:00
}
var methodSpecs []spec.MethodSpec
for _, method := range intf.Methods {
methodSpec, err := spec.ParseInterfaceMethod(pkg.Structs, structModel, method)
2021-01-23 13:03:16 +00:00
if err != nil {
return "", err
}
methodSpecs = append(methodSpecs, methodSpec)
}
return generator.GenerateRepository(pkg.Name, structModel, intf.Name, methodSpecs)
2021-01-23 13:03:16 +00:00
}