From 84315d928d8b3b9218cc88bdf8c0713d13298c1d Mon Sep 17 00:00:00 2001
From: longfangsong <longfangsong@icloud.com>
Date: Thu, 23 Jul 2020 17:00:38 +0800
Subject: [PATCH] Add cli. Close #10

Signed-off-by: longfangsong <longfangsong@icloud.com>
---
 .gitignore               |   1 +
 generator/generator.go   |   7 ++
 generator/goGenerator.go | 147 +++++++++++++++++++++++++++++++++
 go.mod                   |   1 +
 go.sum                   |  12 +++
 main.go                  | 174 +++++++--------------------------------
 6 files changed, 200 insertions(+), 142 deletions(-)
 create mode 100644 generator/generator.go
 create mode 100644 generator/goGenerator.go

diff --git a/.gitignore b/.gitignore
index d332857..3ef6d65 100644
--- a/.gitignore
+++ b/.gitignore
@@ -97,3 +97,4 @@ Temporary Items
 .history/
 .idea
 template/**/*.qtpl.go
+autoAPI
diff --git a/generator/generator.go b/generator/generator.go
new file mode 100644
index 0000000..92735a5
--- /dev/null
+++ b/generator/generator.go
@@ -0,0 +1,7 @@
+package generator
+
+import "autoAPI/table"
+
+type Generator interface {
+	Generate(table table.Table, dirPath string) error
+}
diff --git a/generator/goGenerator.go b/generator/goGenerator.go
new file mode 100644
index 0000000..e4bb273
--- /dev/null
+++ b/generator/goGenerator.go
@@ -0,0 +1,147 @@
+package generator
+
+import (
+	"autoAPI/table"
+	"autoAPI/template/general"
+	"autoAPI/template/go/dockerfile"
+	"autoAPI/template/go/goMod"
+	"autoAPI/template/go/handler"
+	"autoAPI/template/go/infrastructure"
+	"autoAPI/template/go/mainTemplate"
+	"autoAPI/template/go/model"
+	"os"
+	"path/filepath"
+)
+
+type GoGenerator struct{}
+
+func renderDockerfile(table table.Table, dirPath string) error {
+	dockerFileContent := dockerfile.Dockerfile(table)
+	dockerfileFile, err := os.Create(filepath.Join(dirPath, "Dockerfile"))
+	if err != nil {
+		return err
+	}
+	defer dockerfileFile.Close()
+	_, err = dockerfileFile.WriteString(dockerFileContent)
+	return err
+}
+
+func renderGoMod(table table.Table, dirPath string) error {
+	modFileContent := goMod.GoMod(table)
+	modFile, err := os.Create(filepath.Join(dirPath, "go.mod"))
+	if err != nil {
+		return err
+	}
+	defer modFile.Close()
+	_, err = modFile.WriteString(modFileContent)
+	return err
+}
+
+func renderMain(table table.Table, dirPath string) error {
+	mainFileContent := mainTemplate.MainTemplate(table)
+	mainFile, err := os.Create(filepath.Join(dirPath, "main.go"))
+	if err != nil {
+		return err
+	}
+	defer mainFile.Close()
+	_, err = mainFile.WriteString(mainFileContent)
+	return err
+}
+
+func renderHandler(table table.Table, dirPath string) error {
+	handlerDir := filepath.Join(dirPath, "handler")
+	err := os.Mkdir(handlerDir, 0755)
+	if err != nil {
+		return err
+	}
+	handlerFileContent := handler.Handler(table)
+	handlerFile, err := os.Create(filepath.Join(handlerDir, "handler.go"))
+	if err != nil {
+		return err
+	}
+	defer handlerFile.Close()
+	_, err = handlerFile.WriteString(handlerFileContent)
+	return err
+}
+
+func renderModel(table table.Table, dirPath string) error {
+	modelDir := filepath.Join(dirPath, "model")
+	err := os.Mkdir(modelDir, 0755)
+	if err != nil {
+		return err
+	}
+	modelFileContent := model.Model(table)
+	modelFile, err := os.Create(filepath.Join(modelDir, "model.go"))
+	if err != nil {
+		return err
+	}
+	defer modelFile.Close()
+	_, err = modelFile.WriteString(modelFileContent)
+	return err
+}
+
+func renderDB(dirPath string) error {
+	infrastructureDir := filepath.Join(dirPath, "infrastructure")
+	err := os.Mkdir(infrastructureDir, 0755)
+	if err != nil {
+		return err
+	}
+	dbFileContent := infrastructure.DB()
+	dbFile, err := os.Create(filepath.Join(infrastructureDir, "db.go"))
+	if err != nil {
+		return err
+	}
+	defer dbFile.Close()
+	_, err = dbFile.WriteString(dbFileContent)
+	return err
+}
+
+func renderGitHubActions(table table.Table, dirPath string) error {
+	githubActionDir := filepath.Join(dirPath, ".github")
+	if err := os.Mkdir(githubActionDir, 0755); err != nil {
+		return err
+	}
+	githubActionDir = filepath.Join(githubActionDir, "workflow")
+	if err := os.Mkdir(githubActionDir, 0755); err != nil {
+		return err
+	}
+	githubActionFileContent := general.GitHubActionDocker(table)
+	dbFile, err := os.Create(filepath.Join(githubActionDir, "dockerimage.yml"))
+	if err != nil {
+		return err
+	}
+	defer dbFile.Close()
+	_, err = dbFile.WriteString(githubActionFileContent)
+	return err
+
+}
+
+func (generator GoGenerator) Generate(table table.Table, dirPath string) error {
+	err := os.RemoveAll(dirPath)
+	if err != nil {
+		return err
+	}
+	if err = os.Mkdir(dirPath, 0755); err != nil {
+		return err
+	}
+	if err = renderDB(dirPath); err != nil {
+		return err
+	}
+	if err = renderModel(table, dirPath); err != nil {
+		return err
+	}
+	if err = renderHandler(table, dirPath); err != nil {
+		return err
+	}
+	if err = renderMain(table, dirPath); err != nil {
+		return err
+	}
+	if err = renderGitHubActions(table, dirPath); err != nil {
+		return err
+	}
+	if err = renderGoMod(table, dirPath); err != nil {
+		return err
+	}
+	err = renderDockerfile(table, dirPath)
+	return err
+}
diff --git a/go.mod b/go.mod
index 8d80474..823f88d 100644
--- a/go.mod
+++ b/go.mod
@@ -4,6 +4,7 @@ go 1.14
 
 require (
 	github.com/iancoleman/strcase v0.0.0-20191112232945-16388991a334
+	github.com/urfave/cli/v2 v2.2.0
 	github.com/valyala/quicktemplate v1.5.1
 	gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776
 )
