release: new project template
This commit is contained in:
parent
08d0662fe6
commit
1143e0624c
13
README.md
13
README.md
@ -6,4 +6,15 @@ coco 快速项目开发脚手架
|
||||
|
||||
- 新建项目
|
||||
- 代码生成
|
||||
- 自更新
|
||||
- 工具自更新
|
||||
|
||||
## 安装
|
||||
|
||||
```shell
|
||||
go install gitter.top/coco/bootstrap/coco/...@latest
|
||||
go install gitter.top/coco/protoc-gen-coco@latest
|
||||
go install github.com/golang/protobuf/protoc-gen-go@latest
|
||||
go install github.com/bufbuild/buf/cmd/...@latest
|
||||
go install github.com/google/wire/cmd/wire@latest
|
||||
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
|
||||
```
|
||||
|
39
coco/main.go
Normal file
39
coco/main.go
Normal file
@ -0,0 +1,39 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"gitter.top/coco/bootstrap"
|
||||
)
|
||||
|
||||
var (
|
||||
rootCmd = &cobra.Command{
|
||||
Use: "coco",
|
||||
Short: "golang project toolkit",
|
||||
}
|
||||
)
|
||||
|
||||
func init() {
|
||||
logrus.SetFormatter(&logrus.TextFormatter{
|
||||
ForceColors: true,
|
||||
EnvironmentOverrideColors: true,
|
||||
DisableTimestamp: true,
|
||||
DisableSorting: true,
|
||||
DisableLevelTruncation: false,
|
||||
PadLevelText: false,
|
||||
QuoteEmptyFields: false,
|
||||
})
|
||||
rootCmd.AddCommand(bootstrap.Update())
|
||||
rootCmd.AddCommand(bootstrap.CreateProject())
|
||||
rootCmd.AddCommand(bootstrap.AddAPICommand())
|
||||
rootCmd.AddCommand(bootstrap.AddServiceCommand())
|
||||
rootCmd.AddCommand(bootstrap.GenerateProtoFile())
|
||||
rootCmd.AddCommand(bootstrap.InjectProtoFile())
|
||||
}
|
||||
|
||||
func main() {
|
||||
if err := rootCmd.Execute(); err != nil {
|
||||
logrus.Fatalln(err)
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package main
|
||||
package bootstrap
|
||||
|
||||
type Config struct {
|
||||
Version string `yaml:"version"`
|
||||
|
57
coco_generate.go
Normal file
57
coco_generate.go
Normal file
@ -0,0 +1,57 @@
|
||||
package bootstrap
|
||||
|
||||
import (
|
||||
"os"
|
||||
"os/exec"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func GenerateProtoFile() *cobra.Command {
|
||||
var protoFile string
|
||||
var onlyGout, onlyCocout bool
|
||||
cmd := &cobra.Command{
|
||||
Use: "gen",
|
||||
Short: "generate proto file",
|
||||
PreRun: func(_ *cobra.Command, _ []string) {
|
||||
stat, err := os.Stat(protoFile)
|
||||
if err != nil {
|
||||
logrus.Errorf("read proto file %s failed: %v", protoFile, err)
|
||||
return
|
||||
}
|
||||
if stat.IsDir() {
|
||||
logrus.Errorf("proto file can not be directory")
|
||||
return
|
||||
}
|
||||
},
|
||||
Run: func(_ *cobra.Command, _ []string) {
|
||||
var args = []string{protoFile}
|
||||
var goOut = "--go_out=.."
|
||||
var cocoOut = "--coco_out=.."
|
||||
if onlyGout {
|
||||
args = append(args, goOut)
|
||||
}
|
||||
if onlyCocout {
|
||||
args = append(args, cocoOut)
|
||||
}
|
||||
if !onlyCocout && !onlyGout {
|
||||
args = append(args, cocoOut, goOut)
|
||||
}
|
||||
var command = exec.Command("protoc", args...)
|
||||
output, err := command.CombinedOutput()
|
||||
logrus.Infof("exec command: %s", command.String())
|
||||
if err != nil {
|
||||
logrus.Errorf("exec command failed: %v: %v\noutput: %v", command.String(), err, string(output))
|
||||
return
|
||||
}
|
||||
logrus.Infof("generate %s success", protoFile)
|
||||
},
|
||||
}
|
||||
|
||||
cmd.Flags().StringVar(&protoFile, "path", "", "proto file path")
|
||||
cmd.Flags().BoolVar(&onlyGout, "onlyGo", false, "only generate by protoc-gen-go")
|
||||
cmd.Flags().BoolVar(&onlyCocout, "onlyCoco", false, "only generate by protoc-gen-coco")
|
||||
|
||||
return cmd
|
||||
}
|
59
coco_inject.go
Normal file
59
coco_inject.go
Normal file
@ -0,0 +1,59 @@
|
||||
package bootstrap
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
"gitter.top/common/gobuf"
|
||||
)
|
||||
|
||||
func InjectProtoFile() *cobra.Command {
|
||||
var protoFile string
|
||||
var tags []string
|
||||
var tagStyle string
|
||||
cmd := &cobra.Command{
|
||||
Use: "inject",
|
||||
Short: "inject pb.go file",
|
||||
PreRun: func(_ *cobra.Command, _ []string) {
|
||||
stat, err := os.Stat(protoFile)
|
||||
if err != nil {
|
||||
logrus.Errorf("read pb.go file %s failed: %v", protoFile, err)
|
||||
return
|
||||
}
|
||||
if stat.IsDir() {
|
||||
logrus.Errorf("proto file can not be directory")
|
||||
return
|
||||
}
|
||||
},
|
||||
Run: func(_ *cobra.Command, _ []string) {
|
||||
var getStyle = func(style string) gobuf.TagValueStyle {
|
||||
if style == "underline" {
|
||||
return gobuf.Underline
|
||||
}
|
||||
if style == "lowercase" {
|
||||
return gobuf.LowerCase
|
||||
}
|
||||
return gobuf.UpperCase
|
||||
}
|
||||
var inject = gobuf.NewInjectTag(protoFile)
|
||||
for _, tag := range tags {
|
||||
inject.WithTags(gobuf.InjectTagProps{
|
||||
TagName: tag,
|
||||
Style: getStyle(tagStyle),
|
||||
})
|
||||
}
|
||||
if err := inject.Inject(); err != nil {
|
||||
logrus.Errorf("inject %s file failed: %v", protoFile, err)
|
||||
return
|
||||
}
|
||||
logrus.Infof("inject %s success", protoFile)
|
||||
},
|
||||
}
|
||||
|
||||
cmd.Flags().StringVar(&protoFile, "path", "", "pb.go file path")
|
||||
cmd.Flags().StringVar(&tagStyle, "style", "underline", "tag value style, value underline|lowercase|uppercase")
|
||||
cmd.Flags().StringSliceVar(&tags, "tags", []string{"bson"}, "inject tag field name")
|
||||
|
||||
return cmd
|
||||
}
|
@ -1,26 +1,27 @@
|
||||
package main
|
||||
package bootstrap
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
gitea_api "gitter.top/coco/components/gitea-api"
|
||||
giteaApi "gitter.top/coco/components/gitea-api"
|
||||
"gitter.top/coco/components/runtime"
|
||||
"gitter.top/coco/components/yaml"
|
||||
)
|
||||
|
||||
func cocoUpdate() *cobra.Command {
|
||||
func Update() *cobra.Command {
|
||||
var config Config
|
||||
var configPath string
|
||||
return &cobra.Command{
|
||||
Use: "update",
|
||||
Short: "coco tool update",
|
||||
Short: "coco update",
|
||||
PreRun: func(cmd *cobra.Command, args []string) {
|
||||
configPath = runtime.ReplaceEachSlash(fmt.Sprintf("%s/.coco.yaml", runtime.GetHomeDir()))
|
||||
_ = yaml.Read(configPath, &config)
|
||||
},
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
client, err := gitea_api.NewClient("https://gitter.top")
|
||||
client, err := giteaApi.NewClient("https://gitter.top")
|
||||
if err != nil {
|
||||
logrus.Errorf("new gitea api failed: %v", err)
|
||||
return
|
||||
@ -36,12 +37,10 @@ func cocoUpdate() *cobra.Command {
|
||||
}
|
||||
|
||||
// exec update
|
||||
repo := fmt.Sprintf("gitter.top/coco/bootstrap@%s", commitID)
|
||||
if output, err := runtime.Exec("go", "build", "-o", "coco", repo); err != nil {
|
||||
logrus.Errorf("update coco failed: %v", err)
|
||||
repo := fmt.Sprintf("gitter.top/coco/bootstrap/coco/...@%s", commitID)
|
||||
if _, err := runtime.Exec("go", "install", repo); err != nil {
|
||||
logrus.Errorf("update bootstrap failed: %v", err)
|
||||
return
|
||||
} else {
|
||||
logrus.Infof("%s", output)
|
||||
}
|
||||
|
||||
config.Version = commitID
|
||||
@ -49,6 +48,8 @@ func cocoUpdate() *cobra.Command {
|
||||
logrus.Errorf("write config failed: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
logrus.Infof("update success!")
|
||||
},
|
||||
}
|
||||
}
|
||||
|
77
create_api.go
Normal file
77
create_api.go
Normal file
@ -0,0 +1,77 @@
|
||||
package bootstrap
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
"gitter.top/common/gobuf"
|
||||
)
|
||||
|
||||
func AddAPICommand() *cobra.Command {
|
||||
pbPath, _ := os.Getwd()
|
||||
var routerGroup = ""
|
||||
var routerName = ""
|
||||
cmd := &cobra.Command{
|
||||
Use: "addapi",
|
||||
Short: "add api for service",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
if routerName == "" {
|
||||
logrus.Errorf("router name --name empty")
|
||||
return
|
||||
}
|
||||
routerName = FirstUpper(routerName)
|
||||
buf, err := gobuf.NewParser(pbPath)
|
||||
if err != nil {
|
||||
logrus.Errorf("read proto file failed: %v", err)
|
||||
return
|
||||
}
|
||||
if buf.ExistRPC(routerGroup, routerName) {
|
||||
logrus.Warnf("router name exist")
|
||||
return
|
||||
}
|
||||
err = buf.AddRPC(routerGroup, routerName)
|
||||
if err != nil {
|
||||
logrus.Warnf("add router failed: %v", err)
|
||||
return
|
||||
}
|
||||
},
|
||||
}
|
||||
cmd.Flags().StringVar(&pbPath, "path", pbPath, "proto file path")
|
||||
cmd.Flags().StringVar(&routerName, "name", routerName, "api name")
|
||||
cmd.Flags().StringVar(&routerGroup, "service", routerGroup, "service name")
|
||||
return cmd
|
||||
}
|
||||
|
||||
func AddServiceCommand() *cobra.Command {
|
||||
var pbPath = ""
|
||||
var svcName = ""
|
||||
cmd := &cobra.Command{
|
||||
Use: "addgroup",
|
||||
Short: "add router group",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
if svcName == "" {
|
||||
logrus.Errorf("router group name -- name empty")
|
||||
return
|
||||
}
|
||||
|
||||
buf, err := gobuf.NewParser(pbPath)
|
||||
if err != nil {
|
||||
logrus.Errorf("read proto file failed: %v", err)
|
||||
return
|
||||
}
|
||||
if buf.ExistService(svcName) {
|
||||
logrus.Errorf("router group name exist")
|
||||
return
|
||||
}
|
||||
if err := buf.AddService(svcName); err != nil {
|
||||
logrus.Errorf("add router group failed: %+v", err)
|
||||
return
|
||||
}
|
||||
},
|
||||
}
|
||||
cmd.Flags().StringVar(&pbPath, "path", pbPath, "proto file path")
|
||||
cmd.Flags().StringVar(&svcName, "name", svcName, "router group name, such as UserModule")
|
||||
|
||||
return cmd
|
||||
}
|
45
create_project.go
Normal file
45
create_project.go
Normal file
@ -0,0 +1,45 @@
|
||||
package bootstrap
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"gitter.top/coco/bootstrap/template"
|
||||
)
|
||||
|
||||
func CreateProject() *cobra.Command {
|
||||
var name, output string
|
||||
cmd := &cobra.Command{
|
||||
Use: "new",
|
||||
Short: "create new project",
|
||||
PreRun: func(cmd *cobra.Command, args []string) {
|
||||
if name != "" {
|
||||
return
|
||||
}
|
||||
if len(args) == 1 {
|
||||
name = args[0]
|
||||
return
|
||||
}
|
||||
name = "DemoProject"
|
||||
},
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
b := &template.Builder{
|
||||
Path: output,
|
||||
Name: name,
|
||||
}
|
||||
b.Path = path.Join(output, b.Name)
|
||||
if err := b.Build(); err != nil {
|
||||
_, _ = fmt.Fprint(os.Stderr, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
cmd.Flags().StringVar(&name, "name", "", "project name")
|
||||
cmd.Flags().StringVar(&output, "path", ".", "project path")
|
||||
|
||||
return cmd
|
||||
}
|
18
go.mod
18
go.mod
@ -1,18 +1,22 @@
|
||||
module gitter.top/xuthus5/coco
|
||||
module gitter.top/coco/bootstrap
|
||||
|
||||
go 1.18
|
||||
go 1.20
|
||||
|
||||
require (
|
||||
github.com/sirupsen/logrus v1.9.0
|
||||
github.com/spf13/cobra v1.6.1
|
||||
gitter.top/coco/components v0.0.0-20230101151943-8e94d6d01339
|
||||
github.com/sirupsen/logrus v1.9.3
|
||||
github.com/spf13/cobra v1.8.0
|
||||
gitter.top/coco/components v0.0.0-20230414170908-eb14d021db12
|
||||
gitter.top/common/gobuf v0.0.0-20230929042601-dda09f2e32de
|
||||
)
|
||||
|
||||
require (
|
||||
code.gitea.io/sdk/gitea v0.15.1 // indirect
|
||||
github.com/emicklei/proto v1.13.0 // indirect
|
||||
github.com/hashicorp/go-version v1.2.1 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.0.1 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 // indirect
|
||||
gitter.top/sync/proto-contrib v0.15.0 // indirect
|
||||
golang.org/x/sys v0.16.0 // indirect
|
||||
google.golang.org/protobuf v1.32.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
23
main.go
23
main.go
@ -1,23 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var (
|
||||
rootCmd = &cobra.Command{
|
||||
Use: "coco",
|
||||
Short: "golang project generator",
|
||||
}
|
||||
)
|
||||
|
||||
func init() {
|
||||
rootCmd.AddCommand(cocoUpdate())
|
||||
}
|
||||
|
||||
func main() {
|
||||
if err := rootCmd.Execute(); err != nil {
|
||||
logrus.Fatalln(err)
|
||||
}
|
||||
}
|
89
template/creator.go
Normal file
89
template/creator.go
Normal file
@ -0,0 +1,89 @@
|
||||
package template
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
"text/template"
|
||||
)
|
||||
|
||||
var (
|
||||
scaffold = map[string]string{
|
||||
"/.gitignore": templateGitignore,
|
||||
"/Makefile": templateMakefile,
|
||||
"/Dockerfile": templateDockerfile,
|
||||
"/docker-compose.yaml": templateDockerCompose,
|
||||
"/buf.yaml": templateBuf,
|
||||
"/buf.gen.yaml": templateBufGen,
|
||||
"/buf.work.yaml": templateBufWork,
|
||||
"/go.mod": templateModule,
|
||||
"/config_dev.yaml": templateDevYaml,
|
||||
"/config_prod.yaml": templateProdYaml,
|
||||
"/proto/v1/file_module.proto": templateApiservicesProto,
|
||||
"/proto/v1/file_model.proto": templateProto,
|
||||
"/proto/v1/buf.yaml": templateBuf,
|
||||
"/cmd/serve.go": templateCmdNewServe,
|
||||
"/cmd/exec.go": templateCmdExec,
|
||||
"/common/time.go": templateCommon,
|
||||
"/config/config.go": templateConfig,
|
||||
"/register/register.go": templateRouter,
|
||||
"/internal/repositories/.gitkeep": "",
|
||||
"/services/.gitkeep": "",
|
||||
"/gen/.gitkeep": "",
|
||||
}
|
||||
)
|
||||
|
||||
type Builder struct {
|
||||
Name string
|
||||
Path string
|
||||
SSH string
|
||||
}
|
||||
|
||||
func (b *Builder) Build() error {
|
||||
if err := os.MkdirAll(b.Path, 0755); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := b.write(b.Path+"/"+b.Name+".go", templateMain); err != nil {
|
||||
return err
|
||||
}
|
||||
for sr, v := range scaffold {
|
||||
i := strings.LastIndex(sr, "/")
|
||||
if i > 0 {
|
||||
dir := sr[:i]
|
||||
if err := os.MkdirAll(b.Path+dir, 0755); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err := b.write(b.Path+sr, v); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *Builder) write(name, tpl string) (err error) {
|
||||
defer func() {
|
||||
if err := recover(); err != nil {
|
||||
fmt.Println("Failed")
|
||||
}
|
||||
}()
|
||||
fmt.Printf("create %s \n", name)
|
||||
data, err := b.parse(tpl)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return os.WriteFile(name, data, 0644)
|
||||
}
|
||||
|
||||
func (b *Builder) parse(s string) ([]byte, error) {
|
||||
t, err := template.New("").Parse(s)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var buf bytes.Buffer
|
||||
if err := t.Execute(&buf, b); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return buf.Bytes(), nil
|
||||
}
|
70
template/template_apiservices.go
Normal file
70
template/template_apiservices.go
Normal file
@ -0,0 +1,70 @@
|
||||
package template
|
||||
|
||||
const templateApiservicesProto = `syntax = "proto3";
|
||||
|
||||
package proto.v1;
|
||||
|
||||
option go_package = "project/gen;genv1";
|
||||
|
||||
|
||||
// @route_group: true
|
||||
// @base_url: /v1/file
|
||||
// @gen_to: ./services/controller/v1/file_controller.go
|
||||
// @rpc_to: ./services/rpc/v1/file_impl.go
|
||||
service FileService {
|
||||
// @desc: 列表
|
||||
// @author: Young Xu
|
||||
// @method: GET
|
||||
// @api: /list
|
||||
rpc List (FileServiceListRequest) returns (FileServiceListResponse);
|
||||
// @desc: 上传
|
||||
// @author: Young Xu
|
||||
// @method: POST
|
||||
// @api: /upload
|
||||
rpc Upload (FileServiceUploadRequest) returns (FileServiceUploadResponse);
|
||||
// @desc: 删除
|
||||
// @author: Young Xu
|
||||
// @method: DELETE
|
||||
// @api: /delete
|
||||
rpc Delete (FileServiceDeleteRequest) returns (FileServiceDeleteResponse);
|
||||
// @desc: 下载
|
||||
// @author: Young Xu
|
||||
// @method: GET
|
||||
// @api: /download
|
||||
rpc Download (FileServiceDownloadRequest) returns (FileServiceDownloadResponse);
|
||||
}
|
||||
|
||||
|
||||
message FileServiceListRequest {
|
||||
string dirname = 1; // 目录
|
||||
}
|
||||
|
||||
message FileServiceListResponse {
|
||||
message Item {
|
||||
int64 file_id = 1; // 文件ID
|
||||
string filename = 2; // 文件名
|
||||
string file_size = 3; // 文件大小
|
||||
string created_at = 4; // 上传时间
|
||||
string dirname = 5; // 文件路径
|
||||
bool is_directory = 6; // 是否是目录
|
||||
}
|
||||
repeated Item items = 1; // 列表
|
||||
}
|
||||
|
||||
message FileServiceUploadRequest {}
|
||||
|
||||
message FileServiceUploadResponse {}
|
||||
|
||||
message FileServiceDeleteRequest {
|
||||
int64 file_id = 1; // 文件名
|
||||
}
|
||||
|
||||
message FileServiceDeleteResponse {}
|
||||
|
||||
message FileServiceDownloadRequest {
|
||||
// @v: required
|
||||
string file_id = 1; // 文件ID
|
||||
}
|
||||
|
||||
message FileServiceDownloadResponse {}
|
||||
`
|
83
template/template_command.go
Normal file
83
template/template_command.go
Normal file
@ -0,0 +1,83 @@
|
||||
package template
|
||||
|
||||
const templateCmdExec = `package cmd
|
||||
|
||||
import (
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
"gitter.top/common/lormatter"
|
||||
|
||||
"{{.Name}}/config"
|
||||
)
|
||||
|
||||
var (
|
||||
rootCmd = &cobra.Command{}
|
||||
cfgFile string
|
||||
)
|
||||
|
||||
func Execute() {
|
||||
// 预加载配置文件
|
||||
loadConfig()
|
||||
if err := rootCmd.Execute(); err != nil {
|
||||
logrus.Fatalf("exec command failed: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func init() {
|
||||
var formatter = lormatter.Formatter{
|
||||
ShowTime: true,
|
||||
ShowFile: true,
|
||||
}
|
||||
formatter.Register()
|
||||
rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "config_dev.yaml", "config file")
|
||||
rootCmd.AddCommand(apiServerCommand) // API服务
|
||||
rootCmd.AddCommand(grpcServerCommand) // GRPC服务
|
||||
}
|
||||
|
||||
func loadConfig() {
|
||||
// 初始化配置文件
|
||||
config.New(cfgFile)
|
||||
conf := config.Get()
|
||||
if err := conf.Load(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
const templateCmdNewServe = `package cmd
|
||||
|
||||
import (
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"{{.Name}}/register"
|
||||
)
|
||||
|
||||
var (
|
||||
apiServerCommand = &cobra.Command{
|
||||
Use: "api",
|
||||
Short: "start api server",
|
||||
Long: "start api server",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
router := register.NewRegister()
|
||||
if err := router.NewRouter(); err != nil {
|
||||
logrus.Errorf("register router failed: %v", err)
|
||||
}
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
var (
|
||||
grpcServerCommand = &cobra.Command{
|
||||
Use: "grpc",
|
||||
Short: "start grpc server",
|
||||
Long: "start grpc server",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
router := register.NewRegister()
|
||||
if err := router.NewGrpc(); err != nil {
|
||||
logrus.Errorf("register grpc failed: %v", err)
|
||||
}
|
||||
},
|
||||
}
|
||||
)
|
||||
`
|
10
template/template_common.go
Normal file
10
template/template_common.go
Normal file
@ -0,0 +1,10 @@
|
||||
package template
|
||||
|
||||
const templateCommon = `package common
|
||||
|
||||
import "time"
|
||||
|
||||
func Unix2Datetime(t int64) string {
|
||||
return time.Unix(t, 0).Format(time.DateTime)
|
||||
}
|
||||
`
|
62
template/template_config.go
Normal file
62
template/template_config.go
Normal file
@ -0,0 +1,62 @@
|
||||
package template
|
||||
|
||||
const templateConfig = `package config
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
type ServerConfig struct {
|
||||
ServerName string ` + "`" + `yaml:"server-name"` + "`" + `
|
||||
ServerListen string ` + "`" + `yaml:"server-listen"` + "`" + `
|
||||
GrpcListen string ` + "`" + `yaml:"grpc-listen"` + "`" + `
|
||||
Environment string ` + "`" + `yaml:"environment"` + "`" + `
|
||||
}
|
||||
|
||||
type ServerConf struct {
|
||||
ConfigFile string
|
||||
ServerConfig ` + "`" + `yaml:",inline"` + "`" + `
|
||||
}
|
||||
|
||||
var conf *ServerConf
|
||||
|
||||
func New(fileName string) {
|
||||
conf = new(ServerConf)
|
||||
conf.ConfigFile = fileName
|
||||
if err := conf.Load(); err != nil {
|
||||
logrus.Fatalf("read config file failed: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func Get() *ServerConf {
|
||||
if conf == nil {
|
||||
panic("config file not initialized")
|
||||
}
|
||||
return conf
|
||||
}
|
||||
|
||||
func (receiver *ServerConf) Load() error {
|
||||
data, err := os.ReadFile(receiver.ConfigFile)
|
||||
if err != nil && !os.IsNotExist(err) {
|
||||
return err
|
||||
}
|
||||
if err := yaml.Unmarshal(data, receiver); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (receiver *ServerConf) Rewrite() error {
|
||||
data, err := yaml.Marshal(receiver)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := os.WriteFile(receiver.ConfigFile, data, os.ModePerm); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
`
|
10
template/template_main.go
Normal file
10
template/template_main.go
Normal file
@ -0,0 +1,10 @@
|
||||
package template
|
||||
|
||||
const templateMain = `package main
|
||||
|
||||
import "{{.Name}}/cmd"
|
||||
|
||||
func main() {
|
||||
cmd.Execute()
|
||||
}
|
||||
`
|
19
template/template_model.go
Normal file
19
template/template_model.go
Normal file
@ -0,0 +1,19 @@
|
||||
package template
|
||||
|
||||
const templateProto = `syntax = "proto3";
|
||||
|
||||
package proto.v1;
|
||||
|
||||
option go_package = "project/gen;genv1";
|
||||
|
||||
|
||||
// @table_name: t_file
|
||||
message ModelFileRecord {
|
||||
int64 id = 1;
|
||||
string filename = 2;
|
||||
string file_size = 3;
|
||||
string dirname = 4;
|
||||
int64 created_at = 5;
|
||||
bool is_directory = 6;
|
||||
}
|
||||
`
|
18
template/template_module.go
Normal file
18
template/template_module.go
Normal file
@ -0,0 +1,18 @@
|
||||
package template
|
||||
|
||||
const templateModule = `module {{.Name}}
|
||||
|
||||
go 1.20
|
||||
|
||||
require (
|
||||
github.com/gin-gonic/gin v1.9.1
|
||||
github.com/google/wire v0.5.0
|
||||
github.com/sirupsen/logrus v1.9.3
|
||||
github.com/spf13/cobra v1.8.0
|
||||
gitter.top/coco/coco v0.0.1
|
||||
gitter.top/common/lormatter v0.0.0-20230910075849-28d49dccd03a
|
||||
google.golang.org/grpc v1.60.1
|
||||
google.golang.org/protobuf v1.32.0
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
)
|
||||
`
|
99
template/template_plugins_config.go
Normal file
99
template/template_plugins_config.go
Normal file
@ -0,0 +1,99 @@
|
||||
package template
|
||||
|
||||
const templateGitignore = `.idea
|
||||
{{.Name}}
|
||||
{{.Name}}.exe
|
||||
{{.Name}}.exe~
|
||||
`
|
||||
|
||||
const templateMakefile = `.PHONY : clean all ui api gen wire
|
||||
gen:
|
||||
ifeq ($(wildcard "webui/node_modules"),)
|
||||
buf generate
|
||||
else
|
||||
buf generate --exclude-path webui/node_modules
|
||||
endif
|
||||
|
||||
wire:
|
||||
cd gen/wire && wire
|
||||
|
||||
ui:
|
||||
cd webui && npm install && npm run build
|
||||
|
||||
api:
|
||||
go mod tidy && go build .
|
||||
./{{.Name}} api
|
||||
|
||||
all: gen wire ui api
|
||||
`
|
||||
|
||||
const templateDockerfile = `FROM images.local/golang:latest
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
RUN go install gitter.top/coco/protoc-gen-coco@latest &&\
|
||||
go install github.com/golang/protobuf/protoc-gen-go@latest &&\
|
||||
go install github.com/bufbuild/buf/cmd/...@latest
|
||||
|
||||
COPY . /app
|
||||
RUN npm install ts-proto
|
||||
RUN buf generate --exclude-path node_modules
|
||||
RUN cd webui && npm install && npm run build &&\
|
||||
cd .. && go mod tidy && go build .
|
||||
|
||||
EXPOSE 38080
|
||||
ENTRYPOINT [ "./filesaver", "api" ]
|
||||
`
|
||||
|
||||
const templateDockerCompose = `version: "3"
|
||||
|
||||
services:
|
||||
server:
|
||||
image: xuthus5/{{.Name}}:latest
|
||||
container_name: {{.Name}}
|
||||
restart: always
|
||||
volumes:
|
||||
- /data/containers/{{.Name}}:/app/data
|
||||
ports:
|
||||
- "30001:38080"
|
||||
`
|
||||
|
||||
const templateBuf = `version: v1
|
||||
breaking:
|
||||
use:
|
||||
- FILE
|
||||
lint:
|
||||
use:
|
||||
- DEFAULT
|
||||
except:
|
||||
- MINIMAL
|
||||
`
|
||||
|
||||
const templateBufGen = `version: v1
|
||||
plugins:
|
||||
- plugin: buf.build/protocolbuffers/go
|
||||
out: gen
|
||||
opt: paths=source_relative
|
||||
- plugin: coco
|
||||
out: gen
|
||||
opt:
|
||||
- paths=source_relative
|
||||
- prefix=proto
|
||||
- project_name={{.Name}}
|
||||
- plugin: buf.build/community/stephenh-ts-proto
|
||||
out: ./webui/src/gen
|
||||
opt:
|
||||
- paths=source_relative
|
||||
- snakeToCamel=json
|
||||
- esModuleInterop=true
|
||||
- plugin: buf.build/grpc/go:v1.3.0
|
||||
out: gen
|
||||
opt:
|
||||
- paths=source_relative
|
||||
- require_unimplemented_servers=false
|
||||
`
|
||||
|
||||
const templateBufWork = `version: v1
|
||||
directories:
|
||||
- proto
|
||||
`
|
62
template/template_router.go
Normal file
62
template/template_router.go
Normal file
@ -0,0 +1,62 @@
|
||||
package template
|
||||
|
||||
const templateRouter = `package register
|
||||
|
||||
import (
|
||||
"net"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/sirupsen/logrus"
|
||||
"gitter.top/coco/coco"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/reflection"
|
||||
|
||||
"{{.Name}}/config"
|
||||
"{{.Name}}/gen/wire"
|
||||
)
|
||||
|
||||
type Register struct{
|
||||
*config.ServerConf
|
||||
}
|
||||
|
||||
func NewRegister() *Register {
|
||||
return &Register{config.Get()}
|
||||
}
|
||||
|
||||
// NewRouter 注册路由
|
||||
func (receiver *Register) NewRouter() error {
|
||||
// 从这里开始实例化路由注册器
|
||||
var register = coco.NewRegister()
|
||||
register.DefaultRouter(coco.WithListenAddress(receiver.ServerListen),
|
||||
coco.WithGinMode(gin.ReleaseMode), coco.WithCors(), coco.WithRecovery())
|
||||
// register.RegisterStruct(wire.InitFileService())
|
||||
_ = register.PreRun(func() error {
|
||||
engine := register.RawEngine()
|
||||
engine.Static("/assets", "./webui/dist/assets")
|
||||
engine.NoRoute(func(ctx *gin.Context) {
|
||||
ctx.File("./webui/dist/index.html")
|
||||
})
|
||||
return nil
|
||||
})
|
||||
logrus.Infof("start api server: http://%s", receiver.ServerListen)
|
||||
register.Run()
|
||||
return nil
|
||||
}
|
||||
|
||||
// NewGrpc 注册grpc服务端
|
||||
func (receiver *Register) NewGrpc() error {
|
||||
lis, err := net.Listen("tcp", receiver.GrpcListen)
|
||||
if err != nil {
|
||||
logrus.Fatalf("failed to listen grpc: %v", err)
|
||||
}
|
||||
s := grpc.NewServer()
|
||||
//genv1.RegisterFileServiceServer(s, &rpcv1.FileService{})
|
||||
// Register reflection service on gRPC server.
|
||||
reflection.Register(s)
|
||||
logrus.Infof("grpc server: %s", receiver.GrpcListen)
|
||||
if err := s.Serve(lis); err != nil {
|
||||
logrus.Fatalf("failed to serve grpc: %v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
`
|
13
template/template_yaml.go
Normal file
13
template/template_yaml.go
Normal file
@ -0,0 +1,13 @@
|
||||
package template
|
||||
|
||||
const templateDevYaml = `server-name: {{.Name}}
|
||||
server-listen: 0.0.0.0:38080
|
||||
grpc-listen: 0.0.0.0:38090
|
||||
environment: dev
|
||||
`
|
||||
|
||||
const templateProdYaml = `server-name: {{.Name}}
|
||||
server-listen: 0.0.0.0:38080
|
||||
grpc-listen: 0.0.0.0:38090
|
||||
environment: prod
|
||||
`
|
Loading…
Reference in New Issue
Block a user