Files
complie-erlang/worker/mod_worker.go
T

201 lines
4.8 KiB
Go

package worker
import (
"complie-erlang/config"
"complie-erlang/parser/zm_lib"
"complie-erlang/parser/zm_proto"
tm "complie-erlang/template"
"errors"
"fmt"
"gopkg.in/yaml.v2"
"log"
"os"
"path/filepath"
"time"
)
type ModWorker interface {
Name() string
LoadCfg(BaseSet, []string) error
OutPutFiles() ([]string, error)
}
type BaseSet struct {
ModConfigs *config.ModConfigs
Conf config.ModConfig
}
func ModWorkerRun(name string, args []string) error {
xmlPath, err := zm_lib.FindPathByExecutable("./mod_config.yaml")
if err != nil {
return fmt.Errorf("find xml path error: %v", err)
}
bytes, err := os.ReadFile(xmlPath)
if err != nil {
return fmt.Errorf("读取配置文件失败: %v", err)
}
var conf = config.ModConfigs{}
if err = yaml.Unmarshal(bytes, &conf); err != nil {
return fmt.Errorf("解析配置文件 %s 失败: %v", xmlPath, err)
}
var modWorkerName string
var baseSet BaseSet
baseSet.ModConfigs = &conf
for _, modconfig := range conf.ModConfigs {
if modconfig.Name == name {
modWorkerName = modconfig.Worker
baseSet.Conf = modconfig
break
}
}
if modWorkerName == "" {
return fmt.Errorf("无效的 %s", name)
}
for _, worker := range AllWorkers() {
if worker.Name() == modWorkerName {
log.Printf("[info] 初始化开始。。。")
if err := worker.LoadCfg(baseSet, args); err != nil {
return fmt.Errorf("初始化 Err:%v", err)
}
log.Printf("[info] 初始化完成 开始生成输出。。。")
outFiles, err := worker.OutPutFiles()
if err != nil {
return fmt.Errorf("生成输出 Err:%v", err)
}
log.Printf("[info] 生成完成: \n")
for _, outFile := range outFiles {
log.Printf(" - %s:0\n", outFile)
}
return nil
}
}
return errors.New("worker not found")
}
func AllWorkers() []ModWorker {
return []ModWorker{&ProtoModWorker{}}
}
type ProtoModWorker struct {
set BaseSet
Args []string
DefaultArgs []config.DefaultArg
templates *tm.Template // 模板
pluginPath string
parsePort []zm_proto.Port
proto *zm_proto.Proto
}
func (mod *ProtoModWorker) Name() string {
return "proto"
}
func (mod *ProtoModWorker) LoadCfg(set BaseSet, Args []string) error {
mod.set = set
mod.Args = Args
log.Println("[info] 加载配置 set:", set.Conf, "args:", Args)
pluginPathByWd, err := zm_lib.GetPluginPathByWd(set.ModConfigs.Plugin)
if err != nil {
return err
}
log.Println("[info] 项目根目录:", pluginPathByWd)
mod.pluginPath = pluginPathByWd
// 加载模版
findPathByExecutable, err := zm_lib.FindPathByExecutable(set.ModConfigs.TemplateDir)
if err != nil {
return err
}
log.Println("[info] 加载模板:", findPathByExecutable)
mod.templates = tm.NewTemplate()
if err = mod.templates.ParseGlob(findPathByExecutable); err != nil {
return err
}
protoFile := filepath.Join(mod.pluginPath, fmt.Sprintf(mod.set.Conf.ProtoName, mod.Args[0]))
log.Printf("[info] 加载proto文件: %s:1\n", protoFile)
proto := zm_proto.NewProto()
proto.Include(filepath.Dir(protoFile))
if err = proto.ParseImport(filepath.Base(protoFile)); err != nil {
return err
}
parsePort, err := zm_proto.ParsePort(proto, protoFile)
if err != nil {
return err
}
mod.proto = proto
mod.parsePort = parsePort
for _, p := range mod.parsePort {
log.Printf("[info] 解析接口: %s 是否推送: %v \n", p.Cmd, p.IsPush)
}
return nil
}
func (mod *ProtoModWorker) OutPutFiles() ([]string, error) {
for _, dir := range mod.set.Conf.MakeDir {
dir.Path = filepath.Join(mod.pluginPath, fmt.Sprintf(dir.Path, mod.Args[0]))
log.Println("[info] make outDir:", dir.Path)
//if err := os.MkdirAll(dir.Path, os.ModePerm); err != nil {
// return nil, err
//}
}
for _, outFs := range mod.set.Conf.OutFiles {
log.Println("[info] make file:", fmt.Sprintf(outFs.FileName, mod.Args[0]))
template, err := mod.templates.ExecuteTemplate(outFs.ContentTemplate, mod.FormatArgs())
if err != nil {
return nil, err
}
fmt.Printf("\n\n >:\n%s \n\n", template)
}
return nil, nil
}
func (mod *ProtoModWorker) FormatArgs() map[string]any {
var templatesArgs = make(map[string]any)
var defaultArgs = make(map[string]any)
for _, defaultArg := range mod.DefaultArgs {
defaultArgs[defaultArg.Key] = defaultArg.Value
}
templatesArgs["default"] = defaultArgs
var ports []any
for _, port := range mod.parsePort {
if port.IsPush {
continue
}
var portMap = map[string]any{
"Cmd": port.Cmd,
"PortDesc": port.PortDesc,
"ClientPB": port.ClientPB,
"ServerPB": port.ServerPB,
"ClientProto": mod.proto.MessageToErlMod(port.ClientPB),
"ServerProto": mod.proto.MessageToErlMod(port.ServerPB),
}
ports = append(ports, portMap)
}
templatesArgs["ports"] = ports
// 其他默认值
templatesArgs["CreateAt"] = time.Now().Format(time.DateTime)
return templatesArgs
}