Create & Init Project...

This commit is contained in:
2019-04-22 18:49:16 +08:00
commit fc4fa37393
25440 changed files with 4054998 additions and 0 deletions

47
app/tool/creator/BUILD Normal file
View File

@@ -0,0 +1,47 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
"go_binary",
)
go_library(
name = "go_default_library",
srcs = [
"gen.go",
"main.go",
"parser.go",
"templete.go",
"upgrade.go",
"utils.go",
],
importpath = "go-common/app/tool/creator",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//vendor/github.com/otokaze/mock/mockgen:go_default_library",
"//vendor/github.com/otokaze/mock/mockgen/model:go_default_library",
"//vendor/golang.org/x/tools/imports:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)
go_binary(
name = "creator",
embed = [":go_default_library"],
tags = ["automanaged"],
)

View File

@@ -0,0 +1,79 @@
## Creater 代码生成器
### Version 1.2.3
> 1.优化生成library单测代码逻辑
> 2.修正部分bug
### Version 1.2.2
> 1.重构生成monkey代码为独立mock文件
### Version 1.2.1
> 1.生成monkey代码排除返回为空的方法
### Version 1.2.0
> 1.增加生成monkey代码
### Version 1.1.10
> 1.修复生成测试用例格式错位问题
> 2.修复service层TestMain模板问题
### Version 1.1.9
> 1.修复 goimport 失败文件为空的问题.
> 2.修复自定义 chan 类型无法 parser 的问题.
### Version 1.1.8
> 1.gen方法兼容windows路径
> 2.测试方法追加bug修复
### Version 1.1.7
> 1.增加自动生成Reset方法
> 2.create everything...
### Version 1.1.6
> 1.支持 service 层 ut 生成.
> 2.生成的 mock 代码迁移至 mock 文件夹.
> 3.摘除 gock 相关代码.
### Version 1.1.5
> 1.摘除 genmock 代码 这波优化很清真 音風真的很严格.
> 2.魔改 genmock 工具 fork 为 github.com/otokaze/mock/gomock.
### Version 1.1.4
> 1.修改模板context.TODO()为context.Background()
> 2.优化*ast.FuncType的处理逻辑
> 3.修改tpTestFunc模板增加根convey方便用例扩展
### Version 1.1.3
> 1.新增生成mock代码方法
> 2.修改TestMain模板中发布版本号为"docker-1"
> 3.修改genInterface中多包生成对应Interface问题
> 4.修复genMock.go中pkgName冲突问题
### Version 1.1.2
> 1.新增解析Dao层结构体方法
> 2.新增动态增加httpMock方法
> 3.修复Goimport方法
### Version 1.1.1
> 1.优化convey.So
### Version 1.1.0
> 1.增加生成interface功能
> 2.改进类型解析功能
> 3.改进生成imports功能
> 4.修改Dao层测试模板至更加规范化
### Version 1.0.2
> 1.删除 TestMain 无用 flag.
### Version 1.0.1
> 1.添加 context.Context 类型支持.
### Version 1.0.0
> 1.无差别传参. 支持同时传入目录和文件, 生成自如!
> 2.--func 指定 func 生成测试用例. (当前存在 *_test.go 会以 append 方式追加)
> 3.--m 支持选择工作模式. (目前支持的有 test 测试用例...等)
> 4.支持生成 dao_test.go 测试入口文件, 初始化 Dao 一把梭
### Version 0.0.1
> 1.初始化项目.

View File

@@ -0,0 +1,11 @@
# Owner
chenjianrong
# Author
chenjianrong
zhaobingqing
fengshanshan
hedan
# Reviewer
chenjianrong

16
app/tool/creator/OWNERS Normal file
View File

@@ -0,0 +1,16 @@
# See the OWNERS docs at https://go.k8s.io/owners
approvers:
- chenjianrong
- fengshanshan
- hedan
- zhaobingqing
labels:
- tool
options:
no_parent_owners: true
reviewers:
- chenjianrong
- fengshanshan
- hedan
- zhaobingqing

433
app/tool/creator/gen.go Normal file
View File

@@ -0,0 +1,433 @@
package main
import (
"bytes"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"strings"
"github.com/otokaze/mock/mockgen"
"github.com/otokaze/mock/mockgen/model"
)
func genTest(parses []*parse) (err error) {
for _, p := range parses {
switch {
case strings.HasSuffix(p.Path, "_mock.go") ||
strings.HasSuffix(p.Path, ".intf.go"):
continue
case strings.HasSuffix(p.Path, "dao.go") ||
strings.HasSuffix(p.Path, "service.go"):
err = p.genTestMain()
default:
err = p.genUTTest()
}
if err != nil {
break
}
}
return
}
func (p *parse) genUTTest() (err error) {
var (
buffer bytes.Buffer
impts = strings.Join([]string{
`"context"`,
`"testing"`,
`"github.com/smartystreets/goconvey/convey"`,
}, "\n\t")
content []byte
)
filename := strings.Replace(p.Path, ".go", "_test.go", -1)
if _, err = os.Stat(filename); (_func == "" && err == nil) ||
(err != nil && os.IsExist(err)) {
err = nil
return
}
for _, impt := range p.Imports {
impts += "\n\t" + impt
}
if _func == "" {
buffer.WriteString(fmt.Sprintf(tpPackage, p.Package))
buffer.WriteString(fmt.Sprintf(tpImport, impts))
}
for _, parseFunc := range p.Funcs {
if _func != "" && _func != parseFunc.Name {
continue
}
var (
methodK string
tpVars string
vars []string
val []string
notice = "Then "
reset string
)
if parseFunc.Method != nil {
switch {
case strings.Contains(p.Path, "/library"):
methodK = ""
case strings.Contains(p.Path, "/service"):
methodK = "s."
case strings.Contains(p.Path, "/dao"):
methodK = "d."
}
// if IsService(p.Package) {
// methodK = "s."
// } else {
// methodK = "d."
// }
}
tpTestFuncs := fmt.Sprintf(tpTestFunc, strings.Title(p.Package), parseFunc.Name, parseFunc.Name, "%s", "%s", "%s")
tpTestFuncBeCall := methodK + parseFunc.Name + "(%s)\n\t\t\tconvCtx.Convey(\"%s\", func(convCtx convey.C) {"
if parseFunc.Result == nil {
tpTestFuncBeCall = fmt.Sprintf(tpTestFuncBeCall, "%s", "No return values")
tpTestFuncs = fmt.Sprintf(tpTestFuncs, "%s", tpTestFuncBeCall, "%s")
}
for k, res := range parseFunc.Result {
if res.K == "" {
res.K = fmt.Sprintf("p%d", k+1)
}
var so string
if res.V == "error" {
res.K = "err"
so = fmt.Sprintf("\tconvCtx.So(%s, convey.ShouldBeNil)", res.K)
notice += "err should be nil."
} else {
so = fmt.Sprintf("\tconvCtx.So(%s, convey.ShouldNotBeNil)", res.K)
val = append(val, res.K)
}
if len(parseFunc.Result) <= k+1 {
if len(val) != 0 {
notice += strings.Join(val, ",") + " should not be nil."
}
tpTestFuncBeCall = fmt.Sprintf(tpTestFuncBeCall, "%s", notice)
res.K += " := " + tpTestFuncBeCall
} else {
res.K += ", %s"
}
tpTestFuncs = fmt.Sprintf(tpTestFuncs, "%s", res.K+"\n\t\t\t%s", "%s")
tpTestFuncs = fmt.Sprintf(tpTestFuncs, "%s", "%s", so, "%s")
}
if parseFunc.Params == nil {
tpTestFuncs = fmt.Sprintf(tpTestFuncs, "%s", "", "%s")
}
for k, pType := range parseFunc.Params {
if pType.K == "" {
pType.K = fmt.Sprintf("a%d", k+1)
}
var (
init string
params = pType.K
)
switch {
case strings.HasPrefix(pType.V, "context"):
init = params + " = context.Background()"
case strings.HasPrefix(pType.V, "[]byte"):
init = params + " = " + pType.V + "(\"\")"
case strings.HasPrefix(pType.V, "[]"):
init = params + " = " + pType.V + "{}"
case strings.HasPrefix(pType.V, "int") ||
strings.HasPrefix(pType.V, "uint") ||
strings.HasPrefix(pType.V, "float") ||
strings.HasPrefix(pType.V, "double"):
init = params + " = " + pType.V + "(0)"
case strings.HasPrefix(pType.V, "string"):
init = params + " = \"\""
case strings.Contains(pType.V, "*xsql.Tx"):
// init = params + ",_ = d.BeginTran(c)"
init = params + ",_ = " + methodK + "BeginTran(c)"
reset += "\n\t" + params + ".Commit()"
case strings.HasPrefix(pType.V, "*"):
init = params + " = " + strings.Replace(pType.V, "*", "&", -1) + "{}"
case strings.Contains(pType.V, "chan"):
init = params + " = " + pType.V
case pType.V == "time.Time":
init = params + " = time.Now()"
case strings.Contains(pType.V, "chan"):
init = params + " = " + pType.V
default:
init = params + " " + pType.V
}
vars = append(vars, "\t\t"+init)
if len(parseFunc.Params) > k+1 {
params += ", %s"
}
tpTestFuncs = fmt.Sprintf(tpTestFuncs, "%s", params, "%s")
}
if len(vars) > 0 {
tpVars = fmt.Sprintf(tpVar, strings.Join(vars, "\n\t"))
}
tpTestFuncs = fmt.Sprintf(tpTestFuncs, tpVars, "%s")
if reset != "" {
tpTestResets := fmt.Sprintf(tpTestReset, reset)
tpTestFuncs = fmt.Sprintf(tpTestFuncs, tpTestResets)
} else {
tpTestFuncs = fmt.Sprintf(tpTestFuncs, "")
}
buffer.WriteString(tpTestFuncs)
}
var (
file *os.File
flag = os.O_RDWR | os.O_CREATE | os.O_APPEND
)
if file, err = os.OpenFile(filename, flag, 0644); err != nil {
return
}
if _func == "" {
content, _ = GoImport(filename, buffer.Bytes())
} else {
content = buffer.Bytes()
}
if _, err = file.Write(content); err != nil {
return
}
if err = file.Close(); err != nil {
return
}
return
}
func (p *parse) genTestMain() (err error) {
var (
buffer bytes.Buffer
left, right int
vars, mainFunc, fileAbs string
)
if fileAbs, err = filepath.Abs(p.Path); err != nil {
return
}
var pathSplit []string
if pathSplit = strings.Split(fileAbs, "/"); len(pathSplit) == 1 {
pathSplit = strings.Split(fileAbs, "\\")
}
for index, value := range pathSplit {
if value == "go-common" {
left = index
}
if value == "main" ||
value == "ep" ||
value == "openplatform" ||
value == "live" ||
value == "video" ||
value == "tool" ||
value == "bbq" ||
value == "library" {
right = index
break
}
}
var (
tomlPath string
filePath = filepath.Dir(fileAbs)
cmdFiles []os.FileInfo
cmdPath = strings.Join(pathSplit[:right+2], "/") + "/cmd"
)
if cmdFiles, err = ioutil.ReadDir(cmdPath); err != nil {
return
}
for _, f := range cmdFiles {
if !strings.HasSuffix(f.Name(), ".toml") {
continue
}
if tomlPath, err = filepath.Rel(filePath, cmdPath); err != nil {
return
}
if tomlPath != "" {
tomlPath = tomlPath + "/" + f.Name()
break
}
}
var (
filename = strings.Replace(p.Path, ".go", "_test.go", -1)
flag = pathSplit[right+2 : right+3][0]
conf = strings.Join(pathSplit[left:right+2], "/") + "/conf"
impts = strings.Join([]string{`"os"`, `"flag"`, `"testing"`, "\"" + conf + "\""}, "\n\t")
)
if IsService(flag) {
vars = strings.Join([]string{"s *Service"}, "\n\t")
mainFunc = tpTestServiceMain
} else {
vars = strings.Join([]string{"d *Dao"}, "\n\t")
mainFunc = tpTestDaoMain
}
if _, err := os.Stat(filename); os.IsNotExist(err) {
buffer.WriteString(fmt.Sprintf(tpPackage, p.Package))
buffer.WriteString(fmt.Sprintf(tpImport, impts))
buffer.WriteString(fmt.Sprintf(tpVar, vars))
buffer.WriteString(fmt.Sprintf(mainFunc, tomlPath))
ioutil.WriteFile(filename, buffer.Bytes(), 0644)
}
return
}
func genInterface(parses []*parse) (err error) {
var (
parse *parse
pkg = make(map[string]string)
)
for _, parse = range parses {
if strings.Contains(parse.Path, ".intf.go") {
continue
}
dirPath := filepath.Dir(parse.Path)
for _, parseFunc := range parse.Funcs {
if (parseFunc.Method == nil) ||
!(parseFunc.Name[0] >= 'A' && parseFunc.Name[0] <= 'Z') {
continue
}
var (
params string
results string
)
for k, param := range parseFunc.Params {
params += param.K + " " + param.P + param.V
if len(parseFunc.Params) > k+1 {
params += ", "
}
}
for k, res := range parseFunc.Result {
results += res.K + " " + res.P + res.V
if len(parseFunc.Result) > k+1 {
results += ", "
}
}
if len(results) != 0 {
results = "(" + results + ")"
}
pkg[dirPath] += "\t" + fmt.Sprintf(tpIntfcFunc, parseFunc.Name, params, results)
}
}
for k, v := range pkg {
var buffer bytes.Buffer
pathSplit := strings.Split(k, "/")
filename := k + "/" + pathSplit[len(pathSplit)-1] + ".intf.go"
if _, exist := os.Stat(filename); os.IsExist(exist) {
continue
}
buffer.WriteString(fmt.Sprintf(tpPackage, pathSplit[len(pathSplit)-1]))
buffer.WriteString(fmt.Sprintf(tpInterface, strings.Title(pathSplit[len(pathSplit)-1]), v))
content, _ := GoImport(filename, buffer.Bytes())
err = ioutil.WriteFile(filename, content, 0644)
}
return
}
func genMock(files ...string) (err error) {
for _, file := range files {
var pkg *model.Package
if pkg, err = mockgen.ParseFile(file); err != nil {
return
}
if len(pkg.Interfaces) == 0 {
continue
}
var mockDir = pkg.SrcDir + "/mock"
if _, err = os.Stat(mockDir); os.IsNotExist(err) {
err = nil
os.Mkdir(mockDir, 0744)
}
var mockPath = mockDir + "/" + pkg.Name + "_mock.go"
if _, exist := os.Stat(mockPath); os.IsExist(exist) {
continue
}
var g = &mockgen.Generator{Filename: file}
if err = g.Generate(pkg, "mock", mockPath); err != nil {
return
}
if err = ioutil.WriteFile(mockPath, g.Output(), 0644); err != nil {
return
}
}
return
}
func genMonkey(parses []*parse) (err error) {
var (
pkg = make(map[string]string)
)
for _, parse := range parses {
if strings.Contains(parse.Path, "monkey.go") || strings.Contains(parse.Path, "/mock/") {
continue
}
var (
mockVar, mockType, srcDir, flag string
path = strings.Split(filepath.Dir(parse.Path), "/")
pack = ConvertHump(path[len(path)-1])
refer = path[len(path)-1]
)
for i := len(path) - 1; i > len(path)-4; i-- {
if path[i] == "dao" || path[i] == "service" {
srcDir = strings.Join(path[:i+1], "/")
flag = path[i]
break
}
pack = ConvertHump(path[i-1]) + pack
}
if IsService(flag) {
mockVar = "s"
mockType = "*" + refer + ".Service"
} else {
mockVar = "d"
mockType = "*" + refer + ".Dao"
}
for _, parseFunc := range parse.Funcs {
if (parseFunc.Method == nil) || (parseFunc.Result == nil) ||
!(parseFunc.Name[0] >= 'A' && parseFunc.Name[0] <= 'Z') {
continue
}
var (
funcParams, funcResults, mockKey, mockValue, funcName string
)
funcName = pack + parseFunc.Name
for k, param := range parseFunc.Params {
funcParams += "_ " + param.V
if len(parseFunc.Params) > k+1 {
funcParams += ", "
}
}
for k, res := range parseFunc.Result {
if res.K == "" {
if res.V == "error" {
res.K = "err"
} else {
res.K = fmt.Sprintf("p%d", k+1)
}
}
mockKey += res.K
mockValue += res.V
funcResults += res.K + " " + res.P + res.V
if len(parseFunc.Result) > k+1 {
mockKey += ", "
mockValue += ", "
funcResults += ", "
}
}
pkg[srcDir+"."+refer] += fmt.Sprintf(tpMonkeyFunc, funcName, funcName, mockVar, mockType, funcResults, mockVar, parseFunc.Name, mockType, funcParams, mockValue, mockKey)
}
}
for path, content := range pkg {
var (
buffer bytes.Buffer
dir = strings.Split(path, ".")
mockDir = dir[0] + "/mock"
filename = mockDir + "/monkey_" + dir[1] + ".go"
)
if _, err = os.Stat(mockDir); os.IsNotExist(err) {
err = nil
os.Mkdir(mockDir, 0744)
}
if _, err := os.Stat(filename); os.IsExist(err) {
continue
}
buffer.WriteString(fmt.Sprintf(tpPackage, "mock"))
buffer.WriteString(content)
content, _ := GoImport(filename, buffer.Bytes())
ioutil.WriteFile(filename, content, 0644)
}
return
}

61
app/tool/creator/main.go Normal file
View File

@@ -0,0 +1,61 @@
package main
import (
"flag"
"fmt"
"os"
)
var (
err error
_mode, _func string
files []string
parses []*parse
)
func main() {
flag.StringVar(&_mode, "m", "test", "Generating code by Working mode. [test|interface|mock|upgrade...]")
flag.StringVar(&_func, "func", "", "Generating code by function.")
flag.Parse()
if len(os.Args) == 1 {
println("Creater is a tool for generating code.\n\nUsage: creater [-m]")
flag.PrintDefaults()
return
}
if err = parseArgs(os.Args[1:], &files, 0); err != nil {
panic(err)
}
switch _mode {
case "monkey":
if parses, err = parseFile(files...); err != nil {
panic(err)
}
if err = genMonkey(parses); err != nil {
panic(err)
}
case "test":
if parses, err = parseFile(files...); err != nil {
panic(err)
}
if err = genTest(parses); err != nil {
panic(err)
}
case "interface":
if parses, err = parseFile(files...); err != nil {
panic(err)
}
if err = genInterface(parses); err != nil {
panic(err)
}
case "mock":
if err = genMock(files...); err != nil {
panic(err)
}
case "upgrade":
if err = upBladeMaster(files); err != nil {
panic(err)
}
default:
}
fmt.Println(moha)
}

175
app/tool/creator/parser.go Normal file
View File

@@ -0,0 +1,175 @@
package main
import (
"fmt"
"go/ast"
"go/parser"
"go/token"
"io/ioutil"
"os"
"strings"
)
type param struct{ K, V, P string }
type parse struct {
Path string
Package string
Imports []string
Funcs []*struct {
Name string
Method, Params, Result []*param
}
}
func parseArgs(args []string, res *[]string, index int) (err error) {
if len(args) <= index {
return
}
if strings.HasPrefix(args[index], "-") {
index += 2
parseArgs(args, res, index)
return
}
var f os.FileInfo
if f, err = os.Stat(args[index]); err != nil {
return
}
if f.IsDir() {
if !strings.HasSuffix(args[index], "/") {
args[index] += "/"
}
var fs []os.FileInfo
if fs, err = ioutil.ReadDir(args[index]); err != nil {
return
}
for _, f = range fs {
args = append(args, args[index]+f.Name())
}
} else {
if strings.HasSuffix(args[index], ".go") &&
!strings.HasSuffix(args[index], "_test.go") {
*res = append(*res, args[index])
}
}
index++
return parseArgs(args, res, index)
}
func parseFile(files ...string) (parses []*parse, err error) {
for _, file := range files {
var (
astFile *ast.File
fSet = token.NewFileSet()
parse = &parse{}
)
if astFile, err = parser.ParseFile(fSet, file, nil, 0); err != nil {
return
}
if astFile.Name != nil {
parse.Path = file
parse.Package = astFile.Name.Name
}
for _, decl := range astFile.Decls {
switch decl.(type) {
case *ast.GenDecl:
for _, spec := range decl.(*ast.GenDecl).Specs {
switch spec.(type) {
case *ast.ImportSpec:
parse.Imports = append(parse.Imports, spec.(*ast.ImportSpec).Path.Value)
}
}
case *ast.FuncDecl:
var (
dec = decl.(*ast.FuncDecl)
parseFunc = &struct {
Name string
Method, Params, Result []*param
}{Name: dec.Name.Name}
)
if dec.Recv != nil {
parseFunc.Method = parserParams(dec.Recv.List)
}
if dec.Type.Params != nil {
parseFunc.Params = parserParams(dec.Type.Params.List)
}
if dec.Type.Results != nil {
parseFunc.Result = parserParams(dec.Type.Results.List)
}
parse.Funcs = append(parse.Funcs, parseFunc)
}
}
parses = append(parses, parse)
}
return
}
func parserParams(fields []*ast.Field) (params []*param) {
for _, field := range fields {
p := &param{}
//TODO:调用parseType解析类型
p.V = parseType(field.Type)
if field.Names == nil {
params = append(params, p)
}
for _, name := range field.Names {
sp := &param{}
sp.K = name.Name
if sp.K == "t" {
sp.K = "no"
}
sp.V = p.V
sp.P = p.P
params = append(params, sp)
}
}
return
}
func parseType(expr ast.Expr) string {
switch expr.(type) {
case *ast.Ident:
return expr.(*ast.Ident).Name
case *ast.StarExpr:
return "*" + parseType(expr.(*ast.StarExpr).X)
case *ast.ArrayType:
return "[" + parseType(expr.(*ast.ArrayType).Len) + "]" + parseType(expr.(*ast.ArrayType).Elt)
case *ast.SelectorExpr:
return parseType(expr.(*ast.SelectorExpr).X) + "." + expr.(*ast.SelectorExpr).Sel.Name
case *ast.MapType:
return "map[" + parseType(expr.(*ast.MapType).Key) + "]" + parseType(expr.(*ast.MapType).Value)
case *ast.StructType:
return "struct{}"
case *ast.InterfaceType:
return "interface{}"
case *ast.FuncType:
var (
pTemp string
rTemp string
)
pTemp = parseFuncType(pTemp, expr.(*ast.FuncType).Params)
if expr.(*ast.FuncType).Results != nil {
rTemp = parseFuncType(rTemp, expr.(*ast.FuncType).Results)
return fmt.Sprintf("func(%s) (%s)", pTemp, rTemp)
}
return fmt.Sprintf("func(%s)", pTemp)
case *ast.ChanType:
return fmt.Sprintf("make(chan %s)", parseType(expr.(*ast.ChanType).Value))
case *ast.Ellipsis:
return parseType(expr.(*ast.Ellipsis).Elt)
}
return ""
}
func parseFuncType(temp string, data *ast.FieldList) string {
var params = parserParams(data.List)
for i, param := range params {
if i == 0 {
temp = param.K + " " + param.V
continue
}
t := param.K + " " + param.V
temp = fmt.Sprintf("%s, %s", temp, t)
}
return temp
}

View File

@@ -0,0 +1,67 @@
package main
var (
tpPackage = "package %s\n\n"
tpImport = "import (\n\t%s\n)\n\n"
tpVar = "var (\n\t%s\n\t\t)\n"
tpInterface = "type %sInterface interface {\n%s}\n"
tpIntfcFunc = "%s(%s) %s\n"
tpMonkeyFunc = "// Mock%s .\nfunc Mock%s(%s %s,%s) (guard *monkey.PatchGuard) {\n\treturn monkey.PatchInstanceMethod(reflect.TypeOf(%s), \"%s\", func(_ %s, %s) (%s) {\n\t\treturn %s\n\t})\n}\n\n"
tpTestReset = "\n\t\tconvCtx.Reset(func() {%s\n\t\t})"
tpTestFunc = "func Test%s%s(t *testing.T){\n\tconvey.Convey(\"%s\", t, func(convCtx convey.C){\n\t\t%s\tconvCtx.Convey(\"When everything goes positive\", func(convCtx convey.C){\n\t\t\t%s\n\t\t\t})\n\t\t})%s\n\t})\n}\n\n"
tpTestDaoMain = `func TestMain(m *testing.M) {
if os.Getenv("DEPLOY_ENV") != "" {
flag.Set("app_id", "")
flag.Set("conf_token", "")
flag.Set("tree_id", "")
flag.Set("conf_version", "docker-1")
flag.Set("deploy_env", "uat")
flag.Set("conf_host", "config.bilibili.co")
flag.Set("conf_path", "/tmp")
flag.Set("region", "sh")
flag.Set("zone", "sh001")
}else{
flag.Set("conf", "%s")
}
flag.Parse()
if err := conf.Init(); err != nil {
panic(err)
}
d = New(conf.Conf)
os.Exit(m.Run())
}
`
tpTestServiceMain = `func TestMain(m *testing.M){
flag.Set("conf", "%s")
flag.Parse()
if err := conf.Init(); err != nil {
panic(err)
}
s = New(conf.Conf)
os.Exit(m.Run())
}
`
moha = `Generation success!
$$$$$$$$$$$$$$$ $$$$$$$$$$$$$$$%.
&$ &$ =$ $
$ $$$$$$= @&
B=$$ $$$$$$ $$&=
$$$$ +1s $$&-$$ +1s $$$
$$$$ $- $ $$$
$ $ $ .B
$ @ $ .=
$ $ $ %
$ =$ =$ @&
#$$$$$$$$$% -@$$$$$$$$B
莫生 莫生
气 气
代码辣鸡非我意,
自己动手分田地;
你若气死谁如意?
谈笑风生活长命.
// Release 1.1.3. Powered by 主站质保团队`
)

View File

@@ -0,0 +1,35 @@
package main
import (
"io/ioutil"
"regexp"
)
var (
_BmPattern = `(\w+)\s*(:?=)\s*bm\.Default\(\)((?:\n.*?)+)\s*\w+\.Serve\(.*?\,\s*c\..*?\);\s*(\w+)\s*!=\s*nil\s*{(\n*)(.*)\.Error\(.*\,\s*\w+\)`
_BmReplace = `${1} ${2} bm.DefaultServer(c.BM)${3} ${1}.Start(); ${4} != nil {${5}${6}.Error("bm.DefaultServer error(%v)", ${4})`
// _BmConfPattern = `type\sConfig\sstruct\s*{((?:.*?\n)+?)(?:(?:\s*BM\s+\*\w+\n((?:.*?\n)+?)^})|(?:(.*?)^}))`
// _BmConfReplace = `type Config struct {\{1}\tBM *bm.ServerConfig\n\{2}}`
// _confPath = "/../conf/conf.go"
)
func upBladeMaster(files []string) (err error) {
for _, file := range files {
var bs []byte
if bs, err = ioutil.ReadFile(file); err != nil {
return
}
var reg *regexp.Regexp
if reg, err = regexp.Compile(_BmPattern); err != nil {
return
}
if !reg.Match(bs) {
continue
}
bs = reg.ReplaceAll(bs, []byte(_BmReplace))
if err = ioutil.WriteFile(file, bs, 0644); err != nil {
return
}
}
return
}

34
app/tool/creator/utils.go Normal file
View File

@@ -0,0 +1,34 @@
package main
import (
"fmt"
"strings"
"golang.org/x/tools/imports"
)
// GoImport Use golang.org/x/tools/imports auto import pkg
func GoImport(file string, bytes []byte) (res []byte, err error) {
options := &imports.Options{
TabWidth: 8,
TabIndent: true,
Comments: true,
Fragment: true,
}
if res, err = imports.Process(file, bytes, options); err != nil {
fmt.Printf("GoImport(%s) error(%v)", file, err)
res = bytes
return
}
return
}
// IsService checkout the file belongs to service or not
func IsService(pName string) bool {
return pName == "service"
}
//ConvertHump convert words to hump style
func ConvertHump(words string) string {
return strings.ToUpper(words[0:1]) + words[1:]
}