mirror of
https://github.com/zhufuyi/sponge.git
synced 2025-09-26 20:51:14 +08:00
278 lines
9.4 KiB
Go
278 lines
9.4 KiB
Go
package generate
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
|
|
"github.com/zhufuyi/sponge/pkg/replacer"
|
|
|
|
"github.com/huandu/xstrings"
|
|
"github.com/spf13/cobra"
|
|
)
|
|
|
|
// HTTPPbCommand generate web service code based on protobuf file
|
|
func HTTPPbCommand() *cobra.Command {
|
|
var (
|
|
moduleName string // module name for go.mod
|
|
serverName string // server name
|
|
projectName string // project name for deployment name
|
|
repoAddr string // image repo address
|
|
outPath string // output directory
|
|
protobufFile string // protobuf file, support * matching
|
|
)
|
|
|
|
cmd := &cobra.Command{
|
|
Use: "http-pb",
|
|
Short: "Generate web service code based on protobuf file",
|
|
Long: `generate web service code based on protobuf file.
|
|
|
|
Examples:
|
|
# generate web service code.
|
|
sponge web http-pb --module-name=yourModuleName --server-name=yourServerName --project-name=yourProjectName --protobuf-file=./test.proto
|
|
|
|
# generate web service code and specify the output directory, Note: code generation will be canceled when the latest generated file already exists.
|
|
sponge web http-pb --module-name=yourModuleName --server-name=yourServerName --project-name=yourProjectName --protobuf-file=./test.proto --out=./yourServerDir
|
|
|
|
# generate web service code and specify the docker image repository address.
|
|
sponge web http-pb --module-name=yourModuleName --server-name=yourServerName --project-name=yourProjectName --repo-addr=192.168.3.37:9443/user-name --protobuf-file=./test.proto
|
|
`,
|
|
SilenceErrors: true,
|
|
SilenceUsage: true,
|
|
RunE: func(cmd *cobra.Command, args []string) error {
|
|
var err error
|
|
projectName, serverName = convertProjectAndServerName(projectName, serverName)
|
|
g := &httpPbGenerator{
|
|
moduleName: moduleName,
|
|
serverName: serverName,
|
|
projectName: projectName,
|
|
protobufFile: protobufFile,
|
|
repoAddr: repoAddr,
|
|
outPath: outPath,
|
|
}
|
|
outPath, err = g.generateCode()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
_ = generateConfigmap(serverName, outPath)
|
|
return nil
|
|
},
|
|
}
|
|
|
|
cmd.Flags().StringVarP(&moduleName, "module-name", "m", "", "module-name is the name of the module in the go.mod file")
|
|
_ = cmd.MarkFlagRequired("module-name")
|
|
cmd.Flags().StringVarP(&serverName, "server-name", "s", "", "server name")
|
|
_ = cmd.MarkFlagRequired("server-name")
|
|
cmd.Flags().StringVarP(&projectName, "project-name", "p", "", "project name")
|
|
_ = cmd.MarkFlagRequired("project-name")
|
|
cmd.Flags().StringVarP(&protobufFile, "protobuf-file", "f", "", "proto file")
|
|
_ = cmd.MarkFlagRequired("protobuf-file")
|
|
|
|
cmd.Flags().StringVarP(&repoAddr, "repo-addr", "r", "", "docker image repository address, excluding http and repository names")
|
|
cmd.Flags().StringVarP(&outPath, "out", "o", "", "output directory, default is ./serverName_http-pb_<time>")
|
|
|
|
return cmd
|
|
}
|
|
|
|
type httpPbGenerator struct {
|
|
moduleName string
|
|
serverName string
|
|
projectName string
|
|
protobufFile string
|
|
repoAddr string
|
|
outPath string
|
|
}
|
|
|
|
func (g *httpPbGenerator) generateCode() (string, error) {
|
|
protobufFiles, isImportTypes, err := parseProtobufFiles(g.protobufFile)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
subTplName := "http-pb"
|
|
r := Replacers[TplNameSponge]
|
|
if r == nil {
|
|
return "", errors.New("replacer is nil")
|
|
}
|
|
|
|
// setting up template information
|
|
subDirs := []string{ // processing-only subdirectories
|
|
"api/types", "cmd/serverNameExample_httpPbExample",
|
|
"sponge/configs", "sponge/deployments", "sponge/docs", "sponge/scripts", "sponge/third_party",
|
|
"internal/config", "internal/ecode", "internal/routers", "internal/server",
|
|
}
|
|
subFiles := []string{ // processing of sub-documents only
|
|
"sponge/.gitignore", "sponge/.golangci.yml", "sponge/go.mod", "sponge/go.sum",
|
|
"sponge/Jenkinsfile", "sponge/Makefile", "sponge/README.md",
|
|
}
|
|
ignoreDirs := []string{"cmd/sponge"} // specify the directory in the subdirectory where processing is ignored
|
|
ignoreFiles := []string{ // specify the files in the subdirectory to be ignored for processing
|
|
"types.pb.validate.go", "types.pb.go", // api/types
|
|
"swagger.json", "swagger.yaml", "apis.swagger.json", "apis.html", "docs.go", // sponge/docs
|
|
"userExample_rpc.go", "systemCode_rpc.go", "userExample_http.go", // internal/ecode
|
|
"routers_pbExample_test.go", "routers.go", "routers_test.go", "userExample.go", "userExample_router.go", // internal/routers
|
|
"grpc.go", "grpc_option.go", "grpc_test.go", // internal/server
|
|
}
|
|
|
|
if !isImportTypes {
|
|
ignoreFiles = append(ignoreFiles, "types.proto")
|
|
}
|
|
|
|
r.SetSubDirsAndFiles(subDirs, subFiles...)
|
|
r.SetIgnoreSubDirs(ignoreDirs...)
|
|
r.SetIgnoreSubFiles(ignoreFiles...)
|
|
fields := g.addFields(r)
|
|
r.SetReplacementFields(fields)
|
|
_ = r.SetOutputDir(g.outPath, g.serverName+"_"+subTplName)
|
|
if err = r.SaveFiles(); err != nil {
|
|
return "", err
|
|
}
|
|
|
|
_ = saveProtobufFiles(g.moduleName, g.serverName, r.GetOutputDir(), protobufFiles)
|
|
_ = saveGenInfo(g.moduleName, g.serverName, r.GetOutputDir())
|
|
_ = saveEmptySwaggerJSON(r.GetOutputDir())
|
|
|
|
fmt.Printf(`
|
|
using help:
|
|
1. open a terminal and execute the command to generate code: make proto
|
|
2. open file internal/handler/xxx.go, replace panic("implement me") according to template code example.
|
|
3. compile and run service: make run
|
|
4. visit http://localhost:8080/apis/swagger/index.html in your browser, and test api interface.
|
|
|
|
`)
|
|
outpath := r.GetOutputDir()
|
|
fmt.Printf("generate %s's web service code successfully, out = %s\n", g.serverName, outpath)
|
|
return outpath, nil
|
|
}
|
|
|
|
func (g *httpPbGenerator) addFields(r replacer.Replacer) []replacer.Field {
|
|
var fields []replacer.Field
|
|
|
|
repoHost, _ := parseImageRepoAddr(g.repoAddr)
|
|
|
|
fields = append(fields, deleteFieldsMark(r, httpFile, startMark, endMark)...)
|
|
fields = append(fields, deleteFieldsMark(r, dockerFile, wellStartMark, wellEndMark)...)
|
|
fields = append(fields, deleteFieldsMark(r, dockerFileBuild, wellStartMark, wellEndMark)...)
|
|
fields = append(fields, deleteFieldsMark(r, dockerComposeFile, wellStartMark, wellEndMark)...)
|
|
fields = append(fields, deleteFieldsMark(r, k8sDeploymentFile, wellStartMark, wellEndMark)...)
|
|
fields = append(fields, deleteFieldsMark(r, k8sServiceFile, wellStartMark, wellEndMark)...)
|
|
fields = append(fields, deleteFieldsMark(r, imageBuildFile, wellStartMark, wellEndMark)...)
|
|
fields = append(fields, deleteFieldsMark(r, imageBuildLocalFile, wellStartMark, wellEndMark)...)
|
|
fields = append(fields, deleteAllFieldsMark(r, makeFile, wellStartMark, wellEndMark)...)
|
|
fields = append(fields, deleteFieldsMark(r, gitIgnoreFile, wellStartMark, wellEndMark)...)
|
|
fields = append(fields, deleteAllFieldsMark(r, protoShellFile, wellStartMark, wellEndMark)...)
|
|
fields = append(fields, deleteAllFieldsMark(r, appConfigFile, wellStartMark, wellEndMark)...)
|
|
fields = append(fields, deleteFieldsMark(r, deploymentConfigFile, wellStartMark, wellEndMark)...)
|
|
fields = append(fields, replaceFileContentMark(r, readmeFile, "## "+g.serverName)...)
|
|
fields = append(fields, []replacer.Field{
|
|
{ // replace the configuration of the *.yml file
|
|
Old: appConfigFileMark,
|
|
New: httpServerConfigCode,
|
|
},
|
|
{ // replace the configuration of the *.yml file
|
|
Old: appConfigFileMark2,
|
|
New: getDBConfigCode(DBDriverMysql),
|
|
},
|
|
{ // replace the contents of the model/init.go file
|
|
Old: modelInitDBFileMark,
|
|
New: getInitDBCode(DBDriverMysql), // default is mysql
|
|
},
|
|
{ // replace the contents of the Dockerfile file
|
|
Old: dockerFileMark,
|
|
New: dockerFileHTTPCode,
|
|
},
|
|
{ // replace the contents of the Dockerfile_build file
|
|
Old: dockerFileBuildMark,
|
|
New: dockerFileBuildHTTPCode,
|
|
},
|
|
{ // replace the contents of the image-build.sh file
|
|
Old: imageBuildFileMark,
|
|
New: imageBuildFileHTTPCode,
|
|
},
|
|
{ // replace the contents of the image-build-local.sh file
|
|
Old: imageBuildLocalFileMark,
|
|
New: imageBuildLocalFileHTTPCode,
|
|
},
|
|
{ // replace the contents of the docker-compose.yml file
|
|
Old: dockerComposeFileMark,
|
|
New: dockerComposeFileHTTPCode,
|
|
},
|
|
{ // replace the contents of the *-configmap.yml file
|
|
Old: deploymentConfigFileMark,
|
|
New: getDBConfigCode(DBDriverMysql, true),
|
|
},
|
|
{ // replace the contents of the *-deployment.yml file
|
|
Old: k8sDeploymentFileMark,
|
|
New: k8sDeploymentFileHTTPCode,
|
|
},
|
|
{ // replace the contents of the *-svc.yml file
|
|
Old: k8sServiceFileMark,
|
|
New: k8sServiceFileHTTPCode,
|
|
},
|
|
{ // replace the contents of the proto.sh file
|
|
Old: protoShellFileGRPCMark,
|
|
New: "",
|
|
},
|
|
{ // replace the contents of the proto.sh file
|
|
Old: protoShellFileMark,
|
|
New: protoShellHandlerCode,
|
|
},
|
|
{
|
|
Old: "github.com/zhufuyi/sponge",
|
|
New: g.moduleName,
|
|
},
|
|
{
|
|
Old: g.moduleName + "/pkg",
|
|
New: "github.com/zhufuyi/sponge/pkg",
|
|
},
|
|
{ // replace the sponge version of the go.mod file
|
|
Old: spongeTemplateVersionMark,
|
|
New: getLocalSpongeTemplateVersion(),
|
|
},
|
|
{
|
|
Old: "sponge api docs",
|
|
New: g.serverName + " api docs",
|
|
},
|
|
{
|
|
Old: "serverNameExample",
|
|
New: g.serverName,
|
|
},
|
|
// docker image and k8s deployment script replacement
|
|
{
|
|
Old: "server-name-example",
|
|
New: xstrings.ToKebabCase(g.serverName), // convert to kebab-case format
|
|
},
|
|
// docker image and k8s deployment script replacement
|
|
{
|
|
Old: "project-name-example",
|
|
New: g.projectName,
|
|
},
|
|
{
|
|
Old: "projectNameExample",
|
|
New: g.projectName,
|
|
},
|
|
{
|
|
Old: "repo-addr-example",
|
|
New: g.repoAddr,
|
|
},
|
|
{
|
|
Old: "image-repo-host",
|
|
New: repoHost,
|
|
},
|
|
{
|
|
Old: "_httpPbExample",
|
|
New: "",
|
|
},
|
|
{
|
|
Old: "_pbExample",
|
|
New: "",
|
|
},
|
|
{
|
|
Old: "_mixExample",
|
|
New: "",
|
|
},
|
|
}...)
|
|
|
|
return fields
|
|
}
|