2021-01-23 13:03:16 +00:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"errors"
|
|
|
|
"flag"
|
2021-03-30 12:16:46 +00:00
|
|
|
"fmt"
|
2021-01-23 13:03:16 +00:00
|
|
|
"go/parser"
|
|
|
|
"go/token"
|
2021-03-30 12:16:46 +00:00
|
|
|
"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:`
|
|
|
|
|
2021-11-27 04:54:18 +00:00
|
|
|
const version = "v0.2.1"
|
2021-03-30 12:16:46 +00:00
|
|
|
|
2021-01-23 13:03:16 +00:00
|
|
|
func main() {
|
2021-03-30 12:16:46 +00:00
|
|
|
flag.Usage = printUsage
|
|
|
|
|
2021-06-02 11:39:15 +00:00
|
|
|
versionPtr := flag.Bool("version", false, "print version of repogen")
|
2021-01-23 13:03:16 +00:00
|
|
|
sourcePtr := flag.String("src", "", "source file")
|
|
|
|
destPtr := flag.String("dest", "", "destination file")
|
|
|
|
modelPtr := flag.String("model", "", "model struct name")
|
|
|
|
repoPtr := flag.String("repo", "", "repository interface name")
|
|
|
|
|
|
|
|
flag.Parse()
|
|
|
|
|
2021-03-30 12:16:46 +00:00
|
|
|
if *versionPtr {
|
|
|
|
printVersion()
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2021-01-23 13:03:16 +00:00
|
|
|
if *sourcePtr == "" {
|
2021-03-30 12:16:46 +00:00
|
|
|
printUsage()
|
2021-11-27 04:54:18 +00:00
|
|
|
log.Fatal("-src flag required")
|
2021-01-23 13:03:16 +00:00
|
|
|
}
|
|
|
|
if *modelPtr == "" {
|
2021-03-30 12:16:46 +00:00
|
|
|
printUsage()
|
|
|
|
log.Fatal("-model flag required")
|
2021-01-23 13:03:16 +00:00
|
|
|
}
|
|
|
|
if *repoPtr == "" {
|
2021-03-30 12:16:46 +00:00
|
|
|
printUsage()
|
|
|
|
log.Fatal("-repo flag required")
|
2021-01-23 13:03:16 +00:00
|
|
|
}
|
|
|
|
|
2021-02-12 15:19:31 +00:00
|
|
|
code, err := generateFromRequest(*sourcePtr, *modelPtr, *repoPtr)
|
|
|
|
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)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-03-30 12:16:46 +00:00
|
|
|
func printUsage() {
|
2021-06-02 11:39:15 +00:00
|
|
|
fmt.Println(usageText)
|
2021-03-30 12:16:46 +00:00
|
|
|
flag.PrintDefaults()
|
|
|
|
}
|
|
|
|
|
|
|
|
func printVersion() {
|
2021-06-02 11:39:15 +00:00
|
|
|
fmt.Println(version)
|
2021-03-30 12:16:46 +00:00
|
|
|
}
|
|
|
|
|
2021-01-23 13:03:16 +00:00
|
|
|
func generateFromRequest(fileName, structModelName, repositoryInterfaceName string) (string, error) {
|
|
|
|
fset := token.NewFileSet()
|
|
|
|
f, err := parser.ParseFile(fset, fileName, nil, parser.ParseComments)
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
file := code.ExtractComponents(f)
|
|
|
|
|
|
|
|
structModel, ok := file.Structs.ByName(structModelName)
|
|
|
|
if !ok {
|
|
|
|
return "", errors.New("struct model not found")
|
|
|
|
}
|
|
|
|
|
|
|
|
intf, ok := file.Interfaces.ByName(repositoryInterfaceName)
|
|
|
|
if !ok {
|
|
|
|
return "", errors.New("interface model not found")
|
|
|
|
}
|
|
|
|
|
|
|
|
var methodSpecs []spec.MethodSpec
|
|
|
|
for _, method := range intf.Methods {
|
2021-03-03 14:01:32 +00:00
|
|
|
methodSpec, err := spec.ParseInterfaceMethod(file.Structs, structModel, method)
|
2021-01-23 13:03:16 +00:00
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
methodSpecs = append(methodSpecs, methodSpec)
|
|
|
|
}
|
|
|
|
|
|
|
|
return generator.GenerateRepository(file.PackageName, structModel, intf.Name, methodSpecs)
|
|
|
|
}
|