diff --git a/go.sum b/go.sum
index dedf395..13dc36f 100644
--- a/go.sum
+++ b/go.sum
@@ -1,7 +1,18 @@
+github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
+github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY=
+github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
 github.com/iancoleman/strcase v0.0.0-20191112232945-16388991a334 h1:VHgatEHNcBFEB7inlalqfNqw65aNkM1lGX2yt3NmbS8=
 github.com/iancoleman/strcase v0.0.0-20191112232945-16388991a334/go.mod h1:SK73tn/9oHe+/Y0h39VT4UCxmurVJkR5NA7kMEAOgSE=
 github.com/klauspost/compress v1.10.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
 github.com/klauspost/compress v1.10.5/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
+github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
+github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
+github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
+github.com/urfave/cli/v2 v2.2.0 h1:JTTnM6wKzdA0Jqodd966MVj4vWbbquZykeX1sKbe2C4=
+github.com/urfave/cli/v2 v2.2.0/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ=
 github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
 github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
 github.com/valyala/fasthttp v1.12.0/go.mod h1:229t1eWu9UXTPmoUkbpN/fctKPBY4IJoFXQnxHGXy6E=
@@ -15,5 +26,6 @@ golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7w
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 h1:tQIYjPdBoyREyB9XMu+nnTclpTYkz2zFM+lzLJFO4gQ=
 gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
diff --git a/main.go b/main.go
index 97f86b9..99445dd 100644
--- a/main.go
+++ b/main.go
@@ -4,152 +4,42 @@
 package main
 
 import (
+	"autoAPI/generator"
 	"autoAPI/table"
-	"autoAPI/template/general"
-	"autoAPI/template/go/dockerfile"
-	"autoAPI/template/go/goMod"
-	"autoAPI/template/go/handler"
-	"autoAPI/template/go/infrastructure"
-	"autoAPI/template/go/mainTemplate"
-	"autoAPI/template/go/model"
 	"autoAPI/yamlParser"
+	"github.com/urfave/cli/v2"
+	"log"
 	"os"
-	"path/filepath"
 )
 
