Files
ginrpc/gen.go
2023-03-10 16:40:30 +08:00

221 lines
4.7 KiB
Go

package ginrpc
import (
"bytes"
"fmt"
"io/ioutil"
"os"
"os/exec"
"path"
"strings"
"sync"
"text/template"
"time"
"github.com/xxjwxc/public/message"
"github.com/xxjwxc/public/serializing"
"github.com/xxjwxc/public/tools"
)
const (
getRouter = "/conf/gen_router.data"
)
var _mu sync.Mutex // protects the serviceMap
var _once sync.Once
var _genInfo genInfo
var _genInfoCnf genInfo
var _genMap map[string]GenThirdParty
func init() {
_genMap = make(map[string]GenThirdParty)
data, err := ioutil.ReadFile(path.Join(tools.GetCurrentDirectory(), getRouter))
if err == nil {
serializing.Decode(data, &_genInfoCnf) // gob de serialize 反序列化
}
}
// AddGenOne add one to base case
func AddGenOne(handFunName, routerPath string, methods []string, thirdParty []GenThirdParty, note string) {
_mu.Lock()
defer _mu.Unlock()
_genInfo.List = append(_genInfo.List, genRouterInfo{
HandFunName: handFunName,
GenComment: genComment{
Note: note,
RouterPath: routerPath,
Methods: methods,
ThirdPartyList: thirdParty,
},
})
for _, v := range thirdParty {
_genMap[fmt.Sprintf("%v-%v", routerPath, v.Name)] = GenThirdParty{
Note: note,
Name: v.Name,
Data: v.Data,
}
}
}
func GetThirdParty(routerPath, thirdParty string) (*GenThirdParty, error) {
key := fmt.Sprintf("%v-%v", routerPath, thirdParty)
if _, ok := _genMap[key]; ok {
tmp := _genMap[key]
return &GenThirdParty{
Name: tmp.Name,
Note: tmp.Note,
Data: tmp.Data,
}, nil
}
return nil, message.GetError(message.NotFindError)
}
func GetAllRouter() []genRouterInfo {
_mu.Lock()
defer _mu.Unlock()
return _genInfo.List
}
// SetVersion user timestamp to replace version
func SetVersion(tm int64) {
_mu.Lock()
defer _mu.Unlock()
_genInfo.Tm = tm
}
func GetVersion() string {
return fmt.Sprintf("%v", _genInfo.Tm)
}
func checkOnceAdd(handFunName, routerPath string, methods []string, thirdParty []GenThirdParty, note string) {
_once.Do(func() {
_mu.Lock()
defer _mu.Unlock()
_genInfo.Tm = time.Now().Unix()
_genInfo.List = []genRouterInfo{} // reset
})
AddGenOne(handFunName, routerPath, methods, thirdParty, note)
}
// GetStringList format string
func GetStringList(list []string) string {
return `"` + strings.Join(list, `","`) + `"`
}
// GetPartyList format string
func GetPartyList(list []GenThirdParty) string {
var tmp []string
for _, v := range list {
tmp = append(tmp, fmt.Sprintf(`{Name: "%v", Data: "%v"}`, v.Name, v.Data))
}
return strings.Join(tmp, ",")
}
func GetNote(note string) string {
return fmt.Sprintf("`%v`", note)
}
func genOutPut(outDir, modFile string) {
_mu.Lock()
defer _mu.Unlock()
b := genCode(outDir, modFile) // gen .go file
_genInfo.Tm = time.Now().Unix()
_data, _ := serializing.Encode(&_genInfo) // gob serialize 序列化
_path := path.Join(tools.GetCurrentDirectory(), getRouter)
if !b {
tools.BuildDir(_path)
}
f, err := os.Create(_path)
if err != nil {
return
}
defer f.Close()
f.Write(_data)
}
func genCode(outDir, modFile string) bool {
_genInfo.Tm = time.Now().Unix()
if len(outDir) == 0 {
outDir = modFile + "/routers/"
}
pkgName := getPkgName(outDir)
data := struct {
genInfo
PkgName string
}{
genInfo: _genInfo,
PkgName: pkgName,
}
tmpl, err := template.New("gen_out").Funcs(template.FuncMap{"GetStringList": GetStringList, "GetPartyList": GetPartyList, "GetNote": GetNote}).Parse(genTemp)
if err != nil {
panic(err)
}
var buf bytes.Buffer
tmpl.Execute(&buf, data)
f, err := os.Create(outDir + "gen_router.go")
if err != nil {
return false
}
defer f.Close()
f.Write(buf.Bytes())
// format
exec.Command("gofmt", "-l", "-w", outDir).Output()
return true
}
func getPkgName(dir string) string {
dir = strings.Replace(dir, "\\", "/", -1)
dir = strings.TrimRight(dir, "/")
var pkgName string
list := strings.Split(dir, "/")
if len(list) > 0 {
pkgName = list[len(list)-1]
}
if len(pkgName) == 0 || pkgName == "." {
list = strings.Split(tools.GetCurrentDirectory(), "/")
if len(list) > 0 {
pkgName = list[len(list)-1]
}
}
return pkgName
}
func getInfo() map[string][]genRouterInfo {
_mu.Lock()
defer _mu.Unlock()
genInfo := _genInfo
if _genInfoCnf.Tm > genInfo.Tm { // config to update more than coding
genInfo = _genInfoCnf
}
mp := make(map[string][]genRouterInfo, len(genInfo.List))
for _, v := range genInfo.List {
tmp := v
mp[tmp.HandFunName] = append(mp[tmp.HandFunName], tmp)
}
return mp
}
func buildRelativePath(prepath, routerPath string) string {
if strings.HasSuffix(prepath, "/") {
if strings.HasPrefix(routerPath, "/") {
return prepath + strings.TrimPrefix(routerPath, "/")
}
return prepath + routerPath
}
if strings.HasPrefix(routerPath, "/") {
return prepath + routerPath
}
return prepath + "/" + routerPath
}