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 {
|
type Config struct {
|
||||||
Version string `yaml:"version"`
|
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 (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"github.com/spf13/cobra"
|
"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/runtime"
|
||||||
"gitter.top/coco/components/yaml"
|
"gitter.top/coco/components/yaml"
|
||||||
)
|
)
|
||||||
|
|
||||||
func cocoUpdate() *cobra.Command {
|
func Update() *cobra.Command {
|
||||||
var config Config
|
var config Config
|
||||||
var configPath string
|
var configPath string
|
||||||
return &cobra.Command{
|
return &cobra.Command{
|
||||||
Use: "update",
|
Use: "update",
|
||||||
Short: "coco tool update",
|
Short: "coco update",
|
||||||
PreRun: func(cmd *cobra.Command, args []string) {
|
PreRun: func(cmd *cobra.Command, args []string) {
|
||||||
configPath = runtime.ReplaceEachSlash(fmt.Sprintf("%s/.coco.yaml", runtime.GetHomeDir()))
|
configPath = runtime.ReplaceEachSlash(fmt.Sprintf("%s/.coco.yaml", runtime.GetHomeDir()))
|
||||||
_ = yaml.Read(configPath, &config)
|
_ = yaml.Read(configPath, &config)
|
||||||
},
|
},
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
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 {
|
if err != nil {
|
||||||
logrus.Errorf("new gitea api failed: %v", err)
|
logrus.Errorf("new gitea api failed: %v", err)
|
||||||
return
|
return
|
||||||
@ -36,12 +37,10 @@ func cocoUpdate() *cobra.Command {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// exec update
|
// exec update
|
||||||
repo := fmt.Sprintf("gitter.top/coco/bootstrap@%s", commitID)
|
repo := fmt.Sprintf("gitter.top/coco/bootstrap/coco/...@%s", commitID)
|
||||||
if output, err := runtime.Exec("go", "build", "-o", "coco", repo); err != nil {
|
if _, err := runtime.Exec("go", "install", repo); err != nil {
|
||||||
logrus.Errorf("update coco failed: %v", err)
|
logrus.Errorf("update bootstrap failed: %v", err)
|
||||||
return
|
return
|
||||||
} else {
|
|
||||||
logrus.Infof("%s", output)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
config.Version = commitID
|
config.Version = commitID
|
||||||
@ -49,6 +48,8 @@ func cocoUpdate() *cobra.Command {
|
|||||||
logrus.Errorf("write config failed: %v", err)
|
logrus.Errorf("write config failed: %v", err)
|
||||||
return
|
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 (
|
require (
|
||||||
github.com/sirupsen/logrus v1.9.0
|
github.com/sirupsen/logrus v1.9.3
|
||||||
github.com/spf13/cobra v1.6.1
|
github.com/spf13/cobra v1.8.0
|
||||||
gitter.top/coco/components v0.0.0-20230101151943-8e94d6d01339
|
gitter.top/coco/components v0.0.0-20230414170908-eb14d021db12
|
||||||
|
gitter.top/common/gobuf v0.0.0-20230929042601-dda09f2e32de
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
code.gitea.io/sdk/gitea v0.15.1 // indirect
|
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/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
|
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
|
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