mirror of https://github.com/zhufuyi/sponge
adjust directory structure of large repository
This commit is contained in:
parent
1907ce37d0
commit
acdcb11599
|
@ -3,9 +3,8 @@ syntax = "proto3";
|
|||
package api.greeter.v1;
|
||||
|
||||
import "google/api/annotations.proto";
|
||||
import "google/api/http.proto";
|
||||
|
||||
option go_package = "yourModuleName222/api/v1";
|
||||
option go_package = "yourModuleName/api/v1";
|
||||
|
||||
service GreeterService {
|
||||
// create a record
|
||||
|
@ -23,6 +22,12 @@ service GreeterService {
|
|||
};
|
||||
}
|
||||
|
||||
rpc DeleteByID2(DeleteGreeterByIDRequest) returns (DeleteGreeterByIDReply) {
|
||||
option (google.api.http) = {
|
||||
delete: "/api/v1/greeter2/{id}"
|
||||
};
|
||||
}
|
||||
|
||||
// update a record by id
|
||||
rpc UpdateByID(UpdateGreeterByIDRequest) returns (UpdateGreeterByIDReply) {
|
||||
option (google.api.http) = {
|
||||
|
|
|
@ -4,7 +4,7 @@ package v1;
|
|||
|
||||
import "google/api/annotations.proto";
|
||||
|
||||
option go_package = "yourModuleName333/api/v1";
|
||||
option go_package = "yourModuleName/api/v1";
|
||||
|
||||
service mixed {
|
||||
// create a record
|
||||
|
|
|
@ -39,7 +39,7 @@ protoc --proto_path=. --proto_path=./third_party --go-gin_out=. --go-gin_opt=pat
|
|||
protoc --proto_path=. --proto_path=./third_party --go-gin_out=. --go-gin_opt=paths=source_relative --go-gin_opt=plugin=mix \
|
||||
--go-gin_opt=moduleName=yourModuleName --go-gin_opt=serverName=yourServerName *.proto
|
||||
|
||||
# if you want the generated code to suited to mono-repo, you need to specify the parameter --go-gin_opt=suitedMonoRepo=true
|
||||
# if you want the generated code to suited to mono-repo, you need to set the parameter --go-gin_opt=suitedMonoRepo=true
|
||||
|
||||
Tip:
|
||||
If you want to merge the code, after generating the code, execute the command "sponge merge http-pb" or
|
||||
|
@ -89,7 +89,7 @@ func main() {
|
|||
pluginName := strings.ReplaceAll(plugin, " ", "")
|
||||
dirName := "internal"
|
||||
if suitedMonoRepo {
|
||||
dirName = "Internal"
|
||||
dirName = serverName + "/internal"
|
||||
}
|
||||
switch pluginName {
|
||||
case handlerPlugin:
|
||||
|
@ -279,7 +279,7 @@ func firstLetterToUpper(s string) []byte {
|
|||
|
||||
func adaptMonoRepo(moduleName string, serverName string, data []byte) []byte {
|
||||
matchStr := map[string]string{
|
||||
fmt.Sprintf("\"%s/internal/", moduleName): fmt.Sprintf("\"%s/Internal/", moduleName+"/"+serverName),
|
||||
fmt.Sprintf("\"%s/internal/", moduleName): fmt.Sprintf("\"%s/internal/", moduleName+"/"+serverName),
|
||||
fmt.Sprintf("\"%s/configs", moduleName): fmt.Sprintf("\"%s/configs", moduleName+"/"+serverName),
|
||||
fmt.Sprintf("\"%s/api", moduleName): fmt.Sprintf("\"%s/api", moduleName+"/"+serverName),
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ const (
|
|||
protoc --proto_path=. --proto_path=./third_party --go-rpc-tmpl_out=. --go-rpc-tmpl_opt=paths=source_relative \
|
||||
--go-rpc-tmpl_opt=moduleName=yourModuleName --go-rpc-tmpl_opt=serverName=yourServerName *.proto
|
||||
|
||||
# if you want the generated code to suited to mono-repo, you need to specify the parameter --go-gin_opt=suitedMonoRepo=true
|
||||
# if you want the generated code to suited to mono-repo, you need to set the parameter --go-gin_opt=suitedMonoRepo=true
|
||||
|
||||
Tip:
|
||||
If you want to merge the code, after generating the code, execute the command "sponge merge rpc-pb",
|
||||
|
@ -72,7 +72,7 @@ func main() {
|
|||
|
||||
dirName := "internal"
|
||||
if suitedMonoRepo {
|
||||
dirName = "Internal"
|
||||
dirName = serverName + "/internal"
|
||||
}
|
||||
if tmplDir == "" {
|
||||
tmplDir = dirName + "/service"
|
||||
|
@ -182,7 +182,7 @@ func firstLetterToUpper(s string) []byte {
|
|||
|
||||
func adaptMonoRepo(moduleName string, serverName string, data []byte) []byte {
|
||||
matchStr := map[string]string{
|
||||
fmt.Sprintf("\"%s/internal/", moduleName): fmt.Sprintf("\"%s/Internal/", moduleName+"/"+serverName),
|
||||
fmt.Sprintf("\"%s/internal/", moduleName): fmt.Sprintf("\"%s/internal/", moduleName+"/"+serverName),
|
||||
fmt.Sprintf("\"%s/configs", moduleName): fmt.Sprintf("\"%s/configs", moduleName+"/"+serverName),
|
||||
fmt.Sprintf("\"%s/api", moduleName): fmt.Sprintf("\"%s/api", moduleName+"/"+serverName),
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ package generate
|
|||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/fatih/color"
|
||||
"github.com/spf13/cobra"
|
||||
|
@ -33,12 +34,12 @@ func CacheCommand(parentName string) *cobra.Command {
|
|||
|
||||
Examples:
|
||||
# generate kv cache code
|
||||
sponge %s cache --module-name=yourModuleName --cache-name=userToken --prefix-key=user:token: --key-name=id --key-type=uint64 --value-name=token --value-type=string
|
||||
sponge %s cache --module-name=yourModuleName --cache-name=userToken --key-name=id --key-type=uint64 --value-name=token --value-type=string
|
||||
|
||||
# generate kv cache code and specify the server directory, Note: code generation will be canceled when the latest generated file already exists.
|
||||
sponge %s cache --module-name=yourModuleName --cache-name=token --prefix-key=user:token: --key-name=id --key-type=uint64 --value-name=token --value-type=string --out=./yourServerDir
|
||||
sponge %s cache --module-name=yourModuleName --cache-name=token --prefix-key=user:token --key-name=id --key-type=uint64 --value-name=token --value-type=string --out=./yourServerDir
|
||||
|
||||
# if you want the generated code to suited to mono-repo, you need to specify the parameter --suited-mono-repo=true --serverName=yourServerName
|
||||
# if you want the generated code to suited to mono-repo, you need to set the parameter --suited-mono-repo=true --server-name=yourServerName
|
||||
`, parentName, parentName)),
|
||||
SilenceErrors: true,
|
||||
SilenceUsage: true,
|
||||
|
@ -58,6 +59,13 @@ Examples:
|
|||
serverName = convertServerName(serverName)
|
||||
outPath = changeOutPath(outPath, serverName)
|
||||
}
|
||||
cacheName = strings.ReplaceAll(cacheName, ":", "")
|
||||
|
||||
if prefixKey == "" || prefixKey == ":" {
|
||||
prefixKey = cacheName + ":"
|
||||
} else if prefixKey[len(prefixKey)-1] != ':' {
|
||||
prefixKey += ":"
|
||||
}
|
||||
|
||||
var err error
|
||||
var g = &stringCacheGenerator{
|
||||
|
@ -91,14 +99,14 @@ using help:
|
|||
cmd.Flags().StringVarP(&moduleName, "module-name", "m", "", "module-name is the name of the module in the go.mod file")
|
||||
cmd.Flags().StringVarP(&cacheName, "cache-name", "c", "", "cache name, e.g. userToken")
|
||||
_ = cmd.MarkFlagRequired("cache-name")
|
||||
cmd.Flags().StringVarP(&prefixKey, "prefix-key", "p", "", "cache prefix key, must end with a colon, e.g. user:token:")
|
||||
cmd.Flags().StringVarP(&keyName, "key-name", "", "", "key name, e.g. id")
|
||||
cmd.Flags().StringVarP(&prefixKey, "prefix-key", "p", "", "cache prefix key, e.g. user:token")
|
||||
cmd.Flags().StringVarP(&keyName, "key-name", "k", "", "key name, e.g. id")
|
||||
_ = cmd.MarkFlagRequired("key-name")
|
||||
cmd.Flags().StringVarP(&keyType, "key-type", "", "", "key go type, e.g. uint64")
|
||||
cmd.Flags().StringVarP(&keyType, "key-type", "t", "", "key go type, e.g. uint64")
|
||||
_ = cmd.MarkFlagRequired("key-type")
|
||||
cmd.Flags().StringVarP(&valueName, "value-name", "", "", "value name, e.g. token")
|
||||
cmd.Flags().StringVarP(&valueName, "value-name", "v", "", "value name, e.g. token")
|
||||
_ = cmd.MarkFlagRequired("value-name")
|
||||
cmd.Flags().StringVarP(&valueType, "value-type", "", "", "value go type, e.g. string")
|
||||
cmd.Flags().StringVarP(&valueType, "value-type", "w", "", "value go type, e.g. string")
|
||||
_ = cmd.MarkFlagRequired("value-type")
|
||||
cmd.Flags().StringVarP(&serverName, "server-name", "s", "", "server name")
|
||||
cmd.Flags().BoolVarP(&suitedMonoRepo, "suited-mono-repo", "l", false, "whether the generated code is suitable for mono-repo")
|
||||
|
@ -122,18 +130,12 @@ type stringCacheGenerator struct {
|
|||
}
|
||||
|
||||
func (g *stringCacheGenerator) generateCode() (string, error) {
|
||||
subTplName := "cache"
|
||||
subTplName := codeNameCache
|
||||
r := Replacers[TplNameSponge]
|
||||
if r == nil {
|
||||
return "", errors.New("replacer is nil")
|
||||
}
|
||||
|
||||
if g.prefixKey == "" || g.prefixKey == ":" {
|
||||
g.prefixKey = g.cacheName + ":"
|
||||
} else if g.prefixKey[len(g.prefixKey)-1] != ':' {
|
||||
g.prefixKey += ":"
|
||||
}
|
||||
|
||||
// specify the subdirectory and files
|
||||
subDirs := []string{}
|
||||
subFiles := []string{"internal/cache/cacheNameExample.go"}
|
||||
|
@ -207,7 +209,7 @@ func (g *stringCacheGenerator) addFields(r replacer.Replacer) []replacer.Field {
|
|||
}...)
|
||||
|
||||
if g.suitedMonoRepo {
|
||||
fs := SubServerCodeFields(r.GetOutputDir(), g.moduleName, g.serverName)
|
||||
fs := SubServerCodeFields(g.moduleName, g.serverName)
|
||||
fields = append(fields, fs...)
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ import (
|
|||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/huandu/xstrings"
|
||||
|
||||
|
@ -45,7 +46,7 @@ const (
|
|||
codeNameHandler = "handler"
|
||||
codeNameHandlerPb = "handler-pb"
|
||||
codeNameService = "service"
|
||||
codeNameServiceHTTP = "service-http"
|
||||
codeNameServiceHTTP = "service-handler"
|
||||
codeNameHTTP = "http"
|
||||
codeNameHTTPPb = "http-pb"
|
||||
codeNameGRPC = "grpc"
|
||||
|
@ -376,7 +377,12 @@ func getNamesFromOutDir(dir string) (moduleName string, serverName string, suite
|
|||
return "", "", false
|
||||
}
|
||||
|
||||
func saveProtobufFiles(moduleName string, serverName string, outputDir string, protobufFiles []string) error {
|
||||
func saveProtobufFiles(moduleName string, serverName string, suitedMonoRepo bool, outputDir string, protobufFiles []string) error {
|
||||
if suitedMonoRepo {
|
||||
outputDir = strings.TrimSuffix(outputDir, serverName)
|
||||
outputDir = strings.TrimSuffix(outputDir, gofile.GetPathDelimiter())
|
||||
}
|
||||
|
||||
for _, pbFile := range protobufFiles {
|
||||
pbContent, err := os.ReadFile(pbFile)
|
||||
if err != nil {
|
||||
|
@ -390,6 +396,9 @@ func saveProtobufFiles(moduleName string, serverName string, outputDir string, p
|
|||
|
||||
_, name := filepath.Split(pbFile)
|
||||
file := dir + "/" + name
|
||||
if gofile.IsExists(file) {
|
||||
return fmt.Errorf("file %s already exists", file)
|
||||
}
|
||||
err = os.WriteFile(file, pbContent, 0666)
|
||||
if err != nil {
|
||||
return fmt.Errorf("save file %s error, %v", file, err)
|
||||
|
@ -607,21 +616,51 @@ func removeElements(slice []string, elements ...string) []string {
|
|||
return result
|
||||
}
|
||||
|
||||
func serverCodeFields(outDir string, moduleName string, serverName string) []replacer.Field {
|
||||
parts := strings.Split(outDir, gofile.GetPathDelimiter())
|
||||
func moveProtoFileToAPIDir(moduleName string, serverName string, suitedMonoRepo bool, outputDir string) error {
|
||||
apiDir := outputDir + gofile.GetPathDelimiter() + "api"
|
||||
protoFiles, _ := gofile.ListFiles(apiDir, gofile.WithNoAbsolutePath(), gofile.WithSuffix(".proto"))
|
||||
if err := saveProtobufFiles(moduleName, serverName, suitedMonoRepo, outputDir, protoFiles); err != nil {
|
||||
return err
|
||||
}
|
||||
time.Sleep(time.Millisecond * 100)
|
||||
_ = os.RemoveAll(apiDir)
|
||||
return nil
|
||||
}
|
||||
|
||||
var (
|
||||
// for protoc.sh and protoc-doc.sh
|
||||
monoRepoAPIPath = `bash scripts/init.sh
|
||||
cd ..
|
||||
protoBasePath="api"`
|
||||
// for patch.sh
|
||||
typePbShellCode = ` if [ ! -d "../api/types" ]; then
|
||||
sponge patch gen-types-pb --out=./
|
||||
checkResult $?
|
||||
mv -f api/types ../api
|
||||
rmdir api
|
||||
fi`
|
||||
dupCodeMark = "--dir=internal/ecode"
|
||||
adaptDupCode = func(serverType string, serverName string) string {
|
||||
if serverType == codeNameHTTP {
|
||||
return dupCodeMark
|
||||
}
|
||||
return fmt.Sprintf("--dir=%s/internal/ecode", serverName)
|
||||
}
|
||||
)
|
||||
|
||||
func serverCodeFields(serverType string, moduleName string, serverName string) []replacer.Field {
|
||||
return []replacer.Field{
|
||||
{ // internal initial capital means exportable, external code can be referenced
|
||||
{
|
||||
Old: fmt.Sprintf("\"%s/internal/", moduleName),
|
||||
New: fmt.Sprintf("\"%s/Internal/", moduleName+"/"+serverName),
|
||||
New: fmt.Sprintf("\"%s/internal/", moduleName+"/"+serverName),
|
||||
},
|
||||
{
|
||||
Old: parts[len(parts)-1] + gofile.GetPathDelimiter() + "internal",
|
||||
New: parts[len(parts)-1] + gofile.GetPathDelimiter() + "Internal",
|
||||
Old: "=$(cat docs/gen.info",
|
||||
New: fmt.Sprintf("=$(cat %s/docs/gen.info", serverName),
|
||||
},
|
||||
{
|
||||
Old: "--dir=internal/ecode",
|
||||
New: "--dir=Internal/ecode",
|
||||
Old: dupCodeMark,
|
||||
New: adaptDupCode(serverType, serverName),
|
||||
},
|
||||
{
|
||||
Old: fmt.Sprintf("\"%s/cmd/", moduleName),
|
||||
|
@ -640,24 +679,50 @@ func serverCodeFields(outDir string, moduleName string, serverName string) []rep
|
|||
New: fmt.Sprintf("\"%s/api", moduleName+"/"+serverName),
|
||||
},
|
||||
{
|
||||
Old: "vrf internal",
|
||||
New: "vrf Internal",
|
||||
Old: "merge_file_name=docs/apis.json",
|
||||
New: fmt.Sprintf("merge_file_name=%s/docs/apis.json", serverName),
|
||||
},
|
||||
{
|
||||
Old: "--file=docs/apis.swagger.json",
|
||||
New: fmt.Sprintf("--file=%s/docs/apis.swagger.json", serverName),
|
||||
},
|
||||
{
|
||||
Old: "sponge merge http-pb",
|
||||
New: fmt.Sprintf("sponge merge http-pb --dir=%s", serverName),
|
||||
},
|
||||
{
|
||||
Old: "sponge merge rpc-pb",
|
||||
New: fmt.Sprintf("sponge merge rpc-pb --dir=%s", serverName),
|
||||
},
|
||||
{
|
||||
Old: "sponge merge rpc-gw-pb",
|
||||
New: fmt.Sprintf("sponge merge rpc-gw-pb --dir=%s", serverName),
|
||||
},
|
||||
{
|
||||
Old: "docs/apis.html",
|
||||
New: fmt.Sprintf("%s/docs/apis.html", serverName),
|
||||
},
|
||||
{
|
||||
Old: `sponge patch gen-types-pb --out=./`,
|
||||
New: typePbShellCode,
|
||||
},
|
||||
{
|
||||
Old: `protoBasePath="api"`,
|
||||
New: monoRepoAPIPath,
|
||||
},
|
||||
{
|
||||
Old: fmt.Sprintf("go get %s@", moduleName),
|
||||
New: fmt.Sprintf("go get %s@", "github.com/zhufuyi/sponge"),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// SubServerCodeFields sub server code fields
|
||||
func SubServerCodeFields(outDir string, moduleName string, serverName string) []replacer.Field {
|
||||
parts := strings.Split(outDir, gofile.GetPathDelimiter())
|
||||
|
||||
func SubServerCodeFields(moduleName string, serverName string) []replacer.Field {
|
||||
return []replacer.Field{
|
||||
{ // internal initial capital means exportable, external code can be referenced
|
||||
Old: fmt.Sprintf("\"%s/internal/", moduleName),
|
||||
New: fmt.Sprintf("\"%s/Internal/", moduleName+"/"+serverName),
|
||||
},
|
||||
{
|
||||
Old: parts[len(parts)-1] + gofile.GetPathDelimiter() + "internal",
|
||||
New: parts[len(parts)-1] + gofile.GetPathDelimiter() + "Internal",
|
||||
Old: fmt.Sprintf("\"%s/internal/", moduleName),
|
||||
New: fmt.Sprintf("\"%s/internal/", moduleName+"/"+serverName),
|
||||
},
|
||||
{
|
||||
Old: fmt.Sprintf("\"%s/configs", moduleName),
|
||||
|
@ -667,10 +732,6 @@ func SubServerCodeFields(outDir string, moduleName string, serverName string) []
|
|||
Old: fmt.Sprintf("\"%s/api", moduleName),
|
||||
New: fmt.Sprintf("\"%s/api", moduleName+"/"+serverName),
|
||||
},
|
||||
{
|
||||
Old: "vrf internal",
|
||||
New: "vrf Internal",
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -736,3 +797,49 @@ func cutPath(srcFilePath string) string {
|
|||
srcFilePath = strings.ReplaceAll(srcFilePath, dirPath, ".")
|
||||
return strings.ReplaceAll(srcFilePath, "\\", "/")
|
||||
}
|
||||
|
||||
func wrapPoint(s string) string {
|
||||
return "`" + s + "`"
|
||||
}
|
||||
|
||||
func setReadmeTitle(moduleName string, serverName string, serverType string, suitedMonoRepo bool) string {
|
||||
var repoType string
|
||||
if suitedMonoRepo {
|
||||
repoType = "mono-repo"
|
||||
} else {
|
||||
if serverType == codeNameHTTP {
|
||||
repoType = "monolith"
|
||||
} else {
|
||||
repoType = "multi-repo"
|
||||
}
|
||||
}
|
||||
|
||||
return wellPrefix + serverName + fmt.Sprintf(`
|
||||
|
||||
| Feature | Value |
|
||||
| :----------------: | :-----------: |
|
||||
| Server name | %s |
|
||||
| Server type | %s |
|
||||
| Go module name | %s |
|
||||
| Repository type | %s |
|
||||
|
||||
`, wrapPoint(serverName), wrapPoint(serverType), wrapPoint(moduleName), wrapPoint(repoType))
|
||||
}
|
||||
|
||||
// GetGoModFields get go mod fields
|
||||
func GetGoModFields(moduleName string) []replacer.Field {
|
||||
return []replacer.Field{
|
||||
{
|
||||
Old: "github.com/zhufuyi/sponge",
|
||||
New: moduleName,
|
||||
},
|
||||
{
|
||||
Old: defaultGoModVersion,
|
||||
New: getLocalGoVersion(),
|
||||
},
|
||||
{
|
||||
Old: spongeTemplateVersionMark,
|
||||
New: getLocalSpongeTemplateVersion(),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -49,7 +49,7 @@ Examples:
|
|||
# generate dao code and specify the server directory, Note: code generation will be canceled when the latest generated file already exists.
|
||||
sponge %s dao --db-driver=mysql --db-dsn=root:123456@(192.168.3.37:3306)/test --db-table=user --out=./yourServerDir
|
||||
|
||||
# if you want the generated code to suited to mono-repo, you need to specify the parameter --suited-mono-repo=true --serverName=yourServerName
|
||||
# if you want the generated code to suited to mono-repo, you need to set the parameter --suited-mono-repo=true --server-name=yourServerName
|
||||
`, parentName, parentName, parentName, parentName)),
|
||||
SilenceErrors: true,
|
||||
SilenceUsage: true,
|
||||
|
@ -152,7 +152,7 @@ type daoGenerator struct {
|
|||
}
|
||||
|
||||
func (g *daoGenerator) generateCode() (string, error) {
|
||||
subTplName := "dao"
|
||||
subTplName := codeNameDao
|
||||
r := Replacers[TplNameSponge]
|
||||
if r == nil {
|
||||
return "", errors.New("r is nil")
|
||||
|
@ -262,7 +262,7 @@ func (g *daoGenerator) addFields(r replacer.Replacer) []replacer.Field {
|
|||
}...)
|
||||
|
||||
if g.suitedMonoRepo {
|
||||
fs := SubServerCodeFields(r.GetOutputDir(), g.moduleName, g.serverName)
|
||||
fs := SubServerCodeFields(g.moduleName, g.serverName)
|
||||
fields = append(fields, fs...)
|
||||
}
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ Examples:
|
|||
# generate grpc service code and specify the docker image repository address.
|
||||
sponge micro grpc-http-pb --module-name=yourModuleName --server-name=yourServerName --project-name=yourProjectName --repo-addr=192.168.3.37:9443/user-name --protobuf-file=./demo.proto
|
||||
|
||||
# if you want the generated code to suited to mono-repo, you need to specify the parameter --suited-mono-repo=true
|
||||
# if you want the generated code to suited to mono-repo, you need to set the parameter --suited-mono-repo=true
|
||||
`),
|
||||
SilenceErrors: true,
|
||||
SilenceUsage: true,
|
||||
|
@ -106,7 +106,7 @@ func (g *httpAndGRPCPbGenerator) generateCode() error {
|
|||
return err
|
||||
}
|
||||
|
||||
subTplName := "grpc-http-pb"
|
||||
subTplName := codeNameGRPCHTTP
|
||||
r := Replacers[TplNameSponge]
|
||||
if r == nil {
|
||||
return errors.New("replacer is nil")
|
||||
|
@ -121,9 +121,7 @@ func (g *httpAndGRPCPbGenerator) generateCode() error {
|
|||
"sponge/.gitignore", "sponge/.golangci.yml", "sponge/go.mod", "sponge/go.sum",
|
||||
"sponge/Jenkinsfile", "sponge/Makefile", "sponge/README.md",
|
||||
}
|
||||
if g.suitedMonoRepo {
|
||||
subFiles = removeElements(subFiles, "sponge/go.mod", "sponge/go.sum")
|
||||
}
|
||||
|
||||
if isImportTypes {
|
||||
subFiles = append(subFiles, "api/types/types.proto")
|
||||
}
|
||||
|
@ -148,6 +146,12 @@ func (g *httpAndGRPCPbGenerator) generateCode() error {
|
|||
"service.go", "service_test.go",
|
||||
},
|
||||
}
|
||||
|
||||
if g.suitedMonoRepo {
|
||||
subDirs = removeElements(subDirs, "sponge/third_party")
|
||||
subFiles = removeElements(subFiles, "sponge/go.mod", "sponge/go.sum", "api/types/types.proto")
|
||||
}
|
||||
|
||||
replaceFiles := make(map[string][]string)
|
||||
subFiles = append(subFiles, getSubFiles(selectFiles, replaceFiles)...)
|
||||
|
||||
|
@ -163,7 +167,9 @@ func (g *httpAndGRPCPbGenerator) generateCode() error {
|
|||
return err
|
||||
}
|
||||
|
||||
_ = saveProtobufFiles(g.moduleName, g.serverName, r.GetOutputDir(), protobufFiles)
|
||||
if err = saveProtobufFiles(g.moduleName, g.serverName, g.suitedMonoRepo, r.GetOutputDir(), protobufFiles); err != nil {
|
||||
return err
|
||||
}
|
||||
_ = saveGenInfo(g.moduleName, g.serverName, g.suitedMonoRepo, r.GetOutputDir())
|
||||
|
||||
fmt.Printf(`
|
||||
|
@ -197,7 +203,8 @@ func (g *httpAndGRPCPbGenerator) addFields(r replacer.Replacer) []replacer.Field
|
|||
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, wellPrefix+g.serverName)...)
|
||||
fields = append(fields, replaceFileContentMark(r, readmeFile,
|
||||
setReadmeTitle(g.moduleName, g.serverName, codeNameGRPCHTTP, g.suitedMonoRepo))...)
|
||||
fields = append(fields, []replacer.Field{
|
||||
{ // replace the configuration of the *.yml file
|
||||
Old: appConfigFileMark,
|
||||
|
|
|
@ -50,6 +50,8 @@ Examples:
|
|||
|
||||
# generate handler and protobuf code and specify the server directory, Note: code generation will be canceled when the latest generated file already exists.
|
||||
sponge web handler-pb --db-driver=mysql --db-dsn=root:123456@(192.168.3.37:3306)/test --db-table=user --out=./yourServerDir
|
||||
|
||||
# if you want the generated code to suited to mono-repo, you need to set the parameter --suited-mono-repo=true
|
||||
`),
|
||||
SilenceErrors: true,
|
||||
SilenceUsage: true,
|
||||
|
@ -148,7 +150,7 @@ type handlerPbGenerator struct {
|
|||
}
|
||||
|
||||
func (g *handlerPbGenerator) generateCode() (string, error) {
|
||||
subTplName := "handler-pb"
|
||||
subTplName := codeNameHandlerPb
|
||||
r := Replacers[TplNameSponge]
|
||||
if r == nil {
|
||||
return "", errors.New("replacer is nil")
|
||||
|
@ -226,6 +228,12 @@ func (g *handlerPbGenerator) generateCode() (string, error) {
|
|||
return "", err
|
||||
}
|
||||
|
||||
if g.suitedMonoRepo {
|
||||
if err := moveProtoFileToAPIDir(g.moduleName, g.serverName, g.suitedMonoRepo, r.GetOutputDir()); err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
|
||||
return r.GetOutputDir(), nil
|
||||
}
|
||||
|
||||
|
@ -319,7 +327,7 @@ func (g *handlerPbGenerator) addFields(r replacer.Replacer) []replacer.Field {
|
|||
}...)
|
||||
|
||||
if g.suitedMonoRepo {
|
||||
fs := SubServerCodeFields(r.GetOutputDir(), g.moduleName, g.serverName)
|
||||
fs := SubServerCodeFields(g.moduleName, g.serverName)
|
||||
fields = append(fields, fs...)
|
||||
}
|
||||
|
||||
|
|
|
@ -49,7 +49,7 @@ Examples:
|
|||
# generate handler code and specify the server directory, Note: code generation will be canceled when the latest generated file already exists.
|
||||
sponge web handler --db-driver=mysql --db-dsn=root:123456@(192.168.3.37:3306)/test --db-table=user --out=./yourServerDir
|
||||
|
||||
# if you want the generated code to suited to mono-repo, you need to specify the parameter --suited-mono-repo=true --serverName=yourServerName
|
||||
# if you want the generated code to suited to mono-repo, you need to set the parameter --suited-mono-repo=true --server-name=yourServerName
|
||||
`),
|
||||
SilenceErrors: true,
|
||||
SilenceUsage: true,
|
||||
|
@ -146,7 +146,7 @@ type handlerGenerator struct {
|
|||
}
|
||||
|
||||
func (g *handlerGenerator) generateCode() (string, error) {
|
||||
subTplName := "handler"
|
||||
subTplName := codeNameHandler
|
||||
r := Replacers[TplNameSponge]
|
||||
if r == nil {
|
||||
return "", errors.New("replacer is nil")
|
||||
|
@ -284,7 +284,7 @@ func (g *handlerGenerator) addFields(r replacer.Replacer) []replacer.Field {
|
|||
}...)
|
||||
|
||||
if g.suitedMonoRepo {
|
||||
fs := SubServerCodeFields(r.GetOutputDir(), g.moduleName, g.serverName)
|
||||
fs := SubServerCodeFields(g.moduleName, g.serverName)
|
||||
fields = append(fields, fs...)
|
||||
}
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ Examples:
|
|||
# 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
|
||||
|
||||
# if you want the generated code to suited to mono-repo, you need to specify the parameter --suited-mono-repo=true
|
||||
# if you want the generated code to suited to mono-repo, you need to set the parameter --suited-mono-repo=true
|
||||
`),
|
||||
SilenceErrors: true,
|
||||
SilenceUsage: true,
|
||||
|
@ -106,7 +106,7 @@ func (g *httpPbGenerator) generateCode() (string, error) {
|
|||
return "", err
|
||||
}
|
||||
|
||||
subTplName := "http-pb"
|
||||
subTplName := codeNameHTTPPb
|
||||
r := Replacers[TplNameSponge]
|
||||
if r == nil {
|
||||
return "", errors.New("replacer is nil")
|
||||
|
@ -121,9 +121,7 @@ func (g *httpPbGenerator) generateCode() (string, error) {
|
|||
"sponge/.gitignore", "sponge/.golangci.yml", "sponge/go.mod", "sponge/go.sum",
|
||||
"sponge/Jenkinsfile", "sponge/Makefile", "sponge/README.md",
|
||||
}
|
||||
if g.suitedMonoRepo {
|
||||
subFiles = removeElements(subFiles, "sponge/go.mod", "sponge/go.sum")
|
||||
}
|
||||
|
||||
if isImportTypes {
|
||||
subFiles = append(subFiles, "api/types/types.proto")
|
||||
}
|
||||
|
@ -145,8 +143,13 @@ func (g *httpPbGenerator) generateCode() (string, error) {
|
|||
"http.go", "http_test.go", "http_option.go",
|
||||
},
|
||||
}
|
||||
replaceFiles := make(map[string][]string)
|
||||
|
||||
if g.suitedMonoRepo {
|
||||
subDirs = removeElements(subDirs, "sponge/third_party")
|
||||
subFiles = removeElements(subFiles, "sponge/go.mod", "sponge/go.sum", "api/types/types.proto")
|
||||
}
|
||||
|
||||
replaceFiles := make(map[string][]string)
|
||||
subFiles = append(subFiles, getSubFiles(selectFiles, replaceFiles)...)
|
||||
|
||||
// ignore some directories
|
||||
|
@ -161,7 +164,9 @@ func (g *httpPbGenerator) generateCode() (string, error) {
|
|||
return "", err
|
||||
}
|
||||
|
||||
_ = saveProtobufFiles(g.moduleName, g.serverName, r.GetOutputDir(), protobufFiles)
|
||||
if err = saveProtobufFiles(g.moduleName, g.serverName, g.suitedMonoRepo, r.GetOutputDir(), protobufFiles); err != nil {
|
||||
return "", err
|
||||
}
|
||||
_ = saveGenInfo(g.moduleName, g.serverName, g.suitedMonoRepo, r.GetOutputDir())
|
||||
_ = saveEmptySwaggerJSON(r.GetOutputDir())
|
||||
|
||||
|
@ -196,7 +201,8 @@ func (g *httpPbGenerator) addFields(r replacer.Replacer) []replacer.Field {
|
|||
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, wellPrefix+g.serverName)...)
|
||||
fields = append(fields, replaceFileContentMark(r, readmeFile,
|
||||
setReadmeTitle(g.moduleName, g.serverName, codeNameHTTPPb, g.suitedMonoRepo))...)
|
||||
fields = append(fields, []replacer.Field{
|
||||
{ // replace the configuration of the *.yml file
|
||||
Old: appConfigFileMark,
|
||||
|
|
|
@ -55,7 +55,7 @@ Examples:
|
|||
# generate web service code and specify the docker image repository address.
|
||||
sponge web http --module-name=yourModuleName --server-name=yourServerName --project-name=yourProjectName --repo-addr=192.168.3.37:9443/user-name --db-driver=mysql --db-dsn=root:123456@(192.168.3.37:3306)/test --db-table=user
|
||||
|
||||
# if you want the generated code to suited to mono-repo, you need to specify the parameter --suited-mono-repo=true
|
||||
# if you want the generated code to suited to mono-repo, you need to set the parameter --suited-mono-repo=true
|
||||
`),
|
||||
SilenceErrors: true,
|
||||
SilenceUsage: true,
|
||||
|
@ -99,6 +99,7 @@ Examples:
|
|||
codes: codes,
|
||||
outPath: outPath,
|
||||
isExtendedAPI: sqlArgs.IsExtendedAPI,
|
||||
serverType: codeNameHTTP,
|
||||
|
||||
suitedMonoRepo: suitedMonoRepo,
|
||||
}
|
||||
|
@ -182,12 +183,13 @@ type httpGenerator struct {
|
|||
isEmbed bool
|
||||
isExtendedAPI bool
|
||||
suitedMonoRepo bool
|
||||
serverType string
|
||||
|
||||
fields []replacer.Field
|
||||
}
|
||||
|
||||
func (g *httpGenerator) generateCode() (string, error) {
|
||||
subTplName := "http"
|
||||
subTplName := codeNameHTTP
|
||||
r := Replacers[TplNameSponge]
|
||||
if r == nil {
|
||||
return "", errors.New("replacer is nil")
|
||||
|
@ -323,7 +325,8 @@ func (g *httpGenerator) addFields(r replacer.Replacer) []replacer.Field {
|
|||
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, wellPrefix+g.serverName)...)
|
||||
fields = append(fields, replaceFileContentMark(r, readmeFile,
|
||||
setReadmeTitle(g.moduleName, g.serverName, codeNameHTTP, g.suitedMonoRepo))...)
|
||||
fields = append(fields, []replacer.Field{
|
||||
{ // replace the configuration of the *.yml file
|
||||
Old: appConfigFileMark,
|
||||
|
@ -495,7 +498,7 @@ func (g *httpGenerator) addFields(r replacer.Replacer) []replacer.Field {
|
|||
}...)
|
||||
|
||||
if g.suitedMonoRepo {
|
||||
fs := serverCodeFields(r.GetOutputDir(), g.moduleName, g.serverName)
|
||||
fs := serverCodeFields(g.serverType, g.moduleName, g.serverName)
|
||||
fields = append(fields, fs...)
|
||||
}
|
||||
|
||||
|
|
|
@ -97,7 +97,7 @@ type modelGenerator struct {
|
|||
}
|
||||
|
||||
func (g *modelGenerator) generateCode() (string, error) {
|
||||
subTplName := "model"
|
||||
subTplName := codeNameModel
|
||||
r := Replacers[TplNameSponge]
|
||||
if r == nil {
|
||||
return "", errors.New("replacer is nil")
|
||||
|
|
|
@ -128,7 +128,7 @@ type protobufGenerator struct {
|
|||
}
|
||||
|
||||
func (g *protobufGenerator) generateCode() (string, error) {
|
||||
subTplName := "protobuf"
|
||||
subTplName := codeNameProtobuf
|
||||
r := Replacers[TplNameSponge]
|
||||
if r == nil {
|
||||
return "", errors.New("replacer is nil")
|
||||
|
|
|
@ -37,7 +37,7 @@ Examples:
|
|||
# generate grpc connection code and specify the server directory, Note: code generation will be canceled when the latest generated file already exists.
|
||||
sponge micro rpc-conn --rpc-server-name=user --out=./yourServerDir
|
||||
|
||||
# if you want the generated code to suited to mono-repo, you need to specify the parameter --suited-mono-repo=true --serverName=yourServerName
|
||||
# if you want the generated code to suited to mono-repo, you need to set the parameter --suited-mono-repo=true --server-name=yourServerName
|
||||
`),
|
||||
SilenceErrors: true,
|
||||
SilenceUsage: true,
|
||||
|
@ -109,7 +109,7 @@ type grpcConnectionGenerator struct {
|
|||
}
|
||||
|
||||
func (g *grpcConnectionGenerator) generateCode() (string, error) {
|
||||
subTplName := "rpc-conn"
|
||||
subTplName := codeNameGRPCConn
|
||||
r := Replacers[TplNameSponge]
|
||||
if r == nil {
|
||||
return "", errors.New("replacer is nil")
|
||||
|
@ -121,7 +121,7 @@ func (g *grpcConnectionGenerator) generateCode() (string, error) {
|
|||
|
||||
r.SetSubDirsAndFiles(subDirs, subFiles...)
|
||||
_ = r.SetOutputDir(g.outPath, subTplName)
|
||||
fields := g.addFields(r)
|
||||
fields := g.addFields()
|
||||
r.SetReplacementFields(fields)
|
||||
if err := r.SaveFiles(); err != nil {
|
||||
return "", err
|
||||
|
@ -130,7 +130,7 @@ func (g *grpcConnectionGenerator) generateCode() (string, error) {
|
|||
return r.GetOutputDir(), nil
|
||||
}
|
||||
|
||||
func (g *grpcConnectionGenerator) addFields(r replacer.Replacer) []replacer.Field {
|
||||
func (g *grpcConnectionGenerator) addFields() []replacer.Field {
|
||||
var fields []replacer.Field
|
||||
|
||||
fields = append(fields, []replacer.Field{
|
||||
|
@ -150,7 +150,7 @@ func (g *grpcConnectionGenerator) addFields(r replacer.Replacer) []replacer.Fiel
|
|||
}...)
|
||||
|
||||
if g.suitedMonoRepo {
|
||||
fs := SubServerCodeFields(r.GetOutputDir(), g.moduleName, g.serverName)
|
||||
fs := SubServerCodeFields(g.moduleName, g.serverName)
|
||||
fields = append(fields, fs...)
|
||||
}
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ Examples:
|
|||
# generate grpc gateway service code and specify the docker image repository address.
|
||||
sponge micro rpc-gw-pb --module-name=yourModuleName --server-name=yourServerName --project-name=yourProjectName --repo-addr=192.168.3.37:9443/user-name --protobuf-file=./demo.proto
|
||||
|
||||
# if you want the generated code to suited to mono-repo, you need to specify the parameter --suited-mono-repo=true
|
||||
# if you want the generated code to suited to mono-repo, you need to set the parameter --suited-mono-repo=true
|
||||
`),
|
||||
SilenceErrors: true,
|
||||
SilenceUsage: true,
|
||||
|
@ -106,7 +106,7 @@ func (g *rpcGwPbGenerator) generateCode() error {
|
|||
return err
|
||||
}
|
||||
|
||||
subTplName := "rpc-gw-pb"
|
||||
subTplName := codeNameGRPCGW
|
||||
r := Replacers[TplNameSponge]
|
||||
if r == nil {
|
||||
return errors.New("replacer is nil")
|
||||
|
@ -123,9 +123,6 @@ func (g *rpcGwPbGenerator) generateCode() error {
|
|||
"sponge/Jenkinsfile", "sponge/Makefile", "sponge/README.md",
|
||||
}
|
||||
|
||||
if g.suitedMonoRepo {
|
||||
subFiles = removeElements(subFiles, "sponge/go.mod", "sponge/go.sum")
|
||||
}
|
||||
if isImportTypes {
|
||||
subFiles = append(subFiles, "api/types/types.proto")
|
||||
}
|
||||
|
@ -147,8 +144,13 @@ func (g *rpcGwPbGenerator) generateCode() error {
|
|||
"http.go", "http_test.go", "http_option.go",
|
||||
},
|
||||
}
|
||||
replaceFiles := make(map[string][]string)
|
||||
|
||||
if g.suitedMonoRepo {
|
||||
subDirs = removeElements(subDirs, "sponge/third_party")
|
||||
subFiles = removeElements(subFiles, "sponge/go.mod", "sponge/go.sum", "api/types/types.proto")
|
||||
}
|
||||
|
||||
replaceFiles := make(map[string][]string)
|
||||
subFiles = append(subFiles, getSubFiles(selectFiles, replaceFiles)...)
|
||||
|
||||
// ignore some directories
|
||||
|
@ -163,7 +165,9 @@ func (g *rpcGwPbGenerator) generateCode() error {
|
|||
return err
|
||||
}
|
||||
|
||||
_ = saveProtobufFiles(g.moduleName, g.serverName, r.GetOutputDir(), protobufFiles)
|
||||
if err = saveProtobufFiles(g.moduleName, g.serverName, g.suitedMonoRepo, r.GetOutputDir(), protobufFiles); err != nil {
|
||||
return err
|
||||
}
|
||||
_ = saveGenInfo(g.moduleName, g.serverName, g.suitedMonoRepo, r.GetOutputDir())
|
||||
_ = saveEmptySwaggerJSON(r.GetOutputDir())
|
||||
|
||||
|
@ -198,7 +202,8 @@ func (g *rpcGwPbGenerator) addFields(r replacer.Replacer) []replacer.Field {
|
|||
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, wellPrefix+g.serverName)...)
|
||||
fields = append(fields, replaceFileContentMark(r, readmeFile,
|
||||
setReadmeTitle(g.moduleName, g.serverName, codeNameGRPCGW, g.suitedMonoRepo))...)
|
||||
fields = append(fields, []replacer.Field{
|
||||
{ // replace the configuration of the *.yml file
|
||||
Old: appConfigFileMark,
|
||||
|
|
|
@ -39,7 +39,7 @@ Examples:
|
|||
# generate grpc service code and specify the docker image repository address.
|
||||
sponge micro rpc-pb --module-name=yourModuleName --server-name=yourServerName --project-name=yourProjectName --repo-addr=192.168.3.37:9443/user-name --protobuf-file=./demo.proto
|
||||
|
||||
# if you want the generated code to suited to mono-repo, you need to specify the parameter --suited-mono-repo=true
|
||||
# if you want the generated code to suited to mono-repo, you need to set the parameter --suited-mono-repo=true
|
||||
`),
|
||||
SilenceErrors: true,
|
||||
SilenceUsage: true,
|
||||
|
@ -107,7 +107,7 @@ func (g *rpcPbGenerator) generateCode() error {
|
|||
return err
|
||||
}
|
||||
|
||||
subTplName := "rpc-pb"
|
||||
subTplName := codeNameGRPCPb
|
||||
r := Replacers[TplNameSponge]
|
||||
if r == nil {
|
||||
return errors.New("replacer is nil")
|
||||
|
@ -123,9 +123,6 @@ func (g *rpcPbGenerator) generateCode() error {
|
|||
"sponge/Jenkinsfile", "sponge/Makefile", "sponge/README.md",
|
||||
}
|
||||
|
||||
if g.suitedMonoRepo {
|
||||
subFiles = removeElements(subFiles, "sponge/go.mod", "sponge/go.sum")
|
||||
}
|
||||
if isImportTypes {
|
||||
subFiles = append(subFiles, "api/types/types.proto")
|
||||
}
|
||||
|
@ -144,6 +141,12 @@ func (g *rpcPbGenerator) generateCode() error {
|
|||
"service.go", "service_test.go",
|
||||
},
|
||||
}
|
||||
|
||||
if g.suitedMonoRepo {
|
||||
subDirs = removeElements(subDirs, "sponge/third_party")
|
||||
subFiles = removeElements(subFiles, "sponge/go.mod", "sponge/go.sum", "api/types/types.proto")
|
||||
}
|
||||
|
||||
replaceFiles := make(map[string][]string)
|
||||
subFiles = append(subFiles, getSubFiles(selectFiles, replaceFiles)...)
|
||||
|
||||
|
@ -161,7 +164,9 @@ func (g *rpcPbGenerator) generateCode() error {
|
|||
return err
|
||||
}
|
||||
|
||||
_ = saveProtobufFiles(g.moduleName, g.serverName, r.GetOutputDir(), protobufFiles)
|
||||
if err = saveProtobufFiles(g.moduleName, g.serverName, g.suitedMonoRepo, r.GetOutputDir(), protobufFiles); err != nil {
|
||||
return err
|
||||
}
|
||||
_ = saveGenInfo(g.moduleName, g.serverName, g.suitedMonoRepo, r.GetOutputDir())
|
||||
|
||||
fmt.Printf(`
|
||||
|
@ -193,7 +198,8 @@ func (g *rpcPbGenerator) addFields(r replacer.Replacer) []replacer.Field {
|
|||
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, wellPrefix+g.serverName)...)
|
||||
fields = append(fields, replaceFileContentMark(r, readmeFile,
|
||||
setReadmeTitle(g.moduleName, g.serverName, codeNameGRPCPb, g.suitedMonoRepo))...)
|
||||
fields = append(fields, []replacer.Field{
|
||||
{ // replace the configuration of the *.yml file
|
||||
Old: appConfigFileMark,
|
||||
|
|
|
@ -56,7 +56,7 @@ Examples:
|
|||
# generate grpc service code and specify the docker image repository address.
|
||||
sponge micro rpc --module-name=yourModuleName --server-name=yourServerName --project-name=yourProjectName --repo-addr=192.168.3.37:9443/user-name --db-driver=mysql --db-dsn=root:123456@(192.168.3.37:3306)/test --db-table=user
|
||||
|
||||
# if you want the generated code to suited to mono-repo, you need to specify the parameter --suited-mono-repo=true
|
||||
# if you want the generated code to suited to mono-repo, you need to set the parameter --suited-mono-repo=true
|
||||
`),
|
||||
SilenceErrors: true,
|
||||
SilenceUsage: true,
|
||||
|
@ -187,7 +187,7 @@ type rpcGenerator struct {
|
|||
}
|
||||
|
||||
func (g *rpcGenerator) generateCode() (string, error) {
|
||||
subTplName := "rpc"
|
||||
subTplName := codeNameGRPC
|
||||
r := Replacers[TplNameSponge]
|
||||
if r == nil {
|
||||
return "", errors.New("replacer is nil")
|
||||
|
@ -203,10 +203,6 @@ func (g *rpcGenerator) generateCode() (string, error) {
|
|||
"sponge/Jenkinsfile", "sponge/Makefile", "sponge/README.md",
|
||||
}
|
||||
|
||||
if g.suitedMonoRepo {
|
||||
subFiles = removeElements(subFiles, "sponge/go.mod", "sponge/go.sum")
|
||||
}
|
||||
|
||||
selectFiles := map[string][]string{
|
||||
"api/serverNameExample/v1": {
|
||||
"userExample.proto",
|
||||
|
@ -236,8 +232,14 @@ func (g *rpcGenerator) generateCode() (string, error) {
|
|||
"service.go", "service_test.go", "userExample.go", "userExample_client_test.go",
|
||||
},
|
||||
}
|
||||
replaceFiles := make(map[string][]string)
|
||||
|
||||
if g.suitedMonoRepo {
|
||||
subDirs = removeElements(subDirs, "sponge/third_party")
|
||||
subFiles = removeElements(subFiles, "sponge/go.mod", "sponge/go.sum")
|
||||
delete(selectFiles, "api/types")
|
||||
}
|
||||
|
||||
replaceFiles := make(map[string][]string)
|
||||
switch strings.ToLower(g.dbDriver) {
|
||||
case DBDriverMysql, DBDriverPostgresql, DBDriverTidb, DBDriverSqlite:
|
||||
g.fields = append(g.fields, getExpectedSQLForDeletionField(g.isEmbed)...)
|
||||
|
@ -289,6 +291,18 @@ func (g *rpcGenerator) generateCode() (string, error) {
|
|||
if err := r.SaveFiles(); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if g.suitedMonoRepo {
|
||||
if err := moveProtoFileToAPIDir(g.moduleName, g.serverName, g.suitedMonoRepo, r.GetOutputDir()); err != nil {
|
||||
return "", err
|
||||
}
|
||||
//apiDir := g.serverName + gofile.GetPathDelimiter() + "api"
|
||||
//protoFiles, _ := gofile.ListFiles(apiDir, gofile.WithNoAbsolutePath(), gofile.WithSuffix(".proto"))
|
||||
//if err := saveProtobufFiles(g.moduleName, g.serverName, g.suitedMonoRepo, r.GetOutputDir(), protoFiles); err != nil {
|
||||
// return "", err
|
||||
//}
|
||||
//_ = os.RemoveAll(apiDir)
|
||||
}
|
||||
_ = saveGenInfo(g.moduleName, g.serverName, g.suitedMonoRepo, r.GetOutputDir())
|
||||
|
||||
return r.GetOutputDir(), nil
|
||||
|
@ -321,7 +335,8 @@ func (g *rpcGenerator) addFields(r replacer.Replacer) []replacer.Field {
|
|||
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, wellPrefix+g.serverName)...)
|
||||
fields = append(fields, replaceFileContentMark(r, readmeFile,
|
||||
setReadmeTitle(g.moduleName, g.serverName, codeNameGRPC, g.suitedMonoRepo))...)
|
||||
fields = append(fields, []replacer.Field{
|
||||
{ // replace the configuration of the *.yml file
|
||||
Old: appConfigFileMark,
|
||||
|
@ -343,7 +358,7 @@ func (g *rpcGenerator) addFields(r replacer.Replacer) []replacer.Field {
|
|||
Old: daoFileMark,
|
||||
New: g.codes[parser.CodeTypeDAO],
|
||||
},
|
||||
{ // replace the contents of the handler/userExample_logic.go file
|
||||
{ // replace the contents of the service/userExample.go file
|
||||
Old: embedTimeMark,
|
||||
New: getEmbedTimeCode(g.isEmbed),
|
||||
},
|
||||
|
|
|
@ -51,7 +51,7 @@ Examples:
|
|||
# generate service and handler code and specify the server directory, Note: code generation will be canceled when the latest generated file already exists.
|
||||
sponge micro service-handler --db-driver=mysql --db-dsn=root:123456@(192.168.3.37:3306)/test --db-table=user --out=./yourServerDir
|
||||
|
||||
# if you want the generated code to suited to mono-repo, you need to specify the parameter --suited-mono-repo=true
|
||||
# if you want the generated code to suited to mono-repo, you need to set the parameter --suited-mono-repo=true
|
||||
`),
|
||||
SilenceErrors: true,
|
||||
SilenceUsage: true,
|
||||
|
@ -152,7 +152,7 @@ type serviceAndHandlerGenerator struct {
|
|||
|
||||
// nolint
|
||||
func (g *serviceAndHandlerGenerator) generateCode() (string, error) {
|
||||
subTplName := "service-handler"
|
||||
subTplName := codeNameServiceHTTP
|
||||
r := Replacers[TplNameSponge]
|
||||
if r == nil {
|
||||
return "", errors.New("replacer is nil")
|
||||
|
@ -231,6 +231,12 @@ func (g *serviceAndHandlerGenerator) generateCode() (string, error) {
|
|||
return "", err
|
||||
}
|
||||
|
||||
if g.suitedMonoRepo {
|
||||
if err := moveProtoFileToAPIDir(g.moduleName, g.serverName, g.suitedMonoRepo, r.GetOutputDir()); err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
|
||||
return r.GetOutputDir(), nil
|
||||
}
|
||||
|
||||
|
@ -338,7 +344,7 @@ func (g *serviceAndHandlerGenerator) addFields(r replacer.Replacer) []replacer.F
|
|||
}...)
|
||||
|
||||
if g.suitedMonoRepo {
|
||||
fs := SubServerCodeFields(r.GetOutputDir(), g.moduleName, g.serverName)
|
||||
fs := SubServerCodeFields(g.moduleName, g.serverName)
|
||||
fields = append(fields, fs...)
|
||||
}
|
||||
|
||||
|
|
|
@ -50,7 +50,7 @@ Examples:
|
|||
# generate service code and specify the server directory, Note: code generation will be canceled when the latest generated file already exists.
|
||||
sponge micro service --db-driver=mysql --db-dsn=root:123456@(192.168.3.37:3306)/test --db-table=user --out=./yourServerDir
|
||||
|
||||
# if you want the generated code to suited to mono-repo, you need to specify the parameter --suited-mono-repo=true
|
||||
# if you want the generated code to suited to mono-repo, you need to set the parameter --suited-mono-repo=true
|
||||
`),
|
||||
SilenceErrors: true,
|
||||
SilenceUsage: true,
|
||||
|
@ -150,7 +150,7 @@ type serviceGenerator struct {
|
|||
|
||||
// nolint
|
||||
func (g *serviceGenerator) generateCode() (string, error) {
|
||||
subTplName := "service"
|
||||
subTplName := codeNameService
|
||||
r := Replacers[TplNameSponge]
|
||||
if r == nil {
|
||||
return "", errors.New("replacer is nil")
|
||||
|
@ -229,6 +229,12 @@ func (g *serviceGenerator) generateCode() (string, error) {
|
|||
return "", err
|
||||
}
|
||||
|
||||
if g.suitedMonoRepo {
|
||||
if err := moveProtoFileToAPIDir(g.moduleName, g.serverName, g.suitedMonoRepo, r.GetOutputDir()); err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
|
||||
return r.GetOutputDir(), nil
|
||||
}
|
||||
|
||||
|
@ -315,7 +321,7 @@ func (g *serviceGenerator) addFields(r replacer.Replacer) []replacer.Field {
|
|||
}...)
|
||||
|
||||
if g.suitedMonoRepo {
|
||||
fs := SubServerCodeFields(r.GetOutputDir(), g.moduleName, g.serverName)
|
||||
fs := SubServerCodeFields(g.moduleName, g.serverName)
|
||||
fields = append(fields, fs...)
|
||||
}
|
||||
|
||||
|
|
|
@ -267,13 +267,8 @@ func NewCenter(configFile string) (*Center, error) {
|
|||
sponge merge rpc-pb
|
||||
checkResult $?
|
||||
|
||||
colorCyan='\033[1;36m'
|
||||
highBright='\033[1m'
|
||||
markEnd='\033[0m'
|
||||
|
||||
echo ""
|
||||
echo -e "${highBright}Tip:${markEnd} execute the command ${colorCyan}make run${markEnd} and then test grpc api in the file ${colorCyan}internal/service/xxx_client_test.go${markEnd}."
|
||||
echo ""`
|
||||
tipMsg="${highBright}Tip:${markEnd} execute the command ${colorCyan}make run${markEnd} and then test grpc api in the file ${colorCyan}internal/service/xxx_client_test.go${markEnd}."
|
||||
`
|
||||
|
||||
// for http-pb
|
||||
protoShellHandlerCode = `
|
||||
|
@ -301,13 +296,8 @@ func NewCenter(configFile string) (*Center, error) {
|
|||
sponge merge http-pb
|
||||
checkResult $?
|
||||
|
||||
colorCyan='\033[1;36m'
|
||||
highBright='\033[1m'
|
||||
markEnd='\033[0m'
|
||||
|
||||
echo ""
|
||||
echo -e "${highBright}Tip:${markEnd} execute the command ${colorCyan}make run${markEnd} and then visit ${colorCyan}http://localhost:8080/apis/swagger/index.html${markEnd} in your browser. "
|
||||
echo ""`
|
||||
tipMsg="${highBright}Tip:${markEnd} execute the command ${colorCyan}make run${markEnd} and then visit ${colorCyan}http://localhost:8080/apis/swagger/index.html${markEnd} in your browser. "
|
||||
`
|
||||
|
||||
// for rpc-gw
|
||||
protoShellServiceCode = `
|
||||
|
@ -335,15 +325,10 @@ func NewCenter(configFile string) (*Center, error) {
|
|||
sponge merge rpc-gw-pb
|
||||
checkResult $?
|
||||
|
||||
colorCyan='\033[1;36m'
|
||||
highBright='\033[1m'
|
||||
markEnd='\033[0m'
|
||||
tipMsg="${highBright}Tip:${markEnd} execute the command ${colorCyan}make run${markEnd} and then visit ${colorCyan}http://localhost:8080/apis/swagger/index.html${markEnd} in your browser."
|
||||
`
|
||||
|
||||
echo ""
|
||||
echo -e "${highBright}Tip:${markEnd} execute the command ${colorCyan}make run${markEnd} and then visit ${colorCyan}http://localhost:8080/apis/swagger/index.html${markEnd} in your browser."
|
||||
echo ""`
|
||||
|
||||
// for grpc-http
|
||||
//nolint for grpc-http
|
||||
protoShellServiceAndHandlerCode = `
|
||||
# generate the swagger document and merge all files into docs/apis.swagger.json
|
||||
protoc --proto_path=. --proto_path=./third_party \
|
||||
|
@ -379,15 +364,8 @@ func NewCenter(configFile string) (*Center, error) {
|
|||
sponge merge http-pb
|
||||
checkResult $?
|
||||
|
||||
colorCyan='\033[1;36m'
|
||||
highBright='\033[1m'
|
||||
markEnd='\033[0m'
|
||||
|
||||
echo ""
|
||||
echo -e "${highBright}Tip:${markEnd} execute the command ${colorCyan}make run${markEnd} and then"
|
||||
echo -e " 1. test http api in your browser ${colorCyan}http://localhost:8080/apis/swagger/index.html${markEnd}"
|
||||
echo -e " 2. test grpc api in the file ${colorCyan}internal/service/xxx_client_test.go${markEnd}"
|
||||
echo ""`
|
||||
tipMsg="${highBright}Tip:${markEnd} execute the command ${colorCyan}make run${markEnd} and then\n 1. test http api in your browser ${colorCyan}http://localhost:8080/apis/swagger/index.html${markEnd}\n 2. test grpc api in the file ${colorCyan}internal/service/xxx_client_test.go${markEnd}"
|
||||
`
|
||||
|
||||
httpServerConfigCode = `# http server settings
|
||||
http:
|
||||
|
|
|
@ -0,0 +1,125 @@
|
|||
## English | [简体中文](readme-cn.md)
|
||||
|
||||
## Merge Command
|
||||
|
||||
The merge command is used to automatically merge the generated code into existing template files without affecting the existing business logic code. If any issues occur during the merging process, a backup of the code before merging will be saved in the `/tmp/sponge_merge_backup_code` directory, allowing you to restore the previous state of your code.
|
||||
|
||||
Manual merging of code is required when automatic merging fails due to changes in the number of services in the proto file.
|
||||
|
||||
<br>
|
||||
|
||||
### Manual Code Merging Instructions
|
||||
|
||||
In most cases, a proto file typically defines a single service. However, during development, the number of services in a proto file might change, such as increasing from one service to multiple services or decreasing from multiple services to one. Such changes may cause automatic merging to fail, necessitating manual code merging.
|
||||
|
||||
#### Manual Merging When Adding a Service
|
||||
|
||||
Let's take `greeter.proto` as an example, where the initial file contains a single service named `Foobar1`. The content of the file is as follows:
|
||||
|
||||
```protobuf
|
||||
syntax = "proto3";
|
||||
|
||||
package greeter;
|
||||
|
||||
option go_package = "greeter";
|
||||
|
||||
service Foobar1 {
|
||||
rpc SayHello (HelloRequest) returns (HelloReply) {}
|
||||
}
|
||||
|
||||
message HelloRequest {
|
||||
string name = 1;
|
||||
}
|
||||
|
||||
message HelloReply {
|
||||
string message = 1;
|
||||
}
|
||||
```
|
||||
|
||||
When there is only one service, the automatic code merge usually works fine without manual intervention.
|
||||
|
||||
Suppose you need to add a new service named `Foobar2` to `greeter.proto`. The updated file content is as follows:
|
||||
|
||||
```protobuf
|
||||
syntax = "proto3";
|
||||
|
||||
package greeter;
|
||||
|
||||
option go_package = "greeter";
|
||||
|
||||
service Foobar1 {
|
||||
rpc SayHello (SayHelloRequest) returns (SayHelloReply) {}
|
||||
}
|
||||
|
||||
message SayHelloRequest {
|
||||
string name = 1;
|
||||
}
|
||||
|
||||
message SayHelloReply {
|
||||
string message = 1;
|
||||
}
|
||||
|
||||
service Foobar2 {
|
||||
rpc SayHello (SayHelloRequest) returns (SayHelloReply) {}
|
||||
}
|
||||
```
|
||||
|
||||
After adding a new service to the proto file, the automatic code merge may fail, requiring manual code merging. The steps for manual merging are as follows:
|
||||
|
||||
1. Based on the error message, locate the generated code file (with a suffix format of `.go.gen<timestamp>`) and open the file.
|
||||
|
||||
2. Find the Go code block corresponding to the `Foobar2` service and copy it into the target Go file (the one with the same prefix as the `.go.gen<timestamp>` file).
|
||||
|
||||
3. The Go file after copying must meet the following requirements:
|
||||
- The number of service code blocks in the Go file must match the number of services in the proto file, and their order must be consistent.
|
||||
- The service code blocks in the Go file must be separated by a fixed marker: `// ---------- Do not delete or move this split line, this is the merge code marker ----------`.
|
||||
- If the proto file contains only one service, the service code block in the Go file does not need a separator.
|
||||
|
||||
By manually merging the code, the automatic merging feature will work correctly if the number of services in the proto file remains unchanged in the future.
|
||||
|
||||
<br>
|
||||
|
||||
#### Manual Merging When Removing a Service
|
||||
|
||||
Continuing with the `greeter.proto` example, the file currently contains two services: `Foobar1` and `Foobar2`. In this case, automatic code merging usually works fine without manual intervention.
|
||||
|
||||
Suppose you need to remove `Foobar2`, and the updated `greeter.proto` file is as follows:
|
||||
|
||||
```protobuf
|
||||
syntax = "proto3";
|
||||
|
||||
package greeter;
|
||||
|
||||
option go_package = "greeter";
|
||||
|
||||
service Foobar1 {
|
||||
rpc SayHello (SayHelloRequest) returns (SayHelloReply) {}
|
||||
}
|
||||
|
||||
message SayHelloRequest {
|
||||
string name = 1;
|
||||
}
|
||||
|
||||
message SayHelloReply {
|
||||
string message = 1;
|
||||
}
|
||||
```
|
||||
|
||||
At this point, automatic code merging may fail, requiring manual code merging. The steps for manual merging are as follows:
|
||||
|
||||
1. Based on the error message, open the generated code file (also with a `.go.gen<timestamp>` suffix format).
|
||||
|
||||
2. Locate the Go code block corresponding to `Foobar2` and delete this code block.
|
||||
|
||||
3. After manual adjustment, the Go file must meet the following requirements:
|
||||
- The number of service code blocks in the Go file must match the number of services in the proto file, and their order must be consistent.
|
||||
- The service code blocks in the Go file must be separated by a fixed marker: `// ---------- Do not delete or move this split line, this is the merge code marker ----------`.
|
||||
- If the proto file contains only one service, the service code block in the Go file does not need a separator.
|
||||
|
||||
After manual adjustments are complete, the automatic merging feature will work correctly if the number of services in the proto file remains unchanged in the future.
|
||||
|
||||
<br>
|
||||
|
||||
### Warning
|
||||
|
||||
If multiple services are included in a proto file, once the code is generated, do not adjust the order of the services in the proto file, otherwise it will cause confusion in the automatic merging code, and manual adjustment of the code is required.
|
|
@ -11,9 +11,13 @@ import (
|
|||
"path"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/fatih/color"
|
||||
|
||||
"github.com/zhufuyi/sponge/pkg/gobash"
|
||||
"github.com/zhufuyi/sponge/pkg/gofile"
|
||||
)
|
||||
|
@ -64,6 +68,7 @@ func (m *mergeParam) SetSplitLineMark(lineMark string) {
|
|||
|
||||
func (m *mergeParam) runMerge() {
|
||||
files := gofile.FuzzyMatchFiles(m.dir + "/" + m.fuzzyFilename)
|
||||
files = filterAndRemoveOldFiles(files)
|
||||
for _, file := range files {
|
||||
successFile, err := m.runMergeCode(file)
|
||||
if err != nil {
|
||||
|
@ -106,13 +111,10 @@ func (m *mergeParam) runMergeCode(file string) (string, error) {
|
|||
|
||||
count1 := bytes.Count(data1, m.splitLineMark)
|
||||
count2 := bytes.Count(data2, m.splitLineMark)
|
||||
//if count2 > count1 {
|
||||
// // 判断新增加的service,把新的service代码合并到原来的文件中
|
||||
//} else if count2 < count1 {
|
||||
//
|
||||
//}
|
||||
if count1 != count2 {
|
||||
return "", fmt.Errorf("merge code mark mismatch, please merge codes manually, file = %s", file)
|
||||
return "", fmt.Errorf(color.RedString("merge code failed (%s --> %s), manually merge code"+
|
||||
" reference document https://github.com/zhufuyi/sponge/tree/main/cmd/sponge/commands/merge",
|
||||
cutPathPrefix(file), getTargetFilename(file)))
|
||||
}
|
||||
|
||||
var data []byte
|
||||
|
@ -133,7 +135,9 @@ func (m *mergeParam) runMergeCode(file string) (string, error) {
|
|||
}
|
||||
|
||||
if len(data1) > len(data) {
|
||||
return "", fmt.Errorf("to avoid replacing logical code, please merge codes manually, file = %s", file)
|
||||
return "", fmt.Errorf(color.RedString("merge code failed (%s --> %s), to avoid replacing logical code, "+
|
||||
"manually merge code reference document https://github.com/zhufuyi/sponge/tree/main/cmd/sponge/commands/merge",
|
||||
cutPathPrefix(file), getTargetFilename(file)))
|
||||
}
|
||||
|
||||
if len(data1) == len(data) {
|
||||
|
@ -175,8 +179,8 @@ func getOldFile(file string) string {
|
|||
}
|
||||
|
||||
func compareCode(oldCode []code, newCode []code) ([]byte, []byte) {
|
||||
var addCode []byte
|
||||
var position []byte
|
||||
var addCode []string
|
||||
var position string
|
||||
|
||||
for _, code1 := range newCode {
|
||||
isEqual := false
|
||||
|
@ -187,14 +191,18 @@ func compareCode(oldCode []code, newCode []code) ([]byte, []byte) {
|
|||
}
|
||||
}
|
||||
if !isEqual {
|
||||
addCode = append(addCode, []byte(code1.value)...)
|
||||
addCode = append(addCode, code1.value)
|
||||
}
|
||||
}
|
||||
if len(oldCode) > 0 {
|
||||
position = []byte(oldCode[len(oldCode)-1].value) // last position
|
||||
|
||||
l := len(oldCode)
|
||||
if l > 0 {
|
||||
position = oldCode[l-1].value // last position
|
||||
}
|
||||
|
||||
return addCode, position
|
||||
addData := checkAndAdjustErrorCode(addCode, position, l)
|
||||
|
||||
return addData, []byte(position)
|
||||
}
|
||||
|
||||
func compareCode2(oldCode []code, newCode []code, data []byte) ([]byte, []byte) {
|
||||
|
@ -239,8 +247,6 @@ func mergeCode(oldCode []byte, addCode []byte, position []byte) []byte {
|
|||
if len(ss) != 2 {
|
||||
return oldCode
|
||||
}
|
||||
fmt.Println("------ position = ", string(position))
|
||||
fmt.Println("------ addCode = ", string(addCode))
|
||||
data = append(ss[0], position...)
|
||||
data = append(data, addCode...)
|
||||
data = append(data, ss[1]...)
|
||||
|
@ -366,6 +372,8 @@ func getComment(name string, str string) string {
|
|||
return strings.ReplaceAll(match[0], "\nfunc", "")
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------
|
||||
|
||||
func adaptDir(dir string) string {
|
||||
if dir == "." || dir == "./" || dir == ".\\" {
|
||||
return ""
|
||||
|
@ -380,6 +388,124 @@ func adaptDir(dir string) string {
|
|||
return dir + "/"
|
||||
}
|
||||
|
||||
func cutPathPrefix(srcFile string) string {
|
||||
dirPath, _ := filepath.Abs(".")
|
||||
return strings.ReplaceAll(srcFile, dirPath+gofile.GetPathDelimiter(), "")
|
||||
}
|
||||
|
||||
func getTargetFilename(file string) string {
|
||||
filename := gofile.GetFilename(file)
|
||||
ss := strings.Split(filename, ".go.gen")
|
||||
if len(ss) != 2 {
|
||||
return file
|
||||
}
|
||||
return ss[0] + ".go"
|
||||
}
|
||||
|
||||
func filterAndRemoveOldFiles(files []string) []string {
|
||||
if len(files) < 2 {
|
||||
return files
|
||||
}
|
||||
|
||||
var groupFiles = make(map[string][]string)
|
||||
for _, file := range files {
|
||||
filePrefix := strings.Split(file, ".go.gen")
|
||||
if len(filePrefix) != 2 {
|
||||
continue
|
||||
}
|
||||
if _, ok := groupFiles[filePrefix[0]]; !ok {
|
||||
groupFiles[filePrefix[0]] = []string{file}
|
||||
} else {
|
||||
groupFiles[filePrefix[0]] = append(groupFiles[filePrefix[0]], file)
|
||||
}
|
||||
}
|
||||
|
||||
var newFiles, removeFiles []string
|
||||
for _, fs := range groupFiles {
|
||||
l := len(fs)
|
||||
if l == 1 {
|
||||
newFiles = append(newFiles, fs[0])
|
||||
} else if l > 1 {
|
||||
sort.Strings(fs)
|
||||
newFiles = append(newFiles, fs[l-1])
|
||||
removeFiles = append(removeFiles, fs[:l-1]...)
|
||||
}
|
||||
}
|
||||
|
||||
// remove old files
|
||||
for _, file := range removeFiles {
|
||||
_ = os.Remove(file)
|
||||
}
|
||||
|
||||
return newFiles
|
||||
}
|
||||
|
||||
var (
|
||||
errCodeStrMark1 = "errcode.NewError("
|
||||
errCodeStrMark2 = "errcode.NewRPCStatus("
|
||||
)
|
||||
|
||||
func checkAndGetErrorCodeStr(str string) string {
|
||||
if !strings.Contains(str, errCodeStrMark1) && !strings.Contains(str, errCodeStrMark2) {
|
||||
return ""
|
||||
}
|
||||
|
||||
// match strings between left parentheses and commas using regular expressions
|
||||
// string format: ErrLoginUser = errcode.NewError(userBaseCode+2, "failed to Login "+userName)
|
||||
pattern := `\(([^)]+?),`
|
||||
re := regexp.MustCompile(pattern)
|
||||
|
||||
match := re.FindStringSubmatch(str)
|
||||
if len(match) < 2 {
|
||||
return ""
|
||||
}
|
||||
|
||||
return match[1]
|
||||
}
|
||||
|
||||
func parseErrorCode(str string) (string, int) {
|
||||
ss := strings.Split(str, "+")
|
||||
if len(ss) != 2 {
|
||||
return "", 0
|
||||
}
|
||||
num, _ := strconv.Atoi(strings.TrimSpace(ss[1]))
|
||||
return ss[0], num
|
||||
}
|
||||
|
||||
func checkAndAdjustErrorCode(addCode []string, position string, l int) []byte {
|
||||
data := []byte(strings.Join(addCode, ""))
|
||||
|
||||
str := checkAndGetErrorCodeStr(position)
|
||||
if str == "" {
|
||||
return data
|
||||
}
|
||||
referenceStr, maxNum := parseErrorCode(str)
|
||||
if referenceStr == "" || maxNum == 0 {
|
||||
return data
|
||||
}
|
||||
if maxNum < l {
|
||||
maxNum = l
|
||||
}
|
||||
|
||||
// adjust error code
|
||||
var newCode []byte
|
||||
for _, line := range addCode {
|
||||
codeStr := checkAndGetErrorCodeStr(line)
|
||||
if codeStr == "" {
|
||||
return data
|
||||
}
|
||||
baseStr, num := parseErrorCode(codeStr)
|
||||
if baseStr == "" || num == 0 {
|
||||
return data
|
||||
}
|
||||
maxNum++
|
||||
newLine := strings.ReplaceAll(line, codeStr, fmt.Sprintf("%s+%d", referenceStr, maxNum))
|
||||
newCode = append(newCode, []byte(newLine)...)
|
||||
}
|
||||
|
||||
return newCode
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------
|
||||
|
||||
func mergeHTTPECode(dir string) {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package merge
|
||||
|
||||
import (
|
||||
"github.com/fatih/color"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
|
@ -11,11 +12,15 @@ func GinHandlerCode() *cobra.Command {
|
|||
cmd := &cobra.Command{
|
||||
Use: "http-pb",
|
||||
Short: "Merge the generated http related code into the template file",
|
||||
Long: `merge the generated http related code into the template file.
|
||||
Long: color.HiBlackString(`merge the generated http related code into the template file.
|
||||
|
||||
Examples:
|
||||
# merge go template file in local server directory
|
||||
sponge merge http-pb
|
||||
`,
|
||||
|
||||
# merge go template file in specified directory
|
||||
sponge merge http-pb --dir=/path/to/server/directory
|
||||
`),
|
||||
SilenceErrors: true,
|
||||
SilenceUsage: true,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
|
|
|
@ -0,0 +1,123 @@
|
|||
## 合并命令
|
||||
|
||||
合并命令用于将生成的代码自动合并到已有的模板文件中,无需担心影响已编写的业务逻辑代码。如果合并过程中出现意外,合并前的代码备份会保存在 `/tmp/sponge_merge_backup_code` 目录中,您可以从中恢复之前的代码状态。
|
||||
|
||||
当自动合并代码出错时(proto文件中service数量变化导致),需要手动合并代码。
|
||||
|
||||
<br>
|
||||
|
||||
### 手动合并代码说明
|
||||
|
||||
在大多数情况下,一个 proto 文件通常定义一个 service。但在开发过程中,proto 文件中的 service 数量可能会有所变化,例如从一个 service 增加到多个,或者从多个 service 减少为一个。这种变化可能导致自动合并代码失败,此时就需要手动进行代码合并。
|
||||
|
||||
#### 增加 Service 时的手动合并
|
||||
|
||||
以下以 `greeter.proto` 为例,初始文件中只有一个 service,名为 `Foobar1`。文件内容如下:
|
||||
|
||||
```protobuf
|
||||
syntax = "proto3";
|
||||
|
||||
package greeter;
|
||||
|
||||
option go_package = "greeter";
|
||||
|
||||
service Foobar1 {
|
||||
rpc SayHello (HelloRequest) returns (HelloReply) {}
|
||||
}
|
||||
|
||||
message HelloRequest {
|
||||
string name = 1;
|
||||
}
|
||||
|
||||
message HelloReply {
|
||||
string message = 1;
|
||||
}
|
||||
```
|
||||
|
||||
在只有一个 service 的情况下,自动合并代码通常能正常工作,无需手动干预。
|
||||
|
||||
假设现在需要在 `greeter.proto` 中增加一个名为 `Foobar2` 的 service,更新后的文件内容如下:
|
||||
|
||||
```protobuf
|
||||
syntax = "proto3";
|
||||
|
||||
package greeter;
|
||||
|
||||
option go_package = "greeter";
|
||||
|
||||
service Foobar1 {
|
||||
rpc SayHello (SayHelloRequest) returns (SayHelloReply) {}
|
||||
}
|
||||
|
||||
message SayHelloRequest {
|
||||
string name = 1;
|
||||
}
|
||||
|
||||
message SayHelloReply {
|
||||
string message = 1;
|
||||
}
|
||||
|
||||
service Foobar2 {
|
||||
rpc SayHello (SayHelloRequest) returns (SayHelloReply) {}
|
||||
}
|
||||
```
|
||||
|
||||
当 proto 文件中新增 service 后,自动合并代码会导致失败,此时需要手动合并代码。手动合并的步骤如下:
|
||||
|
||||
1. 根据错误提示,找到生成的代码文件(文件后缀格式为 `.go.gen<日期时间>`),打开文件。
|
||||
|
||||
2. 找到 service `Foobar2` 对应的 Go 代码块,将其复制到目标 Go 文件中(即与 `.go.gen<日期时间>`文件相同的前缀go文件)。
|
||||
|
||||
3. 复制后的 Go 文件需符合以下要求:
|
||||
- Go文件的 service 代码块数量与 proto 文件的 service 一样,并且顺序必须一致。
|
||||
- Go文件的 service 代码块必须有固定的分割标记:`// ---------- Do not delete or move this split line, this is the merge code marker ----------`。
|
||||
- 当 proto 文件中仅剩一个 service 时,Go文件的 service 代码块不需要分割标记。
|
||||
|
||||
通过手动合并代码,后续如果 proto 文件中 service 数量不变化,自动合并功能都可以正常工作。
|
||||
|
||||
<br>
|
||||
|
||||
#### 减少 Service 时的手动合并
|
||||
|
||||
继续以 `greeter.proto` 为例,此时文件中包含两个 service:`Foobar1` 和 `Foobar2`。在这种情况下,自动合并代码通常能正常运行,无需手动干预。
|
||||
|
||||
假设现在需要删除 `Foobar2`,更新后的 `greeter.proto` 文件内容如下:
|
||||
|
||||
```protobuf
|
||||
syntax = "proto3";
|
||||
|
||||
package greeter;
|
||||
|
||||
option go_package = "greeter";
|
||||
|
||||
service Foobar1 {
|
||||
rpc SayHello (SayHelloRequest) returns (SayHelloReply) {}
|
||||
}
|
||||
|
||||
message SayHelloRequest {
|
||||
string name = 1;
|
||||
}
|
||||
|
||||
message SayHelloReply {
|
||||
string message = 1;
|
||||
}
|
||||
```
|
||||
|
||||
此时,自动合并代码会导致失败,需手动合并代码。手动合并的步骤如下:
|
||||
|
||||
1. 根据错误提示,打开生成的代码文件(同样为 `.go.gen<时间戳>` 格式)。
|
||||
|
||||
2. 找到与 `Foobar2` 对应的 Go 代码块,删除该代码块。
|
||||
|
||||
3. 手动调整后go文件需满足以下要求:
|
||||
- Go文件的 service 代码块数量与 proto 文件的 service 一样,并且顺序必须一致。
|
||||
- Go文件的 service 代码块必须有固定的分割标记:`// ---------- Do not delete or move this split line, this is the merge code marker ----------`。
|
||||
- 当 proto 文件中仅剩一个 service 时,Go文件的 service 代码块不需要分割标记。
|
||||
|
||||
手动调整完成后,后续如果 proto 文件中 service 数量不变化,自动合并功能都可以正常工作。
|
||||
|
||||
<br>
|
||||
|
||||
### 警告
|
||||
|
||||
如果在一个 proto 文件中包含多个service, 一旦生成代码之后,不要调整proto文件中的service的顺序,否则会导致自动合并代码混乱,此时只能手动调整合并后的代码。
|
|
@ -1,6 +1,7 @@
|
|||
package merge
|
||||
|
||||
import (
|
||||
"github.com/fatih/color"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
|
@ -11,12 +12,15 @@ func GinServiceCode() *cobra.Command {
|
|||
cmd := &cobra.Command{
|
||||
Use: "rpc-gw-pb",
|
||||
Short: "Merge the generated grpc gateway related code into the template file",
|
||||
Long: `merge the generated grpc gateway related code into the template file.
|
||||
Long: color.HiBlackString(`merge the generated grpc gateway related code into the template file.
|
||||
|
||||
Examples:
|
||||
# merge go template file in local server directory
|
||||
sponge merge rpc-gw-pb
|
||||
sponge merge rpc-gw-pb --dir=yourServerDir
|
||||
`,
|
||||
|
||||
# merge go template file in specified server directory
|
||||
sponge merge rpc-gw-pb --dir=/path/to/server/directory
|
||||
`),
|
||||
SilenceErrors: true,
|
||||
SilenceUsage: true,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package merge
|
||||
|
||||
import (
|
||||
"github.com/fatih/color"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
|
@ -11,11 +12,15 @@ func GRPCServiceCode() *cobra.Command {
|
|||
cmd := &cobra.Command{
|
||||
Use: "rpc-pb",
|
||||
Short: "Merge the generated grpc related code into the template file",
|
||||
Long: `merge the generated grpc related code into the template file.
|
||||
Long: color.HiBlackString(`merge the generated grpc related code into the template file.
|
||||
|
||||
Examples:
|
||||
# merge go template file in local server directory
|
||||
sponge merge rpc-pb
|
||||
`,
|
||||
|
||||
# merge go template file in specified directory
|
||||
sponge merge rpc-pb --dir=/path/to/server/directory
|
||||
`),
|
||||
SilenceErrors: true,
|
||||
SilenceUsage: true,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
|
|
|
@ -22,10 +22,11 @@ func PatchCommand() *cobra.Command {
|
|||
patch.GenMysqlInitCommand(),
|
||||
patch.GenTypesPbCommand(),
|
||||
patch.CopyProtoCommand(),
|
||||
patch.CopyThirdPartyProtoCommand(),
|
||||
patch.CopyGOModCommand(),
|
||||
patch.ModifyDuplicateNumCommand(),
|
||||
patch.ModifyDuplicateErrCodeCommand(),
|
||||
patch.AdaptMonoRepoCommand(),
|
||||
patch.AddSpecialTypesCommand(),
|
||||
patch.ModifyProtoPackageCommand(),
|
||||
)
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/fatih/color"
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"github.com/zhufuyi/sponge/pkg/gofile"
|
||||
|
@ -22,13 +23,15 @@ func AdaptMonoRepoCommand() *cobra.Command {
|
|||
cmd := &cobra.Command{
|
||||
Use: "adapt-mono-repo",
|
||||
Short: "Adapt to mono-repo in api directory code",
|
||||
Long: `adapt to mono-repo in api directory code
|
||||
Long: color.HiBlackString(`adapt to mono-repo in api directory code
|
||||
|
||||
Examples:
|
||||
# adapt to mono-repo code
|
||||
# adapt to mono-repo code in local server directory
|
||||
sponge patch adapt-mono-repo
|
||||
|
||||
`,
|
||||
# adapt to mono-repo code in specified directory
|
||||
sponge patch adapt-mono-repo --dir=/path/to/server/directory
|
||||
`),
|
||||
SilenceErrors: true,
|
||||
SilenceUsage: true,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
|
@ -49,8 +52,8 @@ Examples:
|
|||
return err
|
||||
}
|
||||
|
||||
var oldStr = fmt.Sprintf("\"%s/api", moduleName)
|
||||
var newStr = fmt.Sprintf("\"%s/api", moduleName+"/"+serverName)
|
||||
var oldStr = fmt.Sprintf("\"%s/api", moduleName+"/"+serverName)
|
||||
var newStr = fmt.Sprintf("\"%s/api", moduleName)
|
||||
for _, file := range files {
|
||||
data, err := os.ReadFile(file)
|
||||
if err != nil {
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
package patch
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/zhufuyi/sponge/pkg/gofile"
|
||||
)
|
||||
|
||||
// get moduleName and serverName from directory
|
||||
|
@ -37,3 +40,26 @@ func cutPathPrefix(srcProtoFile string) string {
|
|||
srcProtoFile = strings.ReplaceAll(srcProtoFile, dirPath, ".")
|
||||
return strings.ReplaceAll(srcProtoFile, "\\", "/")
|
||||
}
|
||||
|
||||
func listErrCodeFiles(dir string) ([]string, error) {
|
||||
files, err := gofile.ListFiles(dir)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(files) == 0 {
|
||||
return nil, errors.New("not found files")
|
||||
}
|
||||
|
||||
filterFiles := []string{}
|
||||
for _, file := range files {
|
||||
if strings.Contains(file, "systemCode_http.go") || strings.Contains(file, "systemCode_rpc.go") {
|
||||
continue
|
||||
}
|
||||
if strings.Contains(file, "_http.go") || strings.Contains(file, "_rpc.go") {
|
||||
filterFiles = append(filterFiles, file)
|
||||
}
|
||||
}
|
||||
|
||||
return filterFiles, nil
|
||||
}
|
||||
|
|
|
@ -0,0 +1,86 @@
|
|||
package patch
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/fatih/color"
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"github.com/zhufuyi/sponge/cmd/sponge/commands/generate"
|
||||
"github.com/zhufuyi/sponge/pkg/gofile"
|
||||
)
|
||||
|
||||
// CopyGOModCommand copy go mod files
|
||||
func CopyGOModCommand() *cobra.Command {
|
||||
var (
|
||||
moduleName string // module name for go.mod
|
||||
outPath string // output directory
|
||||
isLogExist bool
|
||||
)
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "copy-go-mod",
|
||||
Short: "Copy go mod files",
|
||||
Long: color.HiBlackString(`copy go mod files to local directory.
|
||||
|
||||
Examples:
|
||||
# copy go mod files to current directory
|
||||
sponge patch copy-go-mod --module-name=yourModuleName
|
||||
|
||||
# copy go mod files to yourServerDir, module name from out directory
|
||||
sponge patch copy-go-mod --out=./yourServerDir
|
||||
`),
|
||||
SilenceErrors: true,
|
||||
SilenceUsage: true,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
if moduleName == "" {
|
||||
mn, _, _ := getNamesFromOutDir(outPath)
|
||||
if mn == "" {
|
||||
return errors.New("module-name is required, please use --module-name to set it")
|
||||
}
|
||||
moduleName = mn
|
||||
}
|
||||
|
||||
goModFile := outPath + gofile.GetPathDelimiter() + "go.mod"
|
||||
if gofile.IsExists(goModFile) {
|
||||
if isLogExist {
|
||||
fmt.Printf("%s already exists, skip copying.\n", goModFile)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
out, err := runCopyGoModCommand(moduleName, outPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Printf("copied go.mod to %s\n", out)
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
cmd.Flags().StringVarP(&moduleName, "module-name", "m", "", "module-name is the name of the module in the go.mod file")
|
||||
cmd.Flags().StringVarP(&outPath, "out", "o", ".", "output directory")
|
||||
cmd.Flags().BoolVarP(&isLogExist, "is-log-exist", "l", false, "is log file exist")
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func runCopyGoModCommand(moduleName string, out string) (string, error) {
|
||||
r := generate.Replacers[generate.TplNameSponge]
|
||||
if r == nil {
|
||||
return "", errors.New("replacer is nil")
|
||||
}
|
||||
|
||||
// setting up template information
|
||||
subFiles := []string{"sponge/go.mod", "sponge/go.sum"}
|
||||
r.SetSubDirsAndFiles(nil, subFiles...)
|
||||
r.SetReplacementFields(generate.GetGoModFields(moduleName))
|
||||
_ = r.SetOutputDir(out)
|
||||
if err := r.SaveFiles(); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return r.GetOutputDir(), nil
|
||||
}
|
|
@ -11,6 +11,7 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/fatih/color"
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"github.com/zhufuyi/sponge/pkg/gobash"
|
||||
|
@ -32,7 +33,7 @@ func CopyProtoCommand() *cobra.Command {
|
|||
cmd := &cobra.Command{
|
||||
Use: "copy-proto",
|
||||
Short: "Copy proto file from the grpc service directory",
|
||||
Long: `copy proto file from the grpc service, if the proto file exists, it will be forced to overwrite it,
|
||||
Long: color.HiBlackString(`copy proto file from the grpc service, if the proto file exists, it will be forced to overwrite it,
|
||||
don't worry about losing the proto file after overwriting it, before copying proto it will be backed up to
|
||||
the directory /tmp/sponge_copy_backup_proto_files.
|
||||
|
||||
|
@ -45,7 +46,7 @@ Examples:
|
|||
|
||||
# copy the specified proto files in the grpc service directory
|
||||
sponge patch copy-proto --server-dir=../grpc-server --proto-file=name1.proto,name2.proto
|
||||
`,
|
||||
`),
|
||||
SilenceErrors: true,
|
||||
SilenceUsage: true,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
|
|
|
@ -0,0 +1,77 @@
|
|||
package patch
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/fatih/color"
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"github.com/zhufuyi/sponge/cmd/sponge/commands/generate"
|
||||
"github.com/zhufuyi/sponge/pkg/gofile"
|
||||
)
|
||||
|
||||
// CopyThirdPartyProtoCommand copy third-party proto files
|
||||
func CopyThirdPartyProtoCommand() *cobra.Command {
|
||||
var (
|
||||
outPath string // output directory
|
||||
isLogExist bool
|
||||
)
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "copy-third-party-proto",
|
||||
Short: "Copy third-party proto files",
|
||||
Long: color.HiBlackString(`copy third-party proto files to local directory.
|
||||
|
||||
Examples:
|
||||
# copy third-party proto files to current directory
|
||||
sponge patch copy-third-party-proto
|
||||
|
||||
# copy third-party proto files to yourServerDir
|
||||
sponge patch copy-third-party-proto --out=./yourServerDir
|
||||
`),
|
||||
SilenceErrors: true,
|
||||
SilenceUsage: true,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
out := outPath + gofile.GetPathDelimiter() + "third_party"
|
||||
if gofile.IsExists(out) {
|
||||
if isLogExist {
|
||||
fmt.Printf("%s proto files already exists, skip copying.\n", out)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var err error
|
||||
out, err = runCopyThirdPartyProtoCommand(outPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Printf("copied third_party proto files to %s\n", out)
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
cmd.Flags().StringVarP(&outPath, "out", "o", ".", "output directory")
|
||||
cmd.Flags().BoolVarP(&isLogExist, "is-log-exist", "l", false, "is log file exist")
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func runCopyThirdPartyProtoCommand(out string) (string, error) {
|
||||
r := generate.Replacers[generate.TplNameSponge]
|
||||
if r == nil {
|
||||
return "", errors.New("replacer is nil")
|
||||
}
|
||||
|
||||
// setting up template information
|
||||
subDirs := []string{"sponge/third_party"}
|
||||
|
||||
r.SetSubDirsAndFiles(subDirs)
|
||||
_ = r.SetOutputDir(out)
|
||||
if err := r.SaveFiles(); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return r.GetOutputDir(), nil
|
||||
}
|
|
@ -5,6 +5,7 @@ import (
|
|||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/fatih/color"
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"github.com/zhufuyi/sponge/pkg/gofile"
|
||||
|
@ -20,7 +21,7 @@ func DeleteJSONOmitemptyCommand() *cobra.Command {
|
|||
cmd := &cobra.Command{
|
||||
Use: "del-omitempty",
|
||||
Short: "Delete json tag omitempty",
|
||||
Long: `delete json tag omitempty
|
||||
Long: color.HiBlackString(`delete json tag omitempty
|
||||
|
||||
Examples:
|
||||
# delete all files that include the omitempty character
|
||||
|
@ -29,7 +30,7 @@ Examples:
|
|||
# delete the specified suffix file including the omitempty character
|
||||
sponge patch del-omitempty --dir=./api --suffix-name=pb.go
|
||||
|
||||
`,
|
||||
`),
|
||||
SilenceErrors: true,
|
||||
SilenceUsage: true,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/fatih/color"
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"github.com/zhufuyi/sponge/cmd/sponge/commands/generate"
|
||||
|
@ -24,7 +25,7 @@ func GenerateDBInitCommand() *cobra.Command {
|
|||
cmd := &cobra.Command{
|
||||
Use: "gen-db-init",
|
||||
Short: "Generate database initialization code",
|
||||
Long: `generate database initialization code.
|
||||
Long: color.HiBlackString(`generate database initialization code.
|
||||
|
||||
Examples:
|
||||
# generate mysql initialization code.
|
||||
|
@ -32,7 +33,7 @@ Examples:
|
|||
|
||||
# generate mysql initialization code, and specify the server directory, Note: code generation will be canceled when the latest generated file already exists.
|
||||
sponge patch gen-db-init --db-driver=mysql --out=./yourServerDir
|
||||
`,
|
||||
`),
|
||||
SilenceErrors: true,
|
||||
SilenceUsage: true,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
|
@ -46,7 +47,6 @@ Examples:
|
|||
if serverName == "" {
|
||||
return fmt.Errorf(`serverName is empty`)
|
||||
}
|
||||
targetFile = strings.ReplaceAll(targetFile, "internal", "Internal")
|
||||
}
|
||||
|
||||
var isEmpty bool
|
||||
|
@ -171,7 +171,7 @@ func (g *dbInitGenerator) addFields(r replacer.Replacer) []replacer.Field {
|
|||
}...)
|
||||
|
||||
if g.suitedMonoRepo {
|
||||
fs := generate.SubServerCodeFields(r.GetOutputDir(), g.moduleName, g.serverName)
|
||||
fs := generate.SubServerCodeFields(g.moduleName, g.serverName)
|
||||
fields = append(fields, fs...)
|
||||
}
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/fatih/color"
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"github.com/zhufuyi/sponge/cmd/sponge/commands/generate"
|
||||
|
@ -23,7 +24,7 @@ func GenMysqlInitCommand() *cobra.Command {
|
|||
cmd := &cobra.Command{
|
||||
Use: "gen-mysql-init",
|
||||
Short: "Generate mysql initialization code",
|
||||
Long: `generate mysql initialization code
|
||||
Long: color.HiBlackString(`generate mysql initialization code
|
||||
|
||||
Examples:
|
||||
# generate mysql initialization code.
|
||||
|
@ -31,7 +32,7 @@ Examples:
|
|||
|
||||
# generate mysql initialization code, and specify the server directory, Note: code generation will be canceled when the latest generated file already exists.
|
||||
sponge patch gen-mysql-init --out=./yourServerDir
|
||||
`,
|
||||
`),
|
||||
SilenceErrors: true,
|
||||
SilenceUsage: true,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/fatih/color"
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"github.com/zhufuyi/sponge/cmd/sponge/commands/generate"
|
||||
|
@ -23,7 +24,7 @@ func GenTypesPbCommand() *cobra.Command {
|
|||
cmd := &cobra.Command{
|
||||
Use: "gen-types-pb",
|
||||
Short: "Generate types.proto code",
|
||||
Long: `generate types.proto code
|
||||
Long: color.HiBlackString(`generate types.proto code
|
||||
|
||||
Examples:
|
||||
# generate types.proto code.
|
||||
|
@ -31,7 +32,7 @@ Examples:
|
|||
|
||||
# generate types.proto code and specify the server directory, Note: code generation will be canceled when the latest generated file already exists.
|
||||
sponge patch gen-types-pb --out=./yourServerDir
|
||||
`,
|
||||
`),
|
||||
SilenceErrors: true,
|
||||
SilenceUsage: true,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package patch
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"fmt"
|
||||
"os"
|
||||
|
@ -8,6 +9,7 @@ import (
|
|||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/fatih/color"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
|
@ -20,13 +22,12 @@ func ModifyDuplicateErrCodeCommand() *cobra.Command {
|
|||
cmd := &cobra.Command{
|
||||
Use: "modify-dup-err-code",
|
||||
Short: "Modify duplicate error codes",
|
||||
Long: `modify duplicate error codes
|
||||
Long: color.HiBlackString(`modify duplicate error codes
|
||||
|
||||
Examples:
|
||||
# modify duplicate error codes
|
||||
sponge patch modify-dup-err-code --dir=internal/ecode
|
||||
|
||||
`,
|
||||
`),
|
||||
SilenceErrors: true,
|
||||
SilenceUsage: true,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
|
@ -35,27 +36,16 @@ Examples:
|
|||
return err
|
||||
}
|
||||
|
||||
var total int
|
||||
for _, file := range files {
|
||||
ecsis, err := parseErrCodeInfo(file)
|
||||
count, err := checkAndModifyDuplicateErrCode(file)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, ecsi := range ecsis {
|
||||
msg, err := ecsi.modifyHTTPDuplicateNum()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if msg != "" {
|
||||
fmt.Println("modify http duplicate error codes: ", msg)
|
||||
}
|
||||
msg, err = ecsi.modifyGRPCDuplicateNum()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if msg != "" {
|
||||
fmt.Println("modify grpc duplicate error codes: ", msg)
|
||||
}
|
||||
}
|
||||
total += count
|
||||
}
|
||||
if total > 0 {
|
||||
fmt.Println("modify duplicate error codes successfully.")
|
||||
}
|
||||
return nil
|
||||
},
|
||||
|
@ -67,228 +57,121 @@ Examples:
|
|||
}
|
||||
|
||||
type eCodeInfo struct {
|
||||
Name string
|
||||
Num int
|
||||
Str string
|
||||
Name string
|
||||
Num int
|
||||
Str string
|
||||
DstStr string
|
||||
}
|
||||
|
||||
type errCodesInfo struct {
|
||||
file string
|
||||
var (
|
||||
serviceGroupSeparatorMark = "// ---------- Do not delete or move this split line, this is the merge code marker ----------"
|
||||
defineHTTPErrCodeMark = "errcode.NewError("
|
||||
defineGRPCErrCodeMark = "errcode.NewRPCStatus("
|
||||
)
|
||||
|
||||
httpErrCodeInfo map[string]eCodeInfo // map[name]eCodeInfo
|
||||
httpDuplicationNums map[int][]string
|
||||
httpMaxNum int
|
||||
func parseErrCodeInfo(line string) eCodeInfo {
|
||||
ci := eCodeInfo{}
|
||||
|
||||
grpcErrCodeInfo map[string]eCodeInfo // map[name]eCodeInfo
|
||||
grpcDuplicationNums map[int][]string
|
||||
grpcMaxNum int
|
||||
pattern := `(\w+)\s*=\s*\w+\.(.*?)\((.*?),`
|
||||
re := regexp.MustCompile(pattern)
|
||||
match := re.FindStringSubmatch(line)
|
||||
if len(match) < 4 {
|
||||
return ci
|
||||
}
|
||||
baseCodeStr := match[3]
|
||||
|
||||
index := strings.Index(line, baseCodeStr)
|
||||
if index < 0 {
|
||||
return ci
|
||||
}
|
||||
srcStr := line[:index] + baseCodeStr
|
||||
|
||||
ss := strings.Split(baseCodeStr, "+")
|
||||
if len(ss) != 2 {
|
||||
return ci
|
||||
}
|
||||
num, _ := strconv.Atoi(strings.TrimSpace(ss[1]))
|
||||
|
||||
ci.Name = match[1]
|
||||
ci.Num = num
|
||||
ci.Str = srcStr
|
||||
ci.DstStr = line[:index] + ss[0] + "+"
|
||||
|
||||
return ci
|
||||
}
|
||||
|
||||
func (e *errCodesInfo) getHTTPMaxNum() int {
|
||||
maxNum := 0
|
||||
for num := range e.httpDuplicationNums {
|
||||
if num > maxNum {
|
||||
maxNum = num
|
||||
func getModifyCodeInfos(codes []eCodeInfo) ([]eCodeInfo, int) {
|
||||
maxCode := 0
|
||||
m := map[int][]eCodeInfo{}
|
||||
|
||||
for _, ci := range codes {
|
||||
if ci.Num > maxCode {
|
||||
maxCode = ci.Num
|
||||
}
|
||||
|
||||
if cis, ok := m[ci.Num]; ok {
|
||||
m[ci.Num] = append(cis, ci)
|
||||
} else {
|
||||
m[ci.Num] = []eCodeInfo{ci}
|
||||
}
|
||||
}
|
||||
return maxNum
|
||||
}
|
||||
|
||||
func (e *errCodesInfo) getGRPCMaxNum() int {
|
||||
maxNum := 0
|
||||
for num := range e.grpcDuplicationNums {
|
||||
if num > maxNum {
|
||||
maxNum = num
|
||||
needModify := []eCodeInfo{}
|
||||
for _, infos := range m {
|
||||
if len(infos) > 1 {
|
||||
needModify = append(needModify, infos[1:]...)
|
||||
}
|
||||
}
|
||||
return maxNum
|
||||
|
||||
return needModify, maxCode
|
||||
}
|
||||
|
||||
func (e *errCodesInfo) modifyHTTPDuplicateNum() (string, error) {
|
||||
msg := ""
|
||||
duplicateNums := []string{}
|
||||
|
||||
if len(e.httpDuplicationNums) == 0 {
|
||||
return msg, nil
|
||||
func modifyErrCode(data []byte, infos []eCodeInfo, maxCode int) []byte {
|
||||
for _, info := range infos {
|
||||
maxCode++
|
||||
data = bytes.ReplaceAll(data, []byte(info.Str), []byte(info.DstStr+strconv.Itoa(maxCode)))
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
||||
numMap := map[int]struct{}{}
|
||||
for num := range e.httpDuplicationNums {
|
||||
numMap[num] = struct{}{}
|
||||
}
|
||||
func getDuplicateErrCodeInfo(data []byte) ([]eCodeInfo, int) {
|
||||
cis := []eCodeInfo{}
|
||||
|
||||
e.httpMaxNum = e.getHTTPMaxNum()
|
||||
for _, names := range e.httpDuplicationNums {
|
||||
if len(names) <= 1 {
|
||||
buf := bufio.NewReader(bytes.NewReader(data))
|
||||
for {
|
||||
line, err := buf.ReadString('\n')
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
if !strings.Contains(line, defineHTTPErrCodeMark) && !strings.Contains(line, defineGRPCErrCodeMark) {
|
||||
continue
|
||||
}
|
||||
|
||||
for i, name := range names {
|
||||
if i == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
eci := e.httpErrCodeInfo[name]
|
||||
e.httpMaxNum++
|
||||
newNum := e.httpMaxNum
|
||||
|
||||
_, err := updateErrCodeFile(e.file, newNum, eci)
|
||||
if err != nil {
|
||||
return msg, err
|
||||
}
|
||||
duplicateNums = append(duplicateNums, fmt.Sprintf("%d --> %d", eci.Num, newNum))
|
||||
ci := parseErrCodeInfo(line)
|
||||
if ci.Name != "" {
|
||||
cis = append(cis, ci)
|
||||
}
|
||||
}
|
||||
|
||||
if len(duplicateNums) == 0 {
|
||||
return msg, nil
|
||||
}
|
||||
return strings.Join(duplicateNums, ", "), nil
|
||||
return getModifyCodeInfos(cis)
|
||||
}
|
||||
|
||||
func (e *errCodesInfo) modifyGRPCDuplicateNum() (string, error) {
|
||||
msg := ""
|
||||
duplicateNums := []string{}
|
||||
|
||||
if len(e.grpcDuplicationNums) == 0 {
|
||||
return msg, nil
|
||||
}
|
||||
|
||||
numMap := map[int]struct{}{}
|
||||
for num := range e.grpcDuplicationNums {
|
||||
numMap[num] = struct{}{}
|
||||
}
|
||||
|
||||
e.grpcMaxNum = e.getGRPCMaxNum()
|
||||
for _, names := range e.grpcDuplicationNums {
|
||||
if len(names) <= 1 {
|
||||
continue
|
||||
}
|
||||
|
||||
for i, name := range names {
|
||||
if i == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
eci := e.grpcErrCodeInfo[name]
|
||||
e.grpcMaxNum++
|
||||
newNum := e.grpcMaxNum
|
||||
|
||||
_, err := updateErrCodeFile(e.file, newNum, eci)
|
||||
if err != nil {
|
||||
return msg, err
|
||||
}
|
||||
duplicateNums = append(duplicateNums, fmt.Sprintf("%d --> %d", eci.Num, newNum))
|
||||
}
|
||||
}
|
||||
|
||||
if len(duplicateNums) == 0 {
|
||||
return msg, nil
|
||||
}
|
||||
return strings.Join(duplicateNums, ", "), nil
|
||||
}
|
||||
|
||||
func parseErrCodeInfo(file string) ([]*errCodesInfo, error) {
|
||||
errCodeType := ""
|
||||
ecsis := []*errCodesInfo{}
|
||||
|
||||
func checkAndModifyDuplicateErrCode(file string) (int, error) {
|
||||
data, err := os.ReadFile(file)
|
||||
if err != nil {
|
||||
return ecsis, err
|
||||
}
|
||||
dataStr := string(data)
|
||||
if strings.Contains(dataStr, "errcode.NewError") {
|
||||
errCodeType = httpType
|
||||
} else if strings.Contains(dataStr, "errcode.NewRPCStatus") {
|
||||
errCodeType = grpcType
|
||||
return 0, err
|
||||
}
|
||||
|
||||
if errCodeType == "" {
|
||||
return ecsis, nil
|
||||
serviceGroupData := bytes.Split(data, []byte(serviceGroupSeparatorMark))
|
||||
var fileContent [][]byte
|
||||
var count int
|
||||
for _, groupData := range serviceGroupData {
|
||||
ecis, maxCode := getDuplicateErrCodeInfo(groupData)
|
||||
fileContent = append(fileContent, modifyErrCode(groupData, ecis, maxCode))
|
||||
count += len(ecis)
|
||||
}
|
||||
|
||||
var regStr string
|
||||
if errCodeType == httpType {
|
||||
regStr = `(Err[\w\W]*?)[ ]*?=[ ]*?errcode.NewError\(([\w\W]*?)BaseCode\+(\d),`
|
||||
} else if errCodeType == grpcType {
|
||||
regStr = `(Status[\w\W]*?)[ ]*?=[ ]*?errcode.NewRPCStatus\(([\w\W]*?)BaseCode\+(\d),`
|
||||
}
|
||||
|
||||
reg := regexp.MustCompile(regStr)
|
||||
allSubMatch := reg.FindAllStringSubmatch(dataStr, -1)
|
||||
if len(allSubMatch) == 0 {
|
||||
return ecsis, nil
|
||||
}
|
||||
|
||||
groupNames := make(map[string][][]string)
|
||||
for _, match := range allSubMatch {
|
||||
if len(match) == 4 {
|
||||
gns, ok := groupNames[match[2]]
|
||||
if ok {
|
||||
gns = append(gns, match)
|
||||
} else {
|
||||
gns = [][]string{match}
|
||||
}
|
||||
groupNames[match[2]] = gns
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
for _, gn := range groupNames {
|
||||
ecsi := &errCodesInfo{}
|
||||
eci := make(map[string]eCodeInfo)
|
||||
duplicationNums := make(map[int][]string)
|
||||
for _, match := range gn {
|
||||
if len(match) == 4 {
|
||||
num, _ := strconv.Atoi(match[3])
|
||||
if num == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
if names, ok := duplicationNums[num]; ok {
|
||||
duplicationNums[num] = append(names, match[1])
|
||||
} else {
|
||||
duplicationNums[num] = []string{match[1]}
|
||||
}
|
||||
|
||||
eci[match[1]] = eCodeInfo{Name: match[1], Num: num, Str: match[0]}
|
||||
}
|
||||
}
|
||||
if errCodeType == httpType {
|
||||
ecsi.httpDuplicationNums = duplicationNums
|
||||
ecsi.httpErrCodeInfo = eci
|
||||
} else if errCodeType == grpcType {
|
||||
ecsi.grpcDuplicationNums = duplicationNums
|
||||
ecsi.grpcErrCodeInfo = eci
|
||||
}
|
||||
ecsi.file = file
|
||||
ecsis = append(ecsis, ecsi)
|
||||
}
|
||||
|
||||
return ecsis, nil
|
||||
}
|
||||
|
||||
func updateErrCodeFile(file string, newNum int, eci eCodeInfo) (eCodeInfo, error) {
|
||||
strTmp := eci.Str
|
||||
oldNum := eci.Num
|
||||
eci.Str = replaceNumStr(strTmp, oldNum, newNum)
|
||||
eci.Num = newNum
|
||||
|
||||
data, err := os.ReadFile(file)
|
||||
if err != nil {
|
||||
return eci, err
|
||||
}
|
||||
data = bytes.ReplaceAll(data, []byte(strTmp), []byte(eci.Str))
|
||||
|
||||
err = os.WriteFile(file, data, 0766)
|
||||
if err != nil {
|
||||
return eci, err
|
||||
}
|
||||
return eci, nil
|
||||
}
|
||||
|
||||
func replaceNumStr(str string, oldNum int, newNum int) string {
|
||||
oldNumStr := fmt.Sprintf("+%d", oldNum)
|
||||
newNumStr := fmt.Sprintf("+%d", newNum)
|
||||
return strings.ReplaceAll(str, oldNumStr, newNumStr)
|
||||
data = bytes.Join(fileContent, []byte(serviceGroupSeparatorMark))
|
||||
err = os.WriteFile(file, data, 0666)
|
||||
return count, err
|
||||
}
|
||||
|
|
|
@ -2,23 +2,14 @@ package patch
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/fatih/color"
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"github.com/zhufuyi/sponge/pkg/gofile"
|
||||
"github.com/zhufuyi/sponge/pkg/krand"
|
||||
)
|
||||
|
||||
const (
|
||||
httpType = "http"
|
||||
grpcType = "grpc"
|
||||
)
|
||||
|
||||
// ModifyDuplicateNumCommand modify duplicate numbers
|
||||
|
@ -30,13 +21,12 @@ func ModifyDuplicateNumCommand() *cobra.Command {
|
|||
cmd := &cobra.Command{
|
||||
Use: "modify-dup-num",
|
||||
Short: "Modify duplicate numbers",
|
||||
Long: `modify duplicate numbers
|
||||
Long: color.HiBlackString(`modify duplicate numbers
|
||||
|
||||
Examples:
|
||||
# modify duplicate numbers
|
||||
sponge patch modify-dup-num --dir=internal/ecode
|
||||
|
||||
`,
|
||||
`),
|
||||
SilenceErrors: true,
|
||||
SilenceUsage: true,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
|
@ -45,25 +35,14 @@ Examples:
|
|||
return err
|
||||
}
|
||||
|
||||
nsi, err := parseFiles(files)
|
||||
count, err := checkAndModifyDuplicateNum(files)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if count > 0 {
|
||||
fmt.Println("modify duplicate num successfully.")
|
||||
}
|
||||
|
||||
msg, err := nsi.modifyHTTPDuplicateNum()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if msg != "" {
|
||||
fmt.Println("modify http duplicate numbers: ", msg)
|
||||
}
|
||||
msg, err = nsi.modifyGRPCDuplicateNum()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if msg != "" {
|
||||
fmt.Println("modify grpc duplicate numbers: ", msg)
|
||||
}
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
@ -73,315 +52,161 @@ Examples:
|
|||
return cmd
|
||||
}
|
||||
|
||||
func listErrCodeFiles(dir string) ([]string, error) {
|
||||
files, err := gofile.ListFiles(dir)
|
||||
type coreInfo struct {
|
||||
name string
|
||||
num int
|
||||
srcStr string
|
||||
dstStr string
|
||||
file string
|
||||
}
|
||||
|
||||
var (
|
||||
httpNumMark = "errcode.HCode"
|
||||
grpcNumMark = "errcode.RCode"
|
||||
httpPattern = `errcode\.HCode\(([^)]+)\)`
|
||||
grpcPattern = `errcode\.RCode\(([^)]+)\)`
|
||||
)
|
||||
|
||||
func getVariableName(data []byte, pattern string) string {
|
||||
re := regexp.MustCompile(pattern)
|
||||
match := re.FindStringSubmatch(string(data))
|
||||
if len(match) < 2 {
|
||||
return ""
|
||||
}
|
||||
|
||||
return strings.ReplaceAll(match[1], " ", "")
|
||||
}
|
||||
|
||||
func parseNumInfo(data []byte, variableName string) coreInfo {
|
||||
var info coreInfo
|
||||
pattern := variableName + `\s*=\s*(\d+)`
|
||||
re := regexp.MustCompile(pattern)
|
||||
match := re.FindStringSubmatch(string(data))
|
||||
if len(match) < 2 {
|
||||
return info
|
||||
}
|
||||
|
||||
num, err := strconv.Atoi(match[1])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return info
|
||||
}
|
||||
|
||||
if len(files) == 0 {
|
||||
return nil, errors.New("not found files")
|
||||
ss := strings.Split(match[0], "=")
|
||||
if len(ss) != 2 {
|
||||
return info
|
||||
}
|
||||
|
||||
filterFiles := []string{}
|
||||
for _, file := range files {
|
||||
if strings.Contains(file, "systemCode.go") ||
|
||||
strings.Contains(file, "systemCode_http.go") ||
|
||||
strings.Contains(file, "systemCode_rpc.go") {
|
||||
continue
|
||||
}
|
||||
filterFiles = append(filterFiles, file)
|
||||
}
|
||||
info.name = variableName
|
||||
info.num = num
|
||||
info.srcStr = match[0]
|
||||
info.dstStr = ss[0] + "= "
|
||||
|
||||
return filterFiles, nil
|
||||
return info
|
||||
}
|
||||
|
||||
type numInfo struct {
|
||||
Name string
|
||||
Num int
|
||||
Str string
|
||||
}
|
||||
|
||||
type numbersInfo struct {
|
||||
httpNumInfo map[string]map[string]numInfo // map[file]map[code]numInfo
|
||||
httpDuplicationNums map[int][]string
|
||||
|
||||
grpcNumInfo map[string]map[string]numInfo // map[file]map[code]numInfo
|
||||
grpcDuplicationNums map[int][]string
|
||||
}
|
||||
|
||||
func (r *numbersInfo) modifyHTTPDuplicateNum() (string, error) {
|
||||
msg := ""
|
||||
duplicateNums := []string{}
|
||||
|
||||
if len(r.httpDuplicationNums) == 0 {
|
||||
return msg, nil
|
||||
}
|
||||
|
||||
numMap := map[int]struct{}{}
|
||||
for num := range r.httpDuplicationNums {
|
||||
numMap[num] = struct{}{}
|
||||
}
|
||||
|
||||
for num, fs := range r.httpDuplicationNums {
|
||||
if len(fs) <= 1 {
|
||||
continue
|
||||
}
|
||||
|
||||
fs = sortFiles(fs)
|
||||
for i, file := range fs {
|
||||
if i == 0 {
|
||||
continue
|
||||
}
|
||||
for _, ni := range r.httpNumInfo[file] {
|
||||
newNum := genNewNum(numMap)
|
||||
if ni.Num == num {
|
||||
_, err := updateFile(file, newNum, ni)
|
||||
if err != nil {
|
||||
return msg, err
|
||||
}
|
||||
duplicateNums = append(duplicateNums, fmt.Sprintf("%d --> %d", ni.Num, newNum))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(duplicateNums) == 0 {
|
||||
return msg, nil
|
||||
}
|
||||
return strings.Join(duplicateNums, ", "), nil
|
||||
}
|
||||
|
||||
func (r *numbersInfo) modifyGRPCDuplicateNum() (string, error) {
|
||||
msg := ""
|
||||
duplicateNums := []string{}
|
||||
|
||||
if len(r.grpcDuplicationNums) == 0 {
|
||||
return msg, nil
|
||||
}
|
||||
|
||||
numMap := map[int]struct{}{}
|
||||
for num := range r.grpcDuplicationNums {
|
||||
numMap[num] = struct{}{}
|
||||
}
|
||||
|
||||
for num, fs := range r.grpcDuplicationNums {
|
||||
if len(fs) <= 1 {
|
||||
continue
|
||||
}
|
||||
|
||||
fs = sortFiles(fs)
|
||||
for i, file := range fs {
|
||||
if i == 0 {
|
||||
continue
|
||||
}
|
||||
for _, ni := range r.grpcNumInfo[file] {
|
||||
newNum := genNewNum(numMap)
|
||||
if ni.Num == num {
|
||||
_, err := updateFile(file, newNum, ni)
|
||||
if err != nil {
|
||||
return msg, err
|
||||
}
|
||||
duplicateNums = append(duplicateNums, fmt.Sprintf("%d --> %d", ni.Num, newNum))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(duplicateNums) == 0 {
|
||||
return msg, nil
|
||||
}
|
||||
return strings.Join(duplicateNums, ", "), nil
|
||||
}
|
||||
|
||||
func parseFiles(files []string) (*numbersInfo, error) {
|
||||
nsi := &numbersInfo{
|
||||
httpNumInfo: map[string]map[string]numInfo{},
|
||||
httpDuplicationNums: map[int][]string{},
|
||||
grpcNumInfo: map[string]map[string]numInfo{},
|
||||
grpcDuplicationNums: map[int][]string{},
|
||||
}
|
||||
|
||||
for _, file := range files {
|
||||
result, err := parseNumberInfo(file)
|
||||
if err != nil {
|
||||
return nsi, err
|
||||
}
|
||||
if result == nil {
|
||||
continue
|
||||
}
|
||||
if result.errCodeType == httpType {
|
||||
for _, num := range result.nums {
|
||||
if fs, ok := nsi.httpDuplicationNums[num]; ok {
|
||||
fs = append(fs, file)
|
||||
nsi.httpDuplicationNums[num] = fs
|
||||
} else {
|
||||
nsi.httpDuplicationNums[num] = []string{file}
|
||||
}
|
||||
}
|
||||
nsi.httpNumInfo[file] = result.ni
|
||||
} else if result.errCodeType == grpcType {
|
||||
for _, num := range result.nums {
|
||||
if fs, ok := nsi.grpcDuplicationNums[num]; ok {
|
||||
fs = append(fs, file)
|
||||
nsi.grpcDuplicationNums[num] = fs
|
||||
} else {
|
||||
nsi.grpcDuplicationNums[num] = []string{file}
|
||||
}
|
||||
}
|
||||
nsi.grpcNumInfo[file] = result.ni
|
||||
}
|
||||
}
|
||||
|
||||
return nsi, nil
|
||||
}
|
||||
|
||||
type parseResult struct {
|
||||
ni map[string]numInfo
|
||||
nums []int
|
||||
errCodeType string
|
||||
}
|
||||
|
||||
func parseNumberInfo(file string) (*parseResult, error) {
|
||||
errCodeType := ""
|
||||
ni := map[string]numInfo{}
|
||||
nums := []int{}
|
||||
|
||||
func getNumberInfos(file string) []coreInfo {
|
||||
var infos []coreInfo
|
||||
data, err := os.ReadFile(file)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dataStr := string(data)
|
||||
if strings.Contains(dataStr, "errcode.NewError") {
|
||||
errCodeType = httpType
|
||||
} else if strings.Contains(dataStr, "errcode.NewRPCStatus") {
|
||||
errCodeType = grpcType
|
||||
return infos
|
||||
}
|
||||
|
||||
if errCodeType == "" {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
var regStr string
|
||||
if errCodeType == httpType {
|
||||
regStr = `=[ ]*?errcode.HCode\(([\w\W]*?)\)\n`
|
||||
} else if errCodeType == grpcType {
|
||||
regStr = `=[ ]*?errcode.RCode\(([\w\W]*?)\)\n`
|
||||
}
|
||||
|
||||
reg := regexp.MustCompile(regStr)
|
||||
allSubMatch := reg.FindAllStringSubmatch(dataStr, -1)
|
||||
if len(allSubMatch) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
names := []string{}
|
||||
|
||||
for _, match := range allSubMatch {
|
||||
for i, v := range match {
|
||||
if i == 1 {
|
||||
names = append(names, v)
|
||||
serviceGroupData := bytes.Split(data, []byte(serviceGroupSeparatorMark))
|
||||
for _, groupData := range serviceGroupData {
|
||||
pattern := ""
|
||||
if bytes.Contains(groupData, []byte(httpNumMark)) {
|
||||
pattern = httpPattern
|
||||
} else if bytes.Contains(groupData, []byte(grpcNumMark)) {
|
||||
pattern = grpcPattern
|
||||
}
|
||||
if pattern != "" {
|
||||
variableName := getVariableName(groupData, pattern)
|
||||
if variableName != "" {
|
||||
info := parseNumInfo(groupData, variableName)
|
||||
if info.name != "" {
|
||||
info.file = file
|
||||
infos = append(infos, info)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for _, name := range names {
|
||||
regStr = name + `[ ]*?=[ ]*?([\d]+)`
|
||||
reg = regexp.MustCompile(regStr)
|
||||
allSubMatch = reg.FindAllStringSubmatch(dataStr, -1)
|
||||
for _, match := range allSubMatch {
|
||||
if len(match) == 2 {
|
||||
num, _ := strconv.Atoi(match[1])
|
||||
nums = append(nums, num)
|
||||
ni[name] = numInfo{Name: name, Num: num, Str: match[0]}
|
||||
return infos
|
||||
}
|
||||
|
||||
func getModifyNumInfos(infos []coreInfo) ([]coreInfo, map[int]struct{}) {
|
||||
m := map[int][]coreInfo{}
|
||||
allNum := map[int]struct{}{}
|
||||
for _, info := range infos {
|
||||
allNum[info.num] = struct{}{}
|
||||
if cis, ok := m[info.num]; ok {
|
||||
m[info.num] = append(cis, info)
|
||||
} else {
|
||||
m[info.num] = []coreInfo{info}
|
||||
}
|
||||
}
|
||||
|
||||
needModify := []coreInfo{}
|
||||
for _, numInfos := range m {
|
||||
if len(numInfos) > 1 {
|
||||
needModify = append(needModify, numInfos[1:]...)
|
||||
}
|
||||
}
|
||||
|
||||
return needModify, allNum
|
||||
}
|
||||
|
||||
func modifyNumberInfos(infos []coreInfo, allNum map[int]struct{}) (int, error) {
|
||||
l := len(infos)
|
||||
if l == 0 {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
var nums []int
|
||||
for i := 1; i < 100; i++ {
|
||||
if _, ok := allNum[i]; !ok {
|
||||
nums = append(nums, i)
|
||||
if len(nums) == len(infos) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return &parseResult{
|
||||
ni: ni,
|
||||
nums: nums,
|
||||
errCodeType: errCodeType,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func getFileCreateTime(file string) int64 {
|
||||
fi, err := os.Stat(file)
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
|
||||
return fi.ModTime().Unix()
|
||||
}
|
||||
|
||||
func updateFile(file string, newNum int, ni numInfo) (numInfo, error) {
|
||||
strTmp := ni.Str
|
||||
ni.Num = newNum
|
||||
ni.Str = replaceNum(strTmp, ni.Num)
|
||||
|
||||
data, err := os.ReadFile(file)
|
||||
if err != nil {
|
||||
return ni, err
|
||||
}
|
||||
data = bytes.ReplaceAll(data, []byte(strTmp), []byte(ni.Str))
|
||||
|
||||
err = os.WriteFile(file, data, 0766)
|
||||
if err != nil {
|
||||
return ni, err
|
||||
}
|
||||
return ni, nil
|
||||
}
|
||||
|
||||
func replaceNum(str string, newNum int) string {
|
||||
regStr := `([\w\W]*?=[ ]*?)[\d]+`
|
||||
reg := regexp.MustCompile(regStr)
|
||||
allSubMatch := reg.FindAllStringSubmatch(str, -1)
|
||||
for _, match := range allSubMatch {
|
||||
if len(match) == 2 {
|
||||
str = match[1] + fmt.Sprintf("%d", newNum)
|
||||
if len(nums) < l {
|
||||
for i := 0; i < l-len(nums); i++ {
|
||||
nums = append(nums, 99) // 99 is the largest number
|
||||
}
|
||||
}
|
||||
return str
|
||||
}
|
||||
|
||||
type fileInfo struct {
|
||||
file string
|
||||
createdTime int64
|
||||
}
|
||||
|
||||
func sortFiles(files []string) []string {
|
||||
fis := []*fileInfo{}
|
||||
|
||||
for _, file := range files {
|
||||
fis = append(fis, &fileInfo{
|
||||
file: file,
|
||||
createdTime: getFileCreateTime(file),
|
||||
})
|
||||
}
|
||||
|
||||
sort.Slice(fis, func(i, j int) bool {
|
||||
return fis[i].createdTime < fis[j].createdTime
|
||||
})
|
||||
|
||||
var sFiles []string
|
||||
for _, fi := range fis {
|
||||
sFiles = append(sFiles, fi.file)
|
||||
}
|
||||
return sFiles
|
||||
}
|
||||
|
||||
func genNewNum(numMap map[int]struct{}) int {
|
||||
max := 1000000
|
||||
count := 0
|
||||
for {
|
||||
count++
|
||||
newNum := krand.Int(99)
|
||||
if _, ok := numMap[newNum]; !ok {
|
||||
numMap[newNum] = struct{}{}
|
||||
return newNum
|
||||
for i, info := range infos {
|
||||
data, err := os.ReadFile(info.file)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if count > max {
|
||||
break
|
||||
|
||||
newData := bytes.ReplaceAll(data, []byte(info.srcStr), []byte(info.dstStr+strconv.Itoa(nums[i])))
|
||||
|
||||
err = os.WriteFile(info.file, newData, 0666)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
count++
|
||||
}
|
||||
|
||||
return count, nil
|
||||
}
|
||||
|
||||
func checkAndModifyDuplicateNum(files []string) (int, error) {
|
||||
var allInfos []coreInfo
|
||||
for _, file := range files {
|
||||
infos := getNumberInfos(file)
|
||||
if len(infos) > 0 {
|
||||
allInfos = append(allInfos, infos...)
|
||||
}
|
||||
}
|
||||
return 1
|
||||
|
||||
needModify, allNum := getModifyNumInfos(allInfos)
|
||||
|
||||
return modifyNumberInfos(needModify, allNum)
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/fatih/color"
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"github.com/zhufuyi/sponge/pkg/gofile"
|
||||
|
@ -24,7 +25,7 @@ func ModifyProtoPackageCommand() *cobra.Command {
|
|||
cmd := &cobra.Command{
|
||||
Use: "modify-proto-package",
|
||||
Short: "Modifies the package and go_package names of proto files",
|
||||
Long: `modifies the package and go_package names of proto files.
|
||||
Long: color.HiBlackString(`modifies the package and go_package names of proto files.
|
||||
|
||||
Examples:
|
||||
# modify the package and go_package names of all proto files in the api directory.
|
||||
|
@ -32,8 +33,7 @@ Examples:
|
|||
|
||||
# modify the package and go_package names of all proto files in the api directory, get module name from docs/gen.
|
||||
sponge patch modify-proto-package --dir=api --server-dir=server
|
||||
|
||||
`,
|
||||
`),
|
||||
SilenceErrors: true,
|
||||
SilenceUsage: true,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
|
@ -129,43 +129,25 @@ func replaceProtoPackages(protoFilePath, packageName, goPackage string) error {
|
|||
data = bytes.ReplaceAll(data, []byte("\r\n"), []byte("\n"))
|
||||
}
|
||||
|
||||
regStr := `\npackage [\w\W]*?;`
|
||||
reg := regexp.MustCompile(regStr)
|
||||
srcPackageName := reg.Find(data)
|
||||
|
||||
regStr2 := `go_package [\w\W]*?;\n`
|
||||
reg2 := regexp.MustCompile(regStr2)
|
||||
srcGoPackageName := reg2.Find(data)
|
||||
|
||||
if len(srcPackageName) > 0 {
|
||||
newPackage := fmt.Sprintf("\npackage %s;", packageName)
|
||||
data = bytes.Replace(data, srcPackageName, []byte(newPackage), 1)
|
||||
newGoPackage := fmt.Sprintf("go_package = %s;\n", goPackage)
|
||||
if len(srcGoPackageName) > 0 {
|
||||
data = bytes.Replace(data, srcGoPackageName, []byte(newGoPackage), 1)
|
||||
} else {
|
||||
data = bytes.Replace(data, []byte("\n\n"), []byte("\n\n"+newGoPackage+"\n\n"), 1)
|
||||
}
|
||||
|
||||
if len(srcGoPackageName) > 0 {
|
||||
newGoPackage := fmt.Sprintf("go_package = %s;\n", goPackage)
|
||||
data = bytes.Replace(data, srcGoPackageName, []byte(newGoPackage), 1)
|
||||
regStr := `\npackage [\w\W]*?;`
|
||||
reg := regexp.MustCompile(regStr)
|
||||
srcPackageName := reg.Find(data)
|
||||
newPackage := fmt.Sprintf("\npackage %s;", packageName)
|
||||
if len(srcPackageName) > 0 {
|
||||
data = bytes.Replace(data, srcPackageName, []byte(newPackage), 1)
|
||||
} else {
|
||||
data = bytes.Replace(data, []byte("\n\n"), []byte("\n\n"+newPackage+"\n\n"), 1)
|
||||
}
|
||||
|
||||
return os.WriteFile(protoFilePath, data, 0666)
|
||||
}
|
||||
|
||||
// AddSpecialTypesCommand add common special types that proto files depend on
|
||||
// Deprecated: This command has been discarded
|
||||
func AddSpecialTypesCommand() *cobra.Command {
|
||||
var dir string
|
||||
cmd := &cobra.Command{
|
||||
Use: "add-special-types",
|
||||
Short: "Add common special types that proto files depend on, [Deprecated]",
|
||||
Long: `add common special types that proto files depend on, this command has been deprecated.
|
||||
|
||||
`,
|
||||
SilenceErrors: true,
|
||||
SilenceUsage: true,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
return nil
|
||||
},
|
||||
}
|
||||
cmd.Flags().StringVarP(&dir, "dir", "d", "", "input specified directory")
|
||||
return cmd
|
||||
}
|
||||
|
|
3
go.mod
3
go.mod
|
@ -115,6 +115,7 @@ require (
|
|||
github.com/go-openapi/swag v0.19.15 // indirect
|
||||
github.com/go-playground/locales v0.14.1 // indirect
|
||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||
github.com/go-redsync/redsync/v4 v4.12.1 // indirect
|
||||
github.com/goccy/go-json v0.10.2 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/golang/glog v1.1.2 // indirect
|
||||
|
@ -122,7 +123,7 @@ require (
|
|||
github.com/golang/protobuf v1.5.4 // indirect
|
||||
github.com/google/pprof v0.0.0-20211214055906-6f57359322fd // indirect
|
||||
github.com/google/uuid v1.4.0 // indirect
|
||||
github.com/hashicorp/errwrap v1.0.0 // indirect
|
||||
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
|
||||
github.com/hashicorp/go-hclog v1.2.0 // indirect
|
||||
github.com/hashicorp/go-immutable-radix v1.3.1 // indirect
|
||||
|
|
6
go.sum
6
go.sum
|
@ -235,6 +235,10 @@ github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91
|
|||
github.com/go-playground/validator/v10 v10.10.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos=
|
||||
github.com/go-playground/validator/v10 v10.14.0 h1:vgvQWe3XCz3gIeFDm/HnTIbj6UGmg/+t63MyGU2n5js=
|
||||
github.com/go-playground/validator/v10 v10.14.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU=
|
||||
github.com/go-redsync/redsync/v4 v4.12.1 h1:hCtdZ45DJxMxNdPiby5GlQwOKQmcka2587Y466qPqlA=
|
||||
github.com/go-redsync/redsync/v4 v4.12.1/go.mod h1:sn72ojgeEhxUuRjrliK0NRrB0Zl6kOZ3BDvNN3P2jAY=
|
||||
github.com/go-redsync/redsync/v4 v4.13.0 h1:49X6GJfnbLGaIpBBREM/zA4uIMDXKAh1NDkvQ1EkZKA=
|
||||
github.com/go-redsync/redsync/v4 v4.13.0/go.mod h1:HMW4Q224GZQz6x1Xc7040Yfgacukdzu7ifTDAKiyErQ=
|
||||
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||
github.com/go-sql-driver/mysql v1.7.0 h1:ueSltNNllEqE3qcWBTD0iQd3IpL/6U+mJxLkazJ7YPc=
|
||||
github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
|
||||
|
@ -340,6 +344,8 @@ github.com/hashicorp/consul/sdk v0.8.0 h1:OJtKBtEjboEZvG6AOUdh4Z1Zbyu0WcxQ0qatRr
|
|||
github.com/hashicorp/consul/sdk v0.8.0/go.mod h1:GBvyrGALthsZObzUGsfgHZQDXjg4lOjagTIwIR1vPms=
|
||||
github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
|
||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
|
||||
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
|
||||
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
|
||||
github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ=
|
||||
|
|
|
@ -13,12 +13,17 @@ func init() {
|
|||
}
|
||||
|
||||
func userExampleRouter(group *gin.RouterGroup, h handler.UserExampleHandler) {
|
||||
//group.Use(middleware.Auth()) // all of the following routes use jwt authentication
|
||||
// or group.Use(middleware.Auth(middleware.WithVerify(verify))) // token authentication
|
||||
g := group.Group("/userExample")
|
||||
|
||||
group.POST("/userExample", h.Create)
|
||||
group.DELETE("/userExample/:id", h.DeleteByID)
|
||||
group.PUT("/userExample/:id", h.UpdateByID)
|
||||
group.GET("/userExample/:id", h.GetByID)
|
||||
group.POST("/userExample/list", h.List)
|
||||
// All the following routes use jwt authentication, you also can use middleware.Auth(middleware.WithVerify(fn))
|
||||
//g.Use(middleware.Auth())
|
||||
|
||||
// If jwt authentication is not required for all routes, authentication middleware can be added
|
||||
// separately for only certain routes. In this case, g.Use(middleware.Auth()) above should not be used.
|
||||
|
||||
g.POST("/", h.Create) // [post] /api/v1/userExample
|
||||
g.DELETE("/:id", h.DeleteByID) // [delete] /api/v1/userExample/:id
|
||||
g.PUT("/:id", h.UpdateByID) // [put] /api/v1/userExample/:id
|
||||
g.GET("/:id", h.GetByID) // [get] /api/v1/userExample/:id
|
||||
g.POST("/list", h.List) // [post] /api/v1/userExample/list
|
||||
}
|
||||
|
|
|
@ -13,17 +13,22 @@ func init() {
|
|||
}
|
||||
|
||||
func userExampleRouter(group *gin.RouterGroup, h handler.UserExampleHandler) {
|
||||
//group.Use(middleware.Auth()) // all of the following routes use jwt authentication
|
||||
// or group.Use(middleware.Auth(middleware.WithVerify(verify))) // token authentication
|
||||
g := group.Group("/userExample")
|
||||
|
||||
group.POST("/userExample", h.Create)
|
||||
group.DELETE("/userExample/:id", h.DeleteByID)
|
||||
group.PUT("/userExample/:id", h.UpdateByID)
|
||||
group.GET("/userExample/:id", h.GetByID)
|
||||
group.POST("/userExample/list", h.List)
|
||||
// All the following routes use jwt authentication, you also can use middleware.Auth(middleware.WithVerify(fn))
|
||||
//g.Use(middleware.Auth())
|
||||
|
||||
group.POST("/userExample/delete/ids", h.DeleteByIDs)
|
||||
group.POST("/userExample/condition", h.GetByCondition)
|
||||
group.POST("/userExample/list/ids", h.ListByIDs)
|
||||
group.GET("/userExample/list", h.ListByLastID)
|
||||
// If jwt authentication is not required for all routes, authentication middleware can be added
|
||||
// separately for only certain routes. In this case, g.Use(middleware.Auth()) above should not be used.
|
||||
|
||||
g.POST("/", h.Create) // [post] /api/v1/userExample
|
||||
g.DELETE("/:id", h.DeleteByID) // [delete] /api/v1/userExample/:id
|
||||
g.PUT("/:id", h.UpdateByID) // [put] /api/v1/userExample/:id
|
||||
g.GET("/:id", h.GetByID) // [get] /api/v1/userExample/:id
|
||||
g.POST("/list", h.List) // [post] /api/v1/userExample/list
|
||||
|
||||
g.POST("/delete/ids", h.DeleteByIDs) // [post] /api/v1/userExample/delete/ids
|
||||
g.POST("/condition", h.GetByCondition) // [post] /api/v1/userExample/condition
|
||||
g.POST("/list/ids", h.ListByIDs) // [post] /api/v1/userExample/list/ids
|
||||
g.GET("/list", h.ListByLastID) // [get] /api/v1/userExample/list
|
||||
}
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
#!/bin/bash
|
||||
|
||||
goModFile="go.mod"
|
||||
thirdPartyProtoDir="third_party"
|
||||
|
||||
function checkResult() {
|
||||
result=$1
|
||||
if [ ${result} -ne 0 ]; then
|
||||
exit ${result}
|
||||
fi
|
||||
}
|
||||
|
||||
if [ ! -f "../$goModFile" ]; then
|
||||
sponge patch copy-go-mod
|
||||
checkResult $?
|
||||
mv -f go.mod ..
|
||||
mv -f go.sum ..
|
||||
fi
|
||||
|
||||
if [ ! -d "../$thirdPartyProtoDir" ]; then
|
||||
sponge patch copy-third-party-proto
|
||||
checkResult $?
|
||||
mv -f $thirdPartyProtoDir ..
|
||||
fi
|
|
@ -7,6 +7,15 @@ allProtoFiles=""
|
|||
specifiedProtoFilePath=$1
|
||||
specifiedProtoFilePaths=""
|
||||
|
||||
colorGray='\033[1;30m'
|
||||
colorGreen='\033[1;32m'
|
||||
colorMagenta='\033[1;35m'
|
||||
colorCyan='\033[1;36m'
|
||||
highBright='\033[1m'
|
||||
markEnd='\033[0m'
|
||||
|
||||
tipMsg=""
|
||||
|
||||
function checkResult() {
|
||||
result=$1
|
||||
if [ ${result} -ne 0 ]; then
|
||||
|
@ -97,7 +106,7 @@ function generateByAllProto(){
|
|||
echo "Error: not found proto file in path $protoBasePath"
|
||||
exit 1
|
||||
fi
|
||||
echo "generate *pb.go by proto files: $allProtoFiles"
|
||||
echo -e "generate *pb.go by proto files: ${colorGray}$allProtoFiles${markEnd}"
|
||||
echo ""
|
||||
|
||||
# generate files *_pb.go
|
||||
|
@ -153,7 +162,8 @@ function generateBySpecifiedProto(){
|
|||
if [ "$specifiedProtoFiles"x = x ];then
|
||||
return
|
||||
fi
|
||||
echo "generate template code by proto files: $specifiedProtoFiles"
|
||||
echo -e "generate template code by proto files: ${colorMagenta}$specifiedProtoFiles${markEnd}"
|
||||
echo ""
|
||||
# todo generate api template code command here
|
||||
# delete the templates code start
|
||||
|
||||
|
@ -180,17 +190,11 @@ function generateBySpecifiedProto(){
|
|||
sponge merge rpc-gw-pb
|
||||
checkResult $?
|
||||
|
||||
colorCyan='\033[1;36m'
|
||||
highBright='\033[1m'
|
||||
markEnd='\033[0m'
|
||||
|
||||
echo ""
|
||||
echo -e "${highBright}Tip:${markEnd} execute the command ${colorCyan}make run${markEnd} and then visit ${colorCyan}http://localhost:8080/apis/swagger/index.html${markEnd} in your browser."
|
||||
echo ""
|
||||
tipMsg="${highBright}Tip:${markEnd} execute the command ${colorCyan}make run${markEnd} and then visit ${colorCyan}http://localhost:8080/apis/swagger/index.html${markEnd} in your browser."
|
||||
# delete the templates code end
|
||||
|
||||
if [ "$suitedMonoRepo" == "true" ]; then
|
||||
sponge patch adapt-mono-repo
|
||||
sponge patch adapt-mono-repo --dir=serverNameExample
|
||||
fi
|
||||
}
|
||||
|
||||
|
@ -210,5 +214,7 @@ sponge patch del-omitempty --dir=$protoBasePath --suffix-name=pb.go > /dev/null
|
|||
sponge patch modify-dup-num --dir=internal/ecode
|
||||
sponge patch modify-dup-err-code --dir=internal/ecode
|
||||
|
||||
echo "generated code successfully."
|
||||
echo -e "${colorGreen}generated code done.${markEnd}"
|
||||
echo ""
|
||||
echo -e $tipMsg
|
||||
echo ""
|
||||
|
|
|
@ -25,6 +25,7 @@ checkResult $?
|
|||
sponge patch modify-dup-num --dir=internal/ecode
|
||||
sponge patch modify-dup-err-code --dir=internal/ecode
|
||||
|
||||
colorGreen='\033[1;32m'
|
||||
colorCyan='\033[1;36m'
|
||||
highBright='\033[1m'
|
||||
markEnd='\033[0m'
|
||||
|
@ -32,5 +33,5 @@ markEnd='\033[0m'
|
|||
echo ""
|
||||
echo -e "${highBright}Tip:${markEnd} execute the command ${colorCyan}make run${markEnd} and then visit ${colorCyan}http://${HOST_ADDR}:8080/swagger/index.html${markEnd} in your browser."
|
||||
echo ""
|
||||
echo "generated api docs successfully."
|
||||
echo -e "${colorGreen}generated api docs done.${markEnd}"
|
||||
echo ""
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#!/bin/bash
|
||||
|
||||
rm -rf \
|
||||
rm -rf go.mod go.sum \
|
||||
third_party \
|
||||
mono_01_http_mysql \
|
||||
mono_02_http_postgresql \
|
||||
mono_03_http_sqlite \
|
||||
|
|
|
@ -130,6 +130,7 @@ function runningProtoService() {
|
|||
return 1
|
||||
fi
|
||||
|
||||
make patch TYPE=types-pb
|
||||
make proto
|
||||
checkResult $?
|
||||
echo -e "startup service $name"
|
||||
|
@ -721,8 +722,6 @@ function generate_grpc_gw_pb() {
|
|||
fi
|
||||
|
||||
cd $outDir
|
||||
make copy-proto SERVER=../mono_05_grpc_mysql
|
||||
checkResult $?
|
||||
runningProtoService $serverName $outDir
|
||||
checkResult $?
|
||||
sleep 1
|
||||
|
|
Loading…
Reference in New Issue