-func GenerateAt(table table.Table, dirPath string) error {
-	err := os.RemoveAll(dirPath)
-	if err != nil {
-		return err
-	}
-	if err = os.Mkdir(dirPath, 0755); err != nil {
-		return err
-	}
-	if err = renderDB(dirPath); err != nil {
-		return err
-	}
-	if err = renderModel(table, dirPath); err != nil {
-		return err
-	}
-	if err = renderHandler(table, dirPath); err != nil {
-		return err
-	}
-	if err = renderMain(table, dirPath); err != nil {
-		return err
-	}
-	if err = renderGitHubActions(table, dirPath); err != nil {
-		return err
-	}
-	if err = renderGoMod(table, dirPath); err != nil {
-		return err
-	}
-	err = renderDockerfile(table, dirPath)
-	return err
-}
-
-func renderDockerfile(table table.Table, dirPath string) error {
-	dockerFileContent := dockerfile.Dockerfile(table)
-	dockerfileFile, err := os.Create(filepath.Join(dirPath, "Dockerfile"))
-	if err != nil {
-		return err
-	}
-	defer dockerfileFile.Close()
-	_, err = dockerfileFile.WriteString(dockerFileContent)
-	return err
-}
-
-func renderGoMod(table table.Table, dirPath string) error {
-	modFileContent := goMod.GoMod(table)
-	modFile, err := os.Create(filepath.Join(dirPath, "go.mod"))
-	if err != nil {
-		return err
-	}
-	defer modFile.Close()
-	_, err = modFile.WriteString(modFileContent)
-	return err
-}
-
-func renderMain(table table.Table, dirPath string) error {
-	mainFileContent := mainTemplate.MainTemplate(table)
-	mainFile, err := os.Create(filepath.Join(dirPath, "main.go"))
-	if err != nil {
-		return err
-	}
-	defer mainFile.Close()
-	_, err = mainFile.WriteString(mainFileContent)
-	return err
-}
-
-func renderHandler(table table.Table, dirPath string) error {
-	handlerDir := filepath.Join(dirPath, "handler")
-	err := os.Mkdir(handlerDir, 0755)
-	if err != nil {
-		return err
-	}
-	handlerFileContent := handler.Handler(table)
-	handlerFile, err := os.Create(filepath.Join(handlerDir, "handler.go"))
-	if err != nil {
-		return err
-	}
-	defer handlerFile.Close()
-	_, err = handlerFile.WriteString(handlerFileContent)
-	return err
-}
-
-func renderModel(table table.Table, dirPath string) error {
-	modelDir := filepath.Join(dirPath, "model")
-	err := os.Mkdir(modelDir, 0755)
-	if err != nil {
-		return err
-	}
-	modelFileContent := model.Model(table)
-	modelFile, err := os.Create(filepath.Join(modelDir, "model.go"))
-	if err != nil {
-		return err
-	}
-	defer modelFile.Close()
-	_, err = modelFile.WriteString(modelFileContent)
-	return err
-}
-
-func renderDB(dirPath string) error {
-	infrastructureDir := filepath.Join(dirPath, "infrastructure")
-	err := os.Mkdir(infrastructureDir, 0755)
-	if err != nil {
-		return err
-	}
-	dbFileContent := infrastructure.DB()
-	dbFile, err := os.Create(filepath.Join(infrastructureDir, "db.go"))
-	if err != nil {
-		return err
-	}
-	defer dbFile.Close()
-	_, err = dbFile.WriteString(dbFileContent)
-	return err
-}
-
-func renderGitHubActions(table table.Table, dirPath string) error {
-	githubActionDir := filepath.Join(dirPath, ".github")
-	if err := os.Mkdir(githubActionDir, 0755); err != nil {
-		return err
-	}
-	githubActionDir = filepath.Join(githubActionDir, "workflow")
-	if err := os.Mkdir(githubActionDir, 0755); err != nil {
-		return err
-	}
-	githubActionFileContent := general.GitHubActionDocker(table)
-	dbFile, err := os.Create(filepath.Join(githubActionDir, "dockerimage.yml"))
-	if err != nil {
-		return err
-	}
-	defer dbFile.Close()
-	_, err = dbFile.WriteString(githubActionFileContent)
-	return err
-
-}
-
 func main() {
-	f, _ := yamlParser.Load("./example/student.yaml")
-	m := table.FromYaml(f)
-	_ = GenerateAt(m, "/tmp/student")
+	err := (&cli.App{
+		Flags: []cli.Flag{
+			&cli.StringFlag{
+				Name:    "file",
+				Aliases: []string{"f"},
+				Usage:   "Load configuration from `FILE`",
+			},
+			&cli.StringFlag{
+				Name:    "output",
+				Aliases: []string{"o"},
+				Usage:   "Put the output code in `PATH`",
+			},
+		},
+		Name:  "autoAPI",
+		Usage: "Generate an CRUD api endpoint program automatically!",
+		Action: func(c *cli.Context) error {
+			f, err := yamlParser.Load(c.String("file"))
+			if err != nil {
+				return err
+			}
+			m := table.FromYaml(f)
+			gen := generator.GoGenerator{}
+			err = gen.Generate(m, c.String("output"))
+			return err
+		},
+	}).Run(os.Args)
+	if err != nil {
+		log.Fatal(err)
+	}
